This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
/**
* Normalizer plugs Patchwork\PHP\Shim\Normalizer as a PHP implementation
* of intl's Normalizer when the intl extension in not enabled.
*/
class Normalizer extends Patchwork\PHP\Shim\Normalizer
{
}

View File

@@ -0,0 +1,729 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\PHP\Shim;
/**
* iconv implementation in pure PHP, UTF-8 centric.
*
* Implemented:
* - iconv - Convert string to requested character encoding
* - iconv_mime_decode - Decodes a MIME header field
* - iconv_mime_decode_headers - Decodes multiple MIME header fields at once
* - iconv_get_encoding - Retrieve internal configuration variables of iconv extension
* - iconv_set_encoding - Set current setting for character encoding conversion
* - iconv_mime_encode - Composes a MIME header field
* - ob_iconv_handler - Convert character encoding as output buffer handler
* - iconv_strlen - Returns the character count of string
* - iconv_strpos - Finds position of first occurrence of a needle within a haystack
* - iconv_strrpos - Finds the last occurrence of a needle within a haystack
* - iconv_substr - Cut out part of a string
*
* Charsets available for conversion are defined by files
* in the charset/ directory and by Iconv::$alias below.
* You're welcome to send back any addition you make.
*
* @internal
*/
class Iconv
{
const ERROR_ILLEGAL_CHARACTER = 'iconv(): Detected an illegal character in input string';
const ERROR_WRONG_CHARSET = 'iconv(): Wrong charset, conversion from `%s\' to `%s\' is not allowed';
public static $inputEncoding = 'utf-8';
public static $outputEncoding = 'utf-8';
public static $internalEncoding = 'utf-8';
private static $alias = array(
'utf8' => 'utf-8',
'ascii' => 'us-ascii',
'tis-620' => 'iso-8859-11',
'cp1250' => 'windows-1250',
'cp1251' => 'windows-1251',
'cp1252' => 'windows-1252',
'cp1253' => 'windows-1253',
'cp1254' => 'windows-1254',
'cp1255' => 'windows-1255',
'cp1256' => 'windows-1256',
'cp1257' => 'windows-1257',
'cp1258' => 'windows-1258',
'shift-jis' => 'cp932',
'shift_jis' => 'cp932',
'latin1' => 'iso-8859-1',
'latin2' => 'iso-8859-2',
'latin3' => 'iso-8859-3',
'latin4' => 'iso-8859-4',
'latin5' => 'iso-8859-9',
'latin6' => 'iso-8859-10',
'latin7' => 'iso-8859-13',
'latin8' => 'iso-8859-14',
'latin9' => 'iso-8859-15',
'latin10' => 'iso-8859-16',
'iso8859-1' => 'iso-8859-1',
'iso8859-2' => 'iso-8859-2',
'iso8859-3' => 'iso-8859-3',
'iso8859-4' => 'iso-8859-4',
'iso8859-5' => 'iso-8859-5',
'iso8859-6' => 'iso-8859-6',
'iso8859-7' => 'iso-8859-7',
'iso8859-8' => 'iso-8859-8',
'iso8859-9' => 'iso-8859-9',
'iso8859-10' => 'iso-8859-10',
'iso8859-11' => 'iso-8859-11',
'iso8859-12' => 'iso-8859-12',
'iso8859-13' => 'iso-8859-13',
'iso8859-14' => 'iso-8859-14',
'iso8859-15' => 'iso-8859-15',
'iso8859-16' => 'iso-8859-16',
'iso_8859-1' => 'iso-8859-1',
'iso_8859-2' => 'iso-8859-2',
'iso_8859-3' => 'iso-8859-3',
'iso_8859-4' => 'iso-8859-4',
'iso_8859-5' => 'iso-8859-5',
'iso_8859-6' => 'iso-8859-6',
'iso_8859-7' => 'iso-8859-7',
'iso_8859-8' => 'iso-8859-8',
'iso_8859-9' => 'iso-8859-9',
'iso_8859-10' => 'iso-8859-10',
'iso_8859-11' => 'iso-8859-11',
'iso_8859-12' => 'iso-8859-12',
'iso_8859-13' => 'iso-8859-13',
'iso_8859-14' => 'iso-8859-14',
'iso_8859-15' => 'iso-8859-15',
'iso_8859-16' => 'iso-8859-16',
'iso88591' => 'iso-8859-1',
'iso88592' => 'iso-8859-2',
'iso88593' => 'iso-8859-3',
'iso88594' => 'iso-8859-4',
'iso88595' => 'iso-8859-5',
'iso88596' => 'iso-8859-6',
'iso88597' => 'iso-8859-7',
'iso88598' => 'iso-8859-8',
'iso88599' => 'iso-8859-9',
'iso885910' => 'iso-8859-10',
'iso885911' => 'iso-8859-11',
'iso885912' => 'iso-8859-12',
'iso885913' => 'iso-8859-13',
'iso885914' => 'iso-8859-14',
'iso885915' => 'iso-8859-15',
'iso885916' => 'iso-8859-16',
);
private static $translitMap = array();
private static $convertMap = array();
private static $errorHandler;
private static $lastError;
private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
private static $isValidUtf8;
public static function iconv($inCharset, $outCharset, $str)
{
if ('' === $str .= '') {
return '';
}
// Prepare for //IGNORE and //TRANSLIT
$translit = $ignore = '';
$outCharset = strtolower($outCharset);
$inCharset = strtolower($inCharset);
if ('' === $outCharset) {
$outCharset = 'iso-8859-1';
}
if ('' === $inCharset) {
$inCharset = 'iso-8859-1';
}
if ('//translit' === substr($outCharset, -10)) {
$translit = '//TRANSLIT';
$outCharset = substr($outCharset, 0, -10);
}
if ('//ignore' === substr($outCharset, -8)) {
$ignore = '//IGNORE';
$outCharset = substr($outCharset, 0, -8);
}
if ('//translit' === substr($inCharset, -10)) {
$inCharset = substr($inCharset, 0, -10);
}
if ('//ignore' === substr($inCharset, -8)) {
$inCharset = substr($inCharset, 0, -8);
}
if (isset(self::$alias[ $inCharset])) {
$inCharset = self::$alias[ $inCharset];
}
if (isset(self::$alias[$outCharset])) {
$outCharset = self::$alias[$outCharset];
}
// Load charset maps
if (('utf-8' !== $inCharset && !self::loadMap('from.', $inCharset, $inMap))
|| ('utf-8' !== $outCharset && !self::loadMap('to.', $outCharset, $outMap))) {
trigger_error(sprintf(self::ERROR_WRONG_CHARSET, $inCharset, $outCharset));
return false;
}
if ('utf-8' !== $inCharset) {
// Convert input to UTF-8
$result = '';
if (self::mapToUtf8($result, $inMap, $str, $ignore)) {
$str = $result;
} else {
$str = false;
}
self::$isValidUtf8 = true;
} else {
self::$isValidUtf8 = preg_match('//u', $str);
if (!self::$isValidUtf8 && !$ignore) {
trigger_error(self::ERROR_ILLEGAL_CHARACTER);
return false;
}
if ('utf-8' === $outCharset) {
// UTF-8 validation
$str = self::utf8ToUtf8($str, $ignore);
}
}
if ('utf-8' !== $outCharset && false !== $str) {
// Convert output to UTF-8
$result = '';
if (self::mapFromUtf8($result, $outMap, $str, $ignore, $translit)) {
return $result;
}
return false;
}
return $str;
}
public static function iconv_mime_decode_headers($str, $mode = 0, $charset = null)
{
if (null === $charset) {
$charset = self::$internalEncoding;
}
if (false !== strpos($str, "\r")) {
$str = strtr(str_replace("\r\n", "\n", $str), "\r", "\n");
}
$str = explode("\n\n", $str, 2);
$headers = array();
$str = preg_split('/\n(?![ \t])/', $str[0]);
foreach ($str as $str) {
$str = self::iconv_mime_decode($str, $mode, $charset);
if (false === $str) {
return false;
}
$str = explode(':', $str, 2);
if (2 === count($str)) {
if (isset($headers[$str[0]])) {
if (!is_array($headers[$str[0]])) {
$headers[$str[0]] = array($headers[$str[0]]);
}
$headers[$str[0]][] = ltrim($str[1]);
} else {
$headers[$str[0]] = ltrim($str[1]);
}
}
}
return $headers;
}
public static function iconv_mime_decode($str, $mode = 0, $charset = null)
{
if (null === $charset) {
$charset = self::$internalEncoding;
}
if (ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) {
$charset .= '//IGNORE';
}
if (false !== strpos($str, "\r")) {
$str = strtr(str_replace("\r\n", "\n", $str), "\r", "\n");
}
$str = preg_split('/\n(?![ \t])/', rtrim($str), 2);
$str = preg_replace('/[ \t]*\n[ \t]+/', ' ', rtrim($str[0]));
$str = preg_split('/=\?([^?]+)\?([bqBQ])\?(.*?)\?=/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
$result = self::iconv('utf-8', $charset, $str[0]);
if (false === $result) {
return false;
}
$i = 1;
$len = count($str);
while ($i < $len) {
$c = strtolower($str[$i]);
if ((ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode)
&& 'utf-8' !== $c
&& !isset(self::$alias[$c])
&& !self::loadMap('from.', $c, $d)) {
$d = false;
} elseif ('B' === strtoupper($str[$i + 1])) {
$d = base64_decode($str[$i + 2]);
} else {
$d = rawurldecode(strtr(str_replace('%', '%25', $str[$i + 2]), '=_', '% '));
}
if (false !== $d) {
if ('' !== $d) {
if ('' === $d = self::iconv($c, $charset, $d)) {
$str[$i + 3] = substr($str[$i + 3], 1);
} else {
$result .= $d;
}
}
$d = self::iconv('utf-8', $charset, $str[$i + 3]);
if ('' !== trim($d)) {
$result .= $d;
}
} elseif (ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) {
$result .= "=?{$str[$i]}?{$str[$i + 1]}?{$str[$i + 2]}?={$str[$i + 3]}";
} else {
$result = false;
break;
}
$i += 4;
}
return $result;
}
public static function iconv_get_encoding($type = 'all')
{
switch ($type) {
case 'input_encoding': return self::$inputEncoding;
case 'output_encoding': return self::$outputEncoding;
case 'internal_encoding': return self::$internalEncoding;
}
return array(
'input_encoding' => self::$inputEncoding,
'output_encoding' => self::$outputEncoding,
'internal_encoding' => self::$internalEncoding,
);
}
public static function iconv_set_encoding($type, $charset)
{
switch ($type) {
case 'input_encoding': self::$inputEncoding = $charset; break;
case 'output_encoding': self::$outputEncoding = $charset; break;
case 'internal_encoding': self::$internalEncoding = $charset; break;
default: return false;
}
return true;
}
public static function iconv_mime_encode($fieldName, $fieldValue, $pref = null)
{
if (!is_array($pref)) {
$pref = array();
}
$pref += array(
'scheme' => 'B',
'input-charset' => self::$internalEncoding,
'output-charset' => self::$internalEncoding,
'line-length' => 76,
'line-break-chars' => "\r\n",
);
if (preg_match('/[\x80-\xFF]/', $fieldName)) {
$fieldName = '';
}
$scheme = strtoupper(substr($pref['scheme'], 0, 1));
$in = strtolower($pref['input-charset']);
$out = strtolower($pref['output-charset']);
if ('utf-8' !== $in && false === $fieldValue = self::iconv($in, 'utf-8', $fieldValue)) {
return false;
}
preg_match_all('/./us', $fieldValue, $chars);
$chars = isset($chars[0]) ? $chars[0] : array();
$lineBreak = (int) $pref['line-length'];
$lineStart = "=?{$pref['output-charset']}?{$scheme}?";
$lineLength = strlen($fieldName) + 2 + strlen($lineStart) + 2;
$lineOffset = strlen($lineStart) + 3;
$lineData = '';
$fieldValue = array();
$Q = 'Q' === $scheme;
foreach ($chars as $c) {
if ('utf-8' !== $out && false === $c = self::iconv('utf-8', $out, $c)) {
return false;
}
$o = $Q
? $c = preg_replace_callback(
'/[=_\?\x00-\x1F\x80-\xFF]/',
array(__CLASS__, 'qpByteCallback'),
$c
)
: base64_encode($lineData.$c);
if (isset($o[$lineBreak - $lineLength])) {
if (!$Q) {
$lineData = base64_encode($lineData);
}
$fieldValue[] = $lineStart.$lineData.'?=';
$lineLength = $lineOffset;
$lineData = '';
}
$lineData .= $c;
$Q && $lineLength += strlen($c);
}
if ('' !== $lineData) {
if (!$Q) {
$lineData = base64_encode($lineData);
}
$fieldValue[] = $lineStart.$lineData.'?=';
}
return $fieldName.': '.implode($pref['line-break-chars'].' ', $fieldValue);
}
public static function ob_iconv_handler($buffer, $mode)
{
return self::iconv(self::$internalEncoding, self::$outputEncoding, $buffer);
}
public static function iconv_strlen($s, $encoding = null)
{
static $hasXml = null;
if (null === $hasXml) {
$hasXml = extension_loaded('xml');
}
if ($hasXml) {
return self::strlen1($s, $encoding);
}
return self::strlen2($s, $encoding);
}
public static function strlen1($s, $encoding = null)
{
if (null === $encoding) {
$encoding = self::$internalEncoding;
}
if (0 !== stripos($encoding, 'utf-8') && false === $s = self::iconv($encoding, 'utf-8', $s)) {
return false;
}
return strlen(utf8_decode($s));
}
public static function strlen2($s, $encoding = null)
{
if (null === $encoding) {
$encoding = self::$internalEncoding;
}
if (0 !== stripos($encoding, 'utf-8') && false === $s = self::iconv($encoding, 'utf-8', $s)) {
return false;
}
$ulenMask = self::$ulenMask;
$i = 0;
$j = 0;
$len = strlen($s);
while ($i < $len) {
$u = $s[$i] & "\xF0";
$i += isset($ulenMask[$u]) ? $ulenMask[$u] : 1;
++$j;
}
return $j;
}
public static function iconv_strpos($haystack, $needle, $offset = 0, $encoding = null)
{
if (null === $encoding) {
$encoding = self::$internalEncoding;
}
if (0 !== stripos($encoding, 'utf-8')) {
if (false === $haystack = self::iconv($encoding, 'utf-8', $haystack)) {
return false;
}
if (false === $needle = self::iconv($encoding, 'utf-8', $needle)) {
return false;
}
}
if ($offset = (int) $offset) {
$haystack = self::iconv_substr($haystack, $offset, 2147483647, 'utf-8');
}
$pos = strpos($haystack, $needle);
return false === $pos ? false : ($offset + ($pos ? self::iconv_strlen(substr($haystack, 0, $pos), 'utf-8') : 0));
}
public static function iconv_strrpos($haystack, $needle, $encoding = null)
{
if (null === $encoding) {
$encoding = self::$internalEncoding;
}
if (0 !== stripos($encoding, 'utf-8')) {
if (false === $haystack = self::iconv($encoding, 'utf-8', $haystack)) {
return false;
}
if (false === $needle = self::iconv($encoding, 'utf-8', $needle)) {
return false;
}
}
$pos = isset($needle[0]) ? strrpos($haystack, $needle) : false;
return false === $pos ? false : self::iconv_strlen($pos ? substr($haystack, 0, $pos) : $haystack, 'utf-8');
}
public static function iconv_substr($s, $start, $length = 2147483647, $encoding = null)
{
if (null === $encoding) {
$encoding = self::$internalEncoding;
}
if (0 !== stripos($encoding, 'utf-8')) {
$encoding = null;
} elseif (false === $s = self::iconv($encoding, 'utf-8', $s)) {
return false;
}
$s .= '';
$slen = self::iconv_strlen($s, 'utf-8');
$start = (int) $start;
if (0 > $start) {
$start += $slen;
}
if (0 > $start) {
return false;
}
if ($start >= $slen) {
return false;
}
$rx = $slen - $start;
if (0 > $length) {
$length += $rx;
}
if (0 === $length) {
return '';
}
if (0 > $length) {
return false;
}
if ($length > $rx) {
$length = $rx;
}
$rx = '/^'.($start ? self::pregOffset($start) : '').'('.self::pregOffset($length).')/u';
$s = preg_match($rx, $s, $s) ? $s[1] : '';
if (null === $encoding) {
return $s;
}
return self::iconv('utf-8', $encoding, $s);
}
private static function loadMap($type, $charset, &$map)
{
if (!isset(self::$convertMap[$type.$charset])) {
if (false === $map = self::getData($type.$charset)) {
if ('to.' === $type && self::loadMap('from.', $charset, $map)) {
$map = array_flip($map);
} else {
return false;
}
}
self::$convertMap[$type.$charset] = $map;
} else {
$map = self::$convertMap[$type.$charset];
}
return true;
}
private static function utf8ToUtf8($str, $ignore)
{
$ulenMask = self::$ulenMask;
$valid = self::$isValidUtf8;
$u = $str;
$i = $j = 0;
$len = strlen($str);
while ($i < $len) {
if ($str[$i] < "\x80") {
$u[$j++] = $str[$i++];
} else {
$ulen = $str[$i] & "\xF0";
$ulen = isset($ulenMask[$ulen]) ? $ulenMask[$ulen] : 1;
$uchr = substr($str, $i, $ulen);
if (1 === $ulen || !($valid || preg_match('/^.$/us', $uchr))) {
if ($ignore) {
++$i;
continue;
}
trigger_error(self::ERROR_ILLEGAL_CHARACTER);
return false;
} else {
$i += $ulen;
}
$u[$j++] = $uchr[0];
isset($uchr[1]) && 0 !== ($u[$j++] = $uchr[1])
&& isset($uchr[2]) && 0 !== ($u[$j++] = $uchr[2])
&& isset($uchr[3]) && 0 !== ($u[$j++] = $uchr[3]);
}
}
return substr($u, 0, $j);
}
private static function mapToUtf8(&$result, $map, $str, $ignore)
{
$len = strlen($str);
for ($i = 0; $i < $len; ++$i) {
if (isset($str[$i + 1], $map[$str[$i].$str[$i + 1]])) {
$result .= $map[$str[$i].$str[++$i]];
} elseif (isset($map[$str[$i]])) {
$result .= $map[$str[$i]];
} elseif (!$ignore) {
trigger_error(self::ERROR_ILLEGAL_CHARACTER);
return false;
}
}
return true;
}
private static function mapFromUtf8(&$result, $map, $str, $ignore, $translit)
{
$ulenMask = self::$ulenMask;
$valid = self::$isValidUtf8;
if ($translit && !self::$translitMap) {
self::$translitMap = self::getData('translit');
}
$i = 0;
$len = strlen($str);
while ($i < $len) {
if ($str[$i] < "\x80") {
$uchr = $str[$i++];
} else {
$ulen = $str[$i] & "\xF0";
$ulen = isset($ulenMask[$ulen]) ? $ulenMask[$ulen] : 1;
$uchr = substr($str, $i, $ulen);
if ($ignore && (1 === $ulen || !($valid || preg_match('/^.$/us', $uchr)))) {
++$i;
continue;
} else {
$i += $ulen;
}
}
if (isset($map[$uchr])) {
$result .= $map[$uchr];
} elseif ($translit) {
if (isset(self::$translitMap[$uchr])) {
$uchr = self::$translitMap[$uchr];
} elseif ($uchr >= "\xC3\x80") {
$uchr = \Normalizer::normalize($uchr, \Normalizer::NFD);
if ($uchr[0] < "\x80") {
$uchr = $uchr[0];
} elseif ($ignore) {
continue;
} else {
return false;
}
}
$str = $uchr.substr($str, $i);
$len = strlen($str);
$i = 0;
} elseif (!$ignore) {
return false;
}
}
return true;
}
private static function qpByteCallback($m)
{
return '='.strtoupper(dechex(ord($m[0])));
}
private static function pregOffset($offset)
{
$rx = array();
$offset = (int) $offset;
while ($offset > 65535) {
$rx[] = '.{65535}';
$offset -= 65535;
}
return implode('', $rx).'.{'.$offset.'}';
}
private static function getData($file)
{
if (file_exists($file = __DIR__.'/charset/'.$file.'.ser')) {
return unserialize(file_get_contents($file));
}
return false;
}
}

View File

@@ -0,0 +1,232 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\PHP\Shim;
/**
* Partial intl implementation in pure PHP.
*
* Implemented:
* - grapheme_extract - Extract a sequence of grapheme clusters from a text buffer, which must be encoded in UTF-8
* - grapheme_stripos - Find position (in grapheme units) of first occurrence of a case-insensitive string
* - grapheme_stristr - Returns part of haystack string from the first occurrence of case-insensitive needle to the end of haystack
* - grapheme_strlen - Get string length in grapheme units
* - grapheme_strpos - Find position (in grapheme units) of first occurrence of a string
* - grapheme_strripos - Find position (in grapheme units) of last occurrence of a case-insensitive string
* - grapheme_strrpos - Find position (in grapheme units) of last occurrence of a string
* - grapheme_strstr - Returns part of haystack string from the first occurrence of needle to the end of haystack
* - grapheme_substr - Return part of a string
*
* @internal
*/
class Intl
{
// (CRLF|([ZWNJ-ZWJ]|T+|L*(LV?V+|LV|LVT)T*|L+|[^Control])[Extend]*|[Control])
// This regular expression is a work around for http://bugs.exim.org/1279
const GRAPHEME_CLUSTER_RX = '(?:\r\n|(?:[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{200D}\x{1D165}\x{1D16E}-\x{1D172}]*|[\p{Cc}\p{Cf}\p{Zl}\p{Zp}])';
public static function grapheme_extract($s, $size, $type = GRAPHEME_EXTR_COUNT, $start = 0, &$next = 0)
{
if (!is_scalar($s)) {
$hasError = false;
set_error_handler(function () use (&$hasError) {$hasError = true;});
$next = substr($s, $start);
restore_error_handler();
if ($hasError) {
substr($s, $start);
$s = '';
} else {
$s = $next;
}
} else {
$s = substr($s, $start);
}
$size = (int) $size;
$type = (int) $type;
$start = (int) $start;
if (!isset($s[0]) || 0 > $size || 0 > $start || 0 > $type || 2 < $type) {
return false;
}
if (0 === $size) {
return '';
}
$next = $start;
$s = preg_split('/('.GRAPHEME_CLUSTER_RX.')/u', "\r\n".$s, $size + 1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
if (!isset($s[1])) {
return false;
}
$i = 1;
$ret = '';
do {
if (GRAPHEME_EXTR_COUNT === $type) {
--$size;
} elseif (GRAPHEME_EXTR_MAXBYTES === $type) {
$size -= strlen($s[$i]);
} else {
$size -= iconv_strlen($s[$i], 'UTF-8//IGNORE');
}
if ($size >= 0) {
$ret .= $s[$i];
}
} while (isset($s[++$i]) && $size > 0);
$next += strlen($ret);
return $ret;
}
public static function grapheme_strlen($s)
{
preg_replace('/'.GRAPHEME_CLUSTER_RX.'/u', '', $s, -1, $len);
return 0 === $len && '' !== $s ? null : $len;
}
public static function grapheme_substr($s, $start, $len = 2147483647)
{
preg_match_all('/'.GRAPHEME_CLUSTER_RX.'/u', $s, $s);
$slen = count($s[0]);
$start = (int) $start;
if (0 > $start) {
$start += $slen;
}
if (0 > $start) {
return false;
}
if ($start >= $slen) {
return false;
}
$rem = $slen - $start;
if (0 > $len) {
$len += $rem;
}
if (0 === $len) {
return '';
}
if (0 > $len) {
return false;
}
if ($len > $rem) {
$len = $rem;
}
return implode('', array_slice($s[0], $start, $len));
}
public static function grapheme_substr_workaround62759($s, $start, $len)
{
// Intl based http://bugs.php.net/62759 and 55562 workaround
if (2147483647 == $len) {
return grapheme_substr($s, $start);
}
$s .= '';
$slen = grapheme_strlen($s);
$start = (int) $start;
if (0 > $start) {
$start += $slen;
}
if (0 > $start) {
return false;
}
if ($start >= $slen) {
return false;
}
$rem = $slen - $start;
if (0 > $len) {
$len += $rem;
}
if (0 === $len) {
return '';
}
if (0 > $len) {
return false;
}
if ($len > $rem) {
$len = $rem;
}
return grapheme_substr($s, $start, $len);
}
public static function grapheme_strpos($s, $needle, $offset = 0)
{
return self::grapheme_position($s, $needle, $offset, 0);
}
public static function grapheme_stripos($s, $needle, $offset = 0)
{
return self::grapheme_position($s, $needle, $offset, 1);
}
public static function grapheme_strrpos($s, $needle, $offset = 0)
{
return self::grapheme_position($s, $needle, $offset, 2);
}
public static function grapheme_strripos($s, $needle, $offset = 0)
{
return self::grapheme_position($s, $needle, $offset, 3);
}
public static function grapheme_stristr($s, $needle, $beforeNeedle = false)
{
return mb_stristr($s, $needle, $beforeNeedle, 'UTF-8');
}
public static function grapheme_strstr($s, $needle, $beforeNeedle = false)
{
return mb_strstr($s, $needle, $beforeNeedle, 'UTF-8');
}
private static function grapheme_position($s, $needle, $offset, $mode)
{
if (!preg_match('/./us', $needle .= '')) {
return false;
}
if (!preg_match('/./us', $s .= '')) {
return false;
}
if ($offset > 0) {
$s = self::grapheme_substr($s, $offset);
} elseif ($offset < 0) {
if (defined('HHVM_VERSION_ID') || PHP_VERSION_ID < 50535 || (50600 <= PHP_VERSION_ID && PHP_VERSION_ID < 50621) || (70000 <= PHP_VERSION_ID && PHP_VERSION_ID < 70006)) {
$offset = 0;
} else {
return false;
}
}
switch ($mode) {
case 0: $needle = iconv_strpos($s, $needle, 0, 'UTF-8'); break;
case 1: $needle = mb_stripos($s, $needle, 0, 'UTF-8'); break;
case 2: $needle = iconv_strrpos($s, $needle, 'UTF-8'); break;
default: $needle = mb_strripos($s, $needle, 0, 'UTF-8'); break;
}
return $needle ? self::grapheme_strlen(iconv_substr($s, 0, $needle, 'UTF-8')) + $offset : $needle;
}
}

View File

@@ -0,0 +1,602 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\PHP\Shim;
/**
* Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
*
* Implemented:
* - 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_output_handler - Callback function converts character encoding in output buffer
* - 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
*
* @internal
*/
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', $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, $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', $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, $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)
{
$encoding = self::getEncoding($encoding);
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', $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;
}
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__.'/unidata/'.$file.'.ser')) {
return unserialize(file_get_contents($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;
}
}

View File

@@ -0,0 +1,301 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\PHP\Shim;
/**
* Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
*
* It has been validated with Unicode 6.3 Normalization Conformance Test.
* See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
*
* @internal
*/
class Normalizer
{
const NONE = 1;
const FORM_D = 2;
const FORM_KD = 3;
const FORM_C = 4;
const FORM_KC = 5;
const NFD = 2;
const NFKD = 3;
const NFC = 4;
const NFKC = 5;
private static $C;
private static $D;
private static $KD;
private static $cC;
private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
public static function isNormalized($s, $form = self::NFC)
{
if ($form <= self::NONE || self::NFKC < $form) {
return false;
}
if (!isset($s[strspn($s .= '', self::$ASCII)])) {
return true;
}
if (self::NFC === $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) {
return true;
}
return false; // Pretend false as quick checks implementented in PHP won't be so quick
}
public static function normalize($s, $form = self::NFC)
{
if (!preg_match('//u', $s .= '')) {
return false;
}
switch ($form) {
case self::NONE: return $s;
case self::NFC: $C = true; $K = false; break;
case self::NFD: $C = false; $K = false; break;
case self::NFKC: $C = true; $K = true; break;
case self::NFKD: $C = false; $K = true; break;
default: return false;
}
if ('' === $s) {
return '';
}
if ($K && null === self::$KD) {
self::$KD = self::getData('compatibilityDecomposition');
}
if (null === self::$D) {
self::$D = self::getData('canonicalDecomposition');
self::$cC = self::getData('combiningClass');
}
if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) {
mb_internal_encoding('8bit');
}
$r = self::decompose($s, $K);
if ($C) {
if (null === self::$C) {
self::$C = self::getData('canonicalComposition');
}
$r = self::recompose($r);
}
if (null !== $mbEncoding) {
mb_internal_encoding($mbEncoding);
}
return $r;
}
private static function recompose($s)
{
$ASCII = self::$ASCII;
$compMap = self::$C;
$combClass = self::$cC;
$ulenMask = self::$ulenMask;
$result = $tail = '';
$i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"];
$len = strlen($s);
$lastUchr = substr($s, 0, $i);
$lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;
while ($i < $len) {
if ($s[$i] < "\x80") {
// ASCII chars
if ($tail) {
$lastUchr .= $tail;
$tail = '';
}
if ($j = strspn($s, $ASCII, $i + 1)) {
$lastUchr .= substr($s, $i, $j);
$i += $j;
}
$result .= $lastUchr;
$lastUchr = $s[$i];
$lastUcls = 0;
++$i;
continue;
}
$ulen = $ulenMask[$s[$i] & "\xF0"];
$uchr = substr($s, $i, $ulen);
if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr
|| $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
|| $lastUcls) {
// Table lookup and combining chars composition
$ucls = isset($combClass[$uchr]) ? $combClass[$uchr] : 0;
if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
$lastUchr = $compMap[$lastUchr.$uchr];
} elseif ($lastUcls = $ucls) {
$tail .= $uchr;
} else {
if ($tail) {
$lastUchr .= $tail;
$tail = '';
}
$result .= $lastUchr;
$lastUchr = $uchr;
}
} else {
// Hangul chars
$L = ord($lastUchr[2]) - 0x80;
$V = ord($uchr[2]) - 0xA1;
$T = 0;
$uchr = substr($s, $i + $ulen, 3);
if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") {
$T = ord($uchr[2]) - 0xA7;
0 > $T && $T += 0x40;
$ulen += 3;
}
$L = 0xAC00 + ($L * 21 + $V) * 28 + $T;
$lastUchr = chr(0xE0 | $L >> 12).chr(0x80 | $L >> 6 & 0x3F).chr(0x80 | $L & 0x3F);
}
$i += $ulen;
}
return $result.$lastUchr.$tail;
}
private static function decompose($s, $c)
{
$result = '';
$ASCII = self::$ASCII;
$decompMap = self::$D;
$combClass = self::$cC;
$ulenMask = self::$ulenMask;
if ($c) {
$compatMap = self::$KD;
}
$c = array();
$i = 0;
$len = strlen($s);
while ($i < $len) {
if ($s[$i] < "\x80") {
// ASCII chars
if ($c) {
ksort($c);
$result .= implode('', $c);
$c = array();
}
$j = 1 + strspn($s, $ASCII, $i + 1);
$result .= substr($s, $i, $j);
$i += $j;
continue;
}
$ulen = $ulenMask[$s[$i] & "\xF0"];
$uchr = substr($s, $i, $ulen);
$i += $ulen;
if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) {
// Table lookup
if ($uchr !== $j = isset($compatMap[$uchr]) ? $compatMap[$uchr] : (isset($decompMap[$uchr]) ? $decompMap[$uchr] : $uchr)) {
$uchr = $j;
$j = strlen($uchr);
$ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"];
if ($ulen != $j) {
// Put trailing chars in $s
$j -= $ulen;
$i -= $j;
if (0 > $i) {
$s = str_repeat(' ', -$i).$s;
$len -= $i;
$i = 0;
}
while ($j--) {
$s[$i + $j] = $uchr[$ulen + $j];
}
$uchr = substr($uchr, 0, $ulen);
}
}
if (isset($combClass[$uchr])) {
// Combining chars, for sorting
if (!isset($c[$combClass[$uchr]])) {
$c[$combClass[$uchr]] = '';
}
$c[$combClass[$uchr]] .= $uchr;
continue;
}
} else {
// Hangul chars
$uchr = unpack('C*', $uchr);
$j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80;
$uchr = "\xE1\x84".chr(0x80 + (int) ($j / 588))
."\xE1\x85".chr(0xA1 + (int) (($j % 588) / 28));
if ($j %= 28) {
$uchr .= $j < 25
? ("\xE1\x86".chr(0xA7 + $j))
: ("\xE1\x87".chr(0x67 + $j));
}
}
if ($c) {
ksort($c);
$result .= implode('', $c);
$c = array();
}
$result .= $uchr;
}
if ($c) {
ksort($c);
$result .= implode('', $c);
}
return $result;
}
private static function getData($file)
{
if (file_exists($file = __DIR__.'/unidata/'.$file.'.ser')) {
return unserialize(file_get_contents($file));
}
return false;
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\PHP\Shim;
/**
* @internal
*/
class Xml
{
public static function utf8_encode($s)
{
$s .= $s;
$len = strlen($s);
for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
switch (true) {
case $s[$i] < "\x80": $s[$j] = $s[$i]; break;
case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break;
default: $s[$j] = "\xC3"; $s[++$j] = chr(ord($s[$i]) - 64); break;
}
}
return substr($s, 0, $j);
}
public static function utf8_decode($s)
{
$s .= '';
$len = strlen($s);
for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) {
switch ($s[$i] & "\xF0") {
case "\xC0":
case "\xD0":
$c = (ord($s[$i] & "\x1F") << 6) | ord($s[++$i] & "\x3F");
$s[$j] = $c < 256 ? chr($c) : '?';
break;
case "\xF0": ++$i;
case "\xE0":
$s[$j] = '?';
$i += 2;
break;
default:
$s[$j] = $s[$i];
}
}
return substr($s, 0, $j);
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
a:149:{s:1:" ";s:1:" ";s:1:"!";s:1:"!";s:1:""";s:1:""";s:1:"#";s:1:"#";s:1:"$";s:1:"$";s:1:"%";s:1:"%";s:1:"&";s:1:"&";s:1:"'";s:3:"";s:1:"(";s:1:"(";s:1:")";s:1:")";s:1:"*";s:1:"*";s:1:"+";s:1:"+";s:1:",";s:1:",";s:1:"-";s:1:"-";s:1:".";s:1:".";s:1:"/";s:1:"/";i:0;s:1:"0";i:1;s:1:"1";i:2;s:1:"2";i:3;s:1:"3";i:4;s:1:"4";i:5;s:1:"5";i:6;s:1:"6";i:7;s:1:"7";i:8;s:1:"8";i:9;s:1:"9";s:1:":";s:1:":";s:1:";";s:1:";";s:1:"<";s:1:"<";s:1:"=";s:1:"=";s:1:">";s:1:">";s:1:"?";s:1:"?";s:1:"@";s:1:"@";s:1:"A";s:1:"A";s:1:"B";s:1:"B";s:1:"C";s:1:"C";s:1:"D";s:1:"D";s:1:"E";s:1:"E";s:1:"F";s:1:"F";s:1:"G";s:1:"G";s:1:"H";s:1:"H";s:1:"I";s:1:"I";s:1:"J";s:1:"J";s:1:"K";s:1:"K";s:1:"L";s:1:"L";s:1:"M";s:1:"M";s:1:"N";s:1:"N";s:1:"O";s:1:"O";s:1:"P";s:1:"P";s:1:"Q";s:1:"Q";s:1:"R";s:1:"R";s:1:"S";s:1:"S";s:1:"T";s:1:"T";s:1:"U";s:1:"U";s:1:"V";s:1:"V";s:1:"W";s:1:"W";s:1:"X";s:1:"X";s:1:"Y";s:1:"Y";s:1:"Z";s:1:"Z";s:1:"[";s:1:"[";s:1:"\";s:1:"\";s:1:"]";s:1:"]";s:1:"^";s:1:"^";s:1:"_";s:1:"_";s:1:"`";s:3:"";s:1:"a";s:1:"a";s:1:"b";s:1:"b";s:1:"c";s:1:"c";s:1:"d";s:1:"d";s:1:"e";s:1:"e";s:1:"f";s:1:"f";s:1:"g";s:1:"g";s:1:"h";s:1:"h";s:1:"i";s:1:"i";s:1:"j";s:1:"j";s:1:"k";s:1:"k";s:1:"l";s:1:"l";s:1:"m";s:1:"m";s:1:"n";s:1:"n";s:1:"o";s:1:"o";s:1:"p";s:1:"p";s:1:"q";s:1:"q";s:1:"r";s:1:"r";s:1:"s";s:1:"s";s:1:"t";s:1:"t";s:1:"u";s:1:"u";s:1:"v";s:1:"v";s:1:"w";s:1:"w";s:1:"x";s:1:"x";s:1:"y";s:1:"y";s:1:"z";s:1:"z";s:1:"{";s:1:"{";s:1:"|";s:1:"|";s:1:"}";s:1:"}";s:1:"~";s:1:"~";s:1:"<22>";s:2:"¡";s:1:"<22>";s:2:"¢";s:1:"<22>";s:2:"£";s:1:"<22>";s:3:"";s:1:"<22>";s:2:"¥";s:1:"<22>";s:2:"ƒ";s:1:"<22>";s:2:"§";s:1:"<22>";s:2:"¤";s:1:"<22>";s:1:"'";s:1:"<22>";s:3:"“";s:1:"<22>";s:2:"«";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"fi";s:1:"<22>";s:3:"fl";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"†";s:1:"<22>";s:3:"‡";s:1:"<22>";s:2:"·";s:1:"<22>";s:2:"¶";s:1:"<22>";s:3:"•";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"„";s:1:"<22>";s:3:"”";s:1:"<22>";s:2:"»";s:1:"<22>";s:3:"…";s:1:"<22>";s:3:"‰";s:1:"<22>";s:2:"¿";s:1:"<22>";s:1:"`";s:1:"<22>";s:2:"´";s:1:"<22>";s:2:"ˆ";s:1:"<22>";s:2:"˜";s:1:"<22>";s:2:"¯";s:1:"<22>";s:2:"˘";s:1:"<22>";s:2:"˙";s:1:"<22>";s:2:"¨";s:1:"<22>";s:2:"˚";s:1:"<22>";s:2:"¸";s:1:"<22>";s:2:"˝";s:1:"<22>";s:2:"˛";s:1:"<22>";s:2:"ˇ";s:1:"<22>";s:3:"—";s:1:"<22>";s:2:"Æ";s:1:"<22>";s:2:"ª";s:1:"<22>";s:2:"Ł";s:1:"<22>";s:2:"Ø";s:1:"<22>";s:2:"Œ";s:1:"<22>";s:2:"º";s:1:"<22>";s:2:"æ";s:1:"<22>";s:2:"ı";s:1:"<22>";s:2:"ł";s:1:"<22>";s:2:"ø";s:1:"<22>";s:2:"œ";s:1:"<22>";s:2:"ß";}

View File

@@ -0,0 +1 @@
a:189:{s:1:" ";s:1:" ";s:1:"!";s:1:"!";s:1:""";s:3:"∀";s:1:"#";s:1:"#";s:1:"$";s:3:"∃";s:1:"%";s:1:"%";s:1:"&";s:1:"&";s:1:"'";s:3:"∋";s:1:"(";s:1:"(";s:1:")";s:1:")";s:1:"*";s:3:"";s:1:"+";s:1:"+";s:1:",";s:1:",";s:1:"-";s:3:"";s:1:".";s:1:".";s:1:"/";s:1:"/";i:0;s:1:"0";i:1;s:1:"1";i:2;s:1:"2";i:3;s:1:"3";i:4;s:1:"4";i:5;s:1:"5";i:6;s:1:"6";i:7;s:1:"7";i:8;s:1:"8";i:9;s:1:"9";s:1:":";s:1:":";s:1:";";s:1:";";s:1:"<";s:1:"<";s:1:"=";s:1:"=";s:1:">";s:1:">";s:1:"?";s:1:"?";s:1:"@";s:3:"≅";s:1:"A";s:2:"Α";s:1:"B";s:2:"Β";s:1:"C";s:2:"Χ";s:1:"D";s:2:"Δ";s:1:"E";s:2:"Ε";s:1:"F";s:2:"Φ";s:1:"G";s:2:"Γ";s:1:"H";s:2:"Η";s:1:"I";s:2:"Ι";s:1:"J";s:2:"ϑ";s:1:"K";s:2:"Κ";s:1:"L";s:2:"Λ";s:1:"M";s:2:"Μ";s:1:"N";s:2:"Ν";s:1:"O";s:2:"Ο";s:1:"P";s:2:"Π";s:1:"Q";s:2:"Θ";s:1:"R";s:2:"Ρ";s:1:"S";s:2:"Σ";s:1:"T";s:2:"Τ";s:1:"U";s:2:"Υ";s:1:"V";s:2:"ς";s:1:"W";s:2:"Ω";s:1:"X";s:2:"Ξ";s:1:"Y";s:2:"Ψ";s:1:"Z";s:2:"Ζ";s:1:"[";s:1:"[";s:1:"\";s:3:"∴";s:1:"]";s:1:"]";s:1:"^";s:3:"⊥";s:1:"_";s:1:"_";s:1:"`";s:3:"";s:1:"a";s:2:"α";s:1:"b";s:2:"β";s:1:"c";s:2:"χ";s:1:"d";s:2:"δ";s:1:"e";s:2:"ε";s:1:"f";s:2:"φ";s:1:"g";s:2:"γ";s:1:"h";s:2:"η";s:1:"i";s:2:"ι";s:1:"j";s:2:"ϕ";s:1:"k";s:2:"κ";s:1:"l";s:2:"λ";s:1:"m";s:2:"µ";s:1:"n";s:2:"ν";s:1:"o";s:2:"ο";s:1:"p";s:2:"π";s:1:"q";s:2:"θ";s:1:"r";s:2:"ρ";s:1:"s";s:2:"σ";s:1:"t";s:2:"τ";s:1:"u";s:2:"υ";s:1:"v";s:2:"ϖ";s:1:"w";s:2:"ω";s:1:"x";s:2:"ξ";s:1:"y";s:2:"ψ";s:1:"z";s:2:"ζ";s:1:"{";s:1:"{";s:1:"|";s:1:"|";s:1:"}";s:1:"}";s:1:"~";s:3:"";s:1:"<22>";s:3:"€";s:1:"<22>";s:2:"ϒ";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"≤";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"∞";s:1:"<22>";s:2:"ƒ";s:1:"<22>";s:3:"♣";s:1:"<22>";s:3:"♦";s:1:"<22>";s:3:"♥";s:1:"<22>";s:3:"♠";s:1:"<22>";s:3:"↔";s:1:"<22>";s:3:"←";s:1:"<22>";s:3:"↑";s:1:"<22>";s:3:"→";s:1:"<22>";s:3:"↓";s:1:"<22>";s:2:"°";s:1:"<22>";s:2:"±";s:1:"<22>";s:3:"″";s:1:"<22>";s:3:"≥";s:1:"<22>";s:2:"×";s:1:"<22>";s:3:"∝";s:1:"<22>";s:3:"∂";s:1:"<22>";s:3:"•";s:1:"<22>";s:2:"÷";s:1:"<22>";s:3:"≠";s:1:"<22>";s:3:"≡";s:1:"<22>";s:3:"≈";s:1:"<22>";s:3:"…";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"↵";s:1:"<22>";s:3:"ℵ";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"℘";s:1:"<22>";s:3:"⊗";s:1:"<22>";s:3:"⊕";s:1:"<22>";s:3:"∅";s:1:"<22>";s:3:"∩";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"⊃";s:1:"<22>";s:3:"⊇";s:1:"<22>";s:3:"⊄";s:1:"<22>";s:3:"⊂";s:1:"<22>";s:3:"⊆";s:1:"<22>";s:3:"∈";s:1:"<22>";s:3:"∉";s:1:"<22>";s:3:"∠";s:1:"<22>";s:3:"∇";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"∏";s:1:"<22>";s:3:"√";s:1:"<22>";s:3:"⋅";s:1:"<22>";s:2:"¬";s:1:"<22>";s:3:"∧";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"⇔";s:1:"<22>";s:3:"⇐";s:1:"<22>";s:3:"⇑";s:1:"<22>";s:3:"⇒";s:1:"<22>";s:3:"⇓";s:1:"<22>";s:3:"◊";s:1:"<22>";s:3:"〈";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"∑";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"〉";s:1:"<22>";s:3:"∫";s:1:"<22>";s:3:"⌠";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"⌡";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";}

View File

@@ -0,0 +1 @@
a:202:{s:1:" ";s:1:" ";s:1:"!";s:3:"✁";s:1:""";s:3:"✂";s:1:"#";s:3:"✃";s:1:"$";s:3:"✄";s:1:"%";s:3:"☎";s:1:"&";s:3:"✆";s:1:"'";s:3:"✇";s:1:"(";s:3:"✈";s:1:")";s:3:"✉";s:1:"*";s:3:"☛";s:1:"+";s:3:"☞";s:1:",";s:3:"✌";s:1:"-";s:3:"✍";s:1:".";s:3:"✎";s:1:"/";s:3:"✏";i:0;s:3:"✐";i:1;s:3:"✑";i:2;s:3:"✒";i:3;s:3:"✓";i:4;s:3:"✔";i:5;s:3:"✕";i:6;s:3:"✖";i:7;s:3:"✗";i:8;s:3:"✘";i:9;s:3:"✙";s:1:":";s:3:"✚";s:1:";";s:3:"✛";s:1:"<";s:3:"✜";s:1:"=";s:3:"✝";s:1:">";s:3:"✞";s:1:"?";s:3:"✟";s:1:"@";s:3:"✠";s:1:"A";s:3:"✡";s:1:"B";s:3:"✢";s:1:"C";s:3:"✣";s:1:"D";s:3:"✤";s:1:"E";s:3:"✥";s:1:"F";s:3:"✦";s:1:"G";s:3:"✧";s:1:"H";s:3:"★";s:1:"I";s:3:"✩";s:1:"J";s:3:"✪";s:1:"K";s:3:"✫";s:1:"L";s:3:"✬";s:1:"M";s:3:"✭";s:1:"N";s:3:"✮";s:1:"O";s:3:"✯";s:1:"P";s:3:"✰";s:1:"Q";s:3:"✱";s:1:"R";s:3:"✲";s:1:"S";s:3:"✳";s:1:"T";s:3:"✴";s:1:"U";s:3:"✵";s:1:"V";s:3:"✶";s:1:"W";s:3:"✷";s:1:"X";s:3:"✸";s:1:"Y";s:3:"✹";s:1:"Z";s:3:"✺";s:1:"[";s:3:"✻";s:1:"\";s:3:"✼";s:1:"]";s:3:"✽";s:1:"^";s:3:"✾";s:1:"_";s:3:"✿";s:1:"`";s:3:"❀";s:1:"a";s:3:"❁";s:1:"b";s:3:"❂";s:1:"c";s:3:"❃";s:1:"d";s:3:"❄";s:1:"e";s:3:"❅";s:1:"f";s:3:"❆";s:1:"g";s:3:"❇";s:1:"h";s:3:"❈";s:1:"i";s:3:"❉";s:1:"j";s:3:"❊";s:1:"k";s:3:"❋";s:1:"l";s:3:"●";s:1:"m";s:3:"❍";s:1:"n";s:3:"■";s:1:"o";s:3:"❏";s:1:"p";s:3:"❐";s:1:"q";s:3:"❑";s:1:"r";s:3:"❒";s:1:"s";s:3:"▲";s:1:"t";s:3:"▼";s:1:"u";s:3:"◆";s:1:"v";s:3:"❖";s:1:"w";s:3:"◗";s:1:"x";s:3:"❘";s:1:"y";s:3:"❙";s:1:"z";s:3:"❚";s:1:"{";s:3:"❛";s:1:"|";s:3:"❜";s:1:"}";s:3:"❝";s:1:"~";s:3:"❞";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"❡";s:1:"<22>";s:3:"❢";s:1:"<22>";s:3:"❣";s:1:"<22>";s:3:"❤";s:1:"<22>";s:3:"❥";s:1:"<22>";s:3:"❦";s:1:"<22>";s:3:"❧";s:1:"<22>";s:3:"♣";s:1:"<22>";s:3:"♦";s:1:"<22>";s:3:"♥";s:1:"<22>";s:3:"♠";s:1:"<22>";s:3:"①";s:1:"<22>";s:3:"②";s:1:"<22>";s:3:"③";s:1:"<22>";s:3:"④";s:1:"<22>";s:3:"⑤";s:1:"<22>";s:3:"⑥";s:1:"<22>";s:3:"⑦";s:1:"<22>";s:3:"⑧";s:1:"<22>";s:3:"⑨";s:1:"<22>";s:3:"⑩";s:1:"<22>";s:3:"❶";s:1:"<22>";s:3:"❷";s:1:"<22>";s:3:"❸";s:1:"<22>";s:3:"❹";s:1:"<22>";s:3:"❺";s:1:"<22>";s:3:"❻";s:1:"<22>";s:3:"❼";s:1:"<22>";s:3:"❽";s:1:"<22>";s:3:"❾";s:1:"<22>";s:3:"❿";s:1:"<22>";s:3:"➀";s:1:"<22>";s:3:"➁";s:1:"<22>";s:3:"➂";s:1:"<22>";s:3:"➃";s:1:"<22>";s:3:"➄";s:1:"<22>";s:3:"➅";s:1:"<22>";s:3:"➆";s:1:"<22>";s:3:"➇";s:1:"<22>";s:3:"➈";s:1:"<22>";s:3:"➉";s:1:"<22>";s:3:"➊";s:1:"<22>";s:3:"➋";s:1:"<22>";s:3:"➌";s:1:"<22>";s:3:"➍";s:1:"<22>";s:3:"➎";s:1:"<22>";s:3:"➏";s:1:"<22>";s:3:"➐";s:1:"<22>";s:3:"➑";s:1:"<22>";s:3:"➒";s:1:"<22>";s:3:"➓";s:1:"<22>";s:3:"➔";s:1:"<22>";s:3:"→";s:1:"<22>";s:3:"↔";s:1:"<22>";s:3:"↕";s:1:"<22>";s:3:"➘";s:1:"<22>";s:3:"➙";s:1:"<22>";s:3:"➚";s:1:"<22>";s:3:"➛";s:1:"<22>";s:3:"➜";s:1:"<22>";s:3:"➝";s:1:"<22>";s:3:"➞";s:1:"<22>";s:3:"➟";s:1:"<22>";s:3:"➠";s:1:"<22>";s:3:"➡";s:1:"<22>";s:3:"➢";s:1:"<22>";s:3:"➣";s:1:"<22>";s:3:"➤";s:1:"<22>";s:3:"➥";s:1:"<22>";s:3:"➦";s:1:"<22>";s:3:"➧";s:1:"<22>";s:3:"➨";s:1:"<22>";s:3:"➩";s:1:"<22>";s:3:"➪";s:1:"<22>";s:3:"➫";s:1:"<22>";s:3:"➬";s:1:"<22>";s:3:"➭";s:1:"<22>";s:3:"➮";s:1:"<22>";s:3:"➯";s:1:"<22>";s:3:"➱";s:1:"<22>";s:3:"➲";s:1:"<22>";s:3:"➳";s:1:"<22>";s:3:"➴";s:1:"<22>";s:3:"➵";s:1:"<22>";s:3:"➶";s:1:"<22>";s:3:"➷";s:1:"<22>";s:3:"➸";s:1:"<22>";s:3:"➹";s:1:"<22>";s:3:"➺";s:1:"<22>";s:3:"➻";s:1:"<22>";s:3:"➼";s:1:"<22>";s:3:"➽";s:1:"<22>";s:3:"➾";}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
a:154:{s:2:" ";s:1:" ";s:2:"­";s:1:"-";s:3:"";s:1:"<22>";s:3:"∙";s:1:"<22>";s:2:"ˉ";s:1:"<22>";s:1:" ";s:1:" ";s:1:"!";s:1:"!";s:1:""";s:1:""";s:1:"#";s:1:"#";s:1:"$";s:1:"$";s:1:"%";s:1:"%";s:1:"&";s:1:"&";s:3:"";s:1:"'";s:1:"(";s:1:"(";s:1:")";s:1:")";s:1:"*";s:1:"*";s:1:"+";s:1:"+";s:1:",";s:1:",";s:1:"-";s:1:"-";s:1:".";s:1:".";s:1:"/";s:1:"/";i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;s:1:":";s:1:":";s:1:";";s:1:";";s:1:"<";s:1:"<";s:1:"=";s:1:"=";s:1:">";s:1:">";s:1:"?";s:1:"?";s:1:"@";s:1:"@";s:1:"A";s:1:"A";s:1:"B";s:1:"B";s:1:"C";s:1:"C";s:1:"D";s:1:"D";s:1:"E";s:1:"E";s:1:"F";s:1:"F";s:1:"G";s:1:"G";s:1:"H";s:1:"H";s:1:"I";s:1:"I";s:1:"J";s:1:"J";s:1:"K";s:1:"K";s:1:"L";s:1:"L";s:1:"M";s:1:"M";s:1:"N";s:1:"N";s:1:"O";s:1:"O";s:1:"P";s:1:"P";s:1:"Q";s:1:"Q";s:1:"R";s:1:"R";s:1:"S";s:1:"S";s:1:"T";s:1:"T";s:1:"U";s:1:"U";s:1:"V";s:1:"V";s:1:"W";s:1:"W";s:1:"X";s:1:"X";s:1:"Y";s:1:"Y";s:1:"Z";s:1:"Z";s:1:"[";s:1:"[";s:1:"\";s:1:"\";s:1:"]";s:1:"]";s:1:"^";s:1:"^";s:1:"_";s:1:"_";s:3:"";s:1:"`";s:1:"a";s:1:"a";s:1:"b";s:1:"b";s:1:"c";s:1:"c";s:1:"d";s:1:"d";s:1:"e";s:1:"e";s:1:"f";s:1:"f";s:1:"g";s:1:"g";s:1:"h";s:1:"h";s:1:"i";s:1:"i";s:1:"j";s:1:"j";s:1:"k";s:1:"k";s:1:"l";s:1:"l";s:1:"m";s:1:"m";s:1:"n";s:1:"n";s:1:"o";s:1:"o";s:1:"p";s:1:"p";s:1:"q";s:1:"q";s:1:"r";s:1:"r";s:1:"s";s:1:"s";s:1:"t";s:1:"t";s:1:"u";s:1:"u";s:1:"v";s:1:"v";s:1:"w";s:1:"w";s:1:"x";s:1:"x";s:1:"y";s:1:"y";s:1:"z";s:1:"z";s:1:"{";s:1:"{";s:1:"|";s:1:"|";s:1:"}";s:1:"}";s:1:"~";s:1:"~";s:2:"¡";s:1:"<22>";s:2:"¢";s:1:"<22>";s:2:"£";s:1:"<22>";s:3:"";s:1:"<22>";s:2:"¥";s:1:"<22>";s:2:"ƒ";s:1:"<22>";s:2:"§";s:1:"<22>";s:2:"¤";s:1:"<22>";s:1:"'";s:1:"<22>";s:3:"“";s:1:"<22>";s:2:"«";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"fi";s:1:"<22>";s:3:"fl";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"†";s:1:"<22>";s:3:"‡";s:1:"<22>";s:2:"·";s:1:"<22>";s:2:"¶";s:1:"<22>";s:3:"•";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"„";s:1:"<22>";s:3:"”";s:1:"<22>";s:2:"»";s:1:"<22>";s:3:"…";s:1:"<22>";s:3:"‰";s:1:"<22>";s:2:"¿";s:1:"<22>";s:1:"`";s:1:"<22>";s:2:"´";s:1:"<22>";s:2:"ˆ";s:1:"<22>";s:2:"˜";s:1:"<22>";s:2:"¯";s:1:"<22>";s:2:"˘";s:1:"<22>";s:2:"˙";s:1:"<22>";s:2:"¨";s:1:"<22>";s:2:"˚";s:1:"<22>";s:2:"¸";s:1:"<22>";s:2:"˝";s:1:"<22>";s:2:"˛";s:1:"<22>";s:2:"ˇ";s:1:"<22>";s:3:"—";s:1:"<22>";s:2:"Æ";s:1:"<22>";s:2:"ª";s:1:"<22>";s:2:"Ł";s:1:"<22>";s:2:"Ø";s:1:"<22>";s:2:"Œ";s:1:"<22>";s:2:"º";s:1:"<22>";s:2:"æ";s:1:"<22>";s:2:"ı";s:1:"<22>";s:2:"ł";s:1:"<22>";s:2:"ø";s:1:"<22>";s:2:"œ";s:1:"<22>";s:2:"ß";s:1:"<22>";}

View File

@@ -0,0 +1 @@
a:194:{s:2:" ";s:1:" ";s:3:"∆";s:1:"D";s:3:"Ω";s:1:"W";s:2:"μ";s:1:"m";s:3:"";s:1:"<22>";s:1:" ";s:1:" ";s:1:"!";s:1:"!";s:3:"∀";s:1:""";s:1:"#";s:1:"#";s:3:"∃";s:1:"$";s:1:"%";s:1:"%";s:1:"&";s:1:"&";s:3:"∋";s:1:"'";s:1:"(";s:1:"(";s:1:")";s:1:")";s:3:"";s:1:"*";s:1:"+";s:1:"+";s:1:",";s:1:",";s:3:"";s:1:"-";s:1:".";s:1:".";s:1:"/";s:1:"/";i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;s:1:":";s:1:":";s:1:";";s:1:";";s:1:"<";s:1:"<";s:1:"=";s:1:"=";s:1:">";s:1:">";s:1:"?";s:1:"?";s:3:"≅";s:1:"@";s:2:"Α";s:1:"A";s:2:"Β";s:1:"B";s:2:"Χ";s:1:"C";s:2:"Δ";s:1:"D";s:2:"Ε";s:1:"E";s:2:"Φ";s:1:"F";s:2:"Γ";s:1:"G";s:2:"Η";s:1:"H";s:2:"Ι";s:1:"I";s:2:"ϑ";s:1:"J";s:2:"Κ";s:1:"K";s:2:"Λ";s:1:"L";s:2:"Μ";s:1:"M";s:2:"Ν";s:1:"N";s:2:"Ο";s:1:"O";s:2:"Π";s:1:"P";s:2:"Θ";s:1:"Q";s:2:"Ρ";s:1:"R";s:2:"Σ";s:1:"S";s:2:"Τ";s:1:"T";s:2:"Υ";s:1:"U";s:2:"ς";s:1:"V";s:2:"Ω";s:1:"W";s:2:"Ξ";s:1:"X";s:2:"Ψ";s:1:"Y";s:2:"Ζ";s:1:"Z";s:1:"[";s:1:"[";s:3:"∴";s:1:"\";s:1:"]";s:1:"]";s:3:"⊥";s:1:"^";s:1:"_";s:1:"_";s:3:"";s:1:"`";s:2:"α";s:1:"a";s:2:"β";s:1:"b";s:2:"χ";s:1:"c";s:2:"δ";s:1:"d";s:2:"ε";s:1:"e";s:2:"φ";s:1:"f";s:2:"γ";s:1:"g";s:2:"η";s:1:"h";s:2:"ι";s:1:"i";s:2:"ϕ";s:1:"j";s:2:"κ";s:1:"k";s:2:"λ";s:1:"l";s:2:"µ";s:1:"m";s:2:"ν";s:1:"n";s:2:"ο";s:1:"o";s:2:"π";s:1:"p";s:2:"θ";s:1:"q";s:2:"ρ";s:1:"r";s:2:"σ";s:1:"s";s:2:"τ";s:1:"t";s:2:"υ";s:1:"u";s:2:"ϖ";s:1:"v";s:2:"ω";s:1:"w";s:2:"ξ";s:1:"x";s:2:"ψ";s:1:"y";s:2:"ζ";s:1:"z";s:1:"{";s:1:"{";s:1:"|";s:1:"|";s:1:"}";s:1:"}";s:3:"";s:1:"~";s:3:"€";s:1:"<22>";s:2:"ϒ";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"≤";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"∞";s:1:"<22>";s:2:"ƒ";s:1:"<22>";s:3:"♣";s:1:"<22>";s:3:"♦";s:1:"<22>";s:3:"♥";s:1:"<22>";s:3:"♠";s:1:"<22>";s:3:"↔";s:1:"<22>";s:3:"←";s:1:"<22>";s:3:"↑";s:1:"<22>";s:3:"→";s:1:"<22>";s:3:"↓";s:1:"<22>";s:2:"°";s:1:"<22>";s:2:"±";s:1:"<22>";s:3:"″";s:1:"<22>";s:3:"≥";s:1:"<22>";s:2:"×";s:1:"<22>";s:3:"∝";s:1:"<22>";s:3:"∂";s:1:"<22>";s:3:"•";s:1:"<22>";s:2:"÷";s:1:"<22>";s:3:"≠";s:1:"<22>";s:3:"≡";s:1:"<22>";s:3:"≈";s:1:"<22>";s:3:"…";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"↵";s:1:"<22>";s:3:"ℵ";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"℘";s:1:"<22>";s:3:"⊗";s:1:"<22>";s:3:"⊕";s:1:"<22>";s:3:"∅";s:1:"<22>";s:3:"∩";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"⊃";s:1:"<22>";s:3:"⊇";s:1:"<22>";s:3:"⊄";s:1:"<22>";s:3:"⊂";s:1:"<22>";s:3:"⊆";s:1:"<22>";s:3:"∈";s:1:"<22>";s:3:"∉";s:1:"<22>";s:3:"∠";s:1:"<22>";s:3:"∇";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"∏";s:1:"<22>";s:3:"√";s:1:"<22>";s:3:"⋅";s:1:"<22>";s:2:"¬";s:1:"<22>";s:3:"∧";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"⇔";s:1:"<22>";s:3:"⇐";s:1:"<22>";s:3:"⇑";s:1:"<22>";s:3:"⇒";s:1:"<22>";s:3:"⇓";s:1:"<22>";s:3:"◊";s:1:"<22>";s:3:"〈";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"∑";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"〉";s:1:"<22>";s:3:"∫";s:1:"<22>";s:3:"⌠";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"⌡";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";}

View File

@@ -0,0 +1 @@
a:203:{s:2:" ";s:1:" ";s:1:" ";s:1:" ";s:3:"✁";s:1:"!";s:3:"✂";s:1:""";s:3:"✃";s:1:"#";s:3:"✄";s:1:"$";s:3:"☎";s:1:"%";s:3:"✆";s:1:"&";s:3:"✇";s:1:"'";s:3:"✈";s:1:"(";s:3:"✉";s:1:")";s:3:"☛";s:1:"*";s:3:"☞";s:1:"+";s:3:"✌";s:1:",";s:3:"✍";s:1:"-";s:3:"✎";s:1:".";s:3:"✏";s:1:"/";s:3:"✐";i:0;s:3:"✑";i:1;s:3:"✒";i:2;s:3:"✓";i:3;s:3:"✔";i:4;s:3:"✕";i:5;s:3:"✖";i:6;s:3:"✗";i:7;s:3:"✘";i:8;s:3:"✙";i:9;s:3:"✚";s:1:":";s:3:"✛";s:1:";";s:3:"✜";s:1:"<";s:3:"✝";s:1:"=";s:3:"✞";s:1:">";s:3:"✟";s:1:"?";s:3:"✠";s:1:"@";s:3:"✡";s:1:"A";s:3:"✢";s:1:"B";s:3:"✣";s:1:"C";s:3:"✤";s:1:"D";s:3:"✥";s:1:"E";s:3:"✦";s:1:"F";s:3:"✧";s:1:"G";s:3:"★";s:1:"H";s:3:"✩";s:1:"I";s:3:"✪";s:1:"J";s:3:"✫";s:1:"K";s:3:"✬";s:1:"L";s:3:"✭";s:1:"M";s:3:"✮";s:1:"N";s:3:"✯";s:1:"O";s:3:"✰";s:1:"P";s:3:"✱";s:1:"Q";s:3:"✲";s:1:"R";s:3:"✳";s:1:"S";s:3:"✴";s:1:"T";s:3:"✵";s:1:"U";s:3:"✶";s:1:"V";s:3:"✷";s:1:"W";s:3:"✸";s:1:"X";s:3:"✹";s:1:"Y";s:3:"✺";s:1:"Z";s:3:"✻";s:1:"[";s:3:"✼";s:1:"\";s:3:"✽";s:1:"]";s:3:"✾";s:1:"^";s:3:"✿";s:1:"_";s:3:"❀";s:1:"`";s:3:"❁";s:1:"a";s:3:"❂";s:1:"b";s:3:"❃";s:1:"c";s:3:"❄";s:1:"d";s:3:"❅";s:1:"e";s:3:"❆";s:1:"f";s:3:"❇";s:1:"g";s:3:"❈";s:1:"h";s:3:"❉";s:1:"i";s:3:"❊";s:1:"j";s:3:"❋";s:1:"k";s:3:"●";s:1:"l";s:3:"❍";s:1:"m";s:3:"■";s:1:"n";s:3:"❏";s:1:"o";s:3:"❐";s:1:"p";s:3:"❑";s:1:"q";s:3:"❒";s:1:"r";s:3:"▲";s:1:"s";s:3:"▼";s:1:"t";s:3:"◆";s:1:"u";s:3:"❖";s:1:"v";s:3:"◗";s:1:"w";s:3:"❘";s:1:"x";s:3:"❙";s:1:"y";s:3:"❚";s:1:"z";s:3:"❛";s:1:"{";s:3:"❜";s:1:"|";s:3:"❝";s:1:"}";s:3:"❞";s:1:"~";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"";s:1:"<22>";s:3:"❡";s:1:"<22>";s:3:"❢";s:1:"<22>";s:3:"❣";s:1:"<22>";s:3:"❤";s:1:"<22>";s:3:"❥";s:1:"<22>";s:3:"❦";s:1:"<22>";s:3:"❧";s:1:"<22>";s:3:"♣";s:1:"<22>";s:3:"♦";s:1:"<22>";s:3:"♥";s:1:"<22>";s:3:"♠";s:1:"<22>";s:3:"①";s:1:"<22>";s:3:"②";s:1:"<22>";s:3:"③";s:1:"<22>";s:3:"④";s:1:"<22>";s:3:"⑤";s:1:"<22>";s:3:"⑥";s:1:"<22>";s:3:"⑦";s:1:"<22>";s:3:"⑧";s:1:"<22>";s:3:"⑨";s:1:"<22>";s:3:"⑩";s:1:"<22>";s:3:"❶";s:1:"<22>";s:3:"❷";s:1:"<22>";s:3:"❸";s:1:"<22>";s:3:"❹";s:1:"<22>";s:3:"❺";s:1:"<22>";s:3:"❻";s:1:"<22>";s:3:"❼";s:1:"<22>";s:3:"❽";s:1:"<22>";s:3:"❾";s:1:"<22>";s:3:"❿";s:1:"<22>";s:3:"➀";s:1:"<22>";s:3:"➁";s:1:"<22>";s:3:"➂";s:1:"<22>";s:3:"➃";s:1:"<22>";s:3:"➄";s:1:"<22>";s:3:"➅";s:1:"<22>";s:3:"➆";s:1:"<22>";s:3:"➇";s:1:"<22>";s:3:"➈";s:1:"<22>";s:3:"➉";s:1:"<22>";s:3:"➊";s:1:"<22>";s:3:"➋";s:1:"<22>";s:3:"➌";s:1:"<22>";s:3:"➍";s:1:"<22>";s:3:"➎";s:1:"<22>";s:3:"➏";s:1:"<22>";s:3:"➐";s:1:"<22>";s:3:"➑";s:1:"<22>";s:3:"➒";s:1:"<22>";s:3:"➓";s:1:"<22>";s:3:"➔";s:1:"<22>";s:3:"→";s:1:"<22>";s:3:"↔";s:1:"<22>";s:3:"↕";s:1:"<22>";s:3:"➘";s:1:"<22>";s:3:"➙";s:1:"<22>";s:3:"➚";s:1:"<22>";s:3:"➛";s:1:"<22>";s:3:"➜";s:1:"<22>";s:3:"➝";s:1:"<22>";s:3:"➞";s:1:"<22>";s:3:"➟";s:1:"<22>";s:3:"➠";s:1:"<22>";s:3:"➡";s:1:"<22>";s:3:"➢";s:1:"<22>";s:3:"➣";s:1:"<22>";s:3:"➤";s:1:"<22>";s:3:"➥";s:1:"<22>";s:3:"➦";s:1:"<22>";s:3:"➧";s:1:"<22>";s:3:"➨";s:1:"<22>";s:3:"➩";s:1:"<22>";s:3:"➪";s:1:"<22>";s:3:"➫";s:1:"<22>";s:3:"➬";s:1:"<22>";s:3:"➭";s:1:"<22>";s:3:"➮";s:1:"<22>";s:3:"➯";s:1:"<22>";s:3:"➱";s:1:"<22>";s:3:"➲";s:1:"<22>";s:3:"➳";s:1:"<22>";s:3:"➴";s:1:"<22>";s:3:"➵";s:1:"<22>";s:3:"➶";s:1:"<22>";s:3:"➷";s:1:"<22>";s:3:"➸";s:1:"<22>";s:3:"➹";s:1:"<22>";s:3:"➺";s:1:"<22>";s:3:"➻";s:1:"<22>";s:3:"➼";s:1:"<22>";s:3:"➽";s:1:"<22>";s:3:"➾";s:1:"<22>";}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,155 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork;
/**
* Turkish locale specialized version of Patchwork\Utf8.
*/
class TurkishUtf8 extends Utf8
{
public static function strtocasefold($s, $full = true)
{
if (false !== strpos($s, 'İ')) {
$s = str_replace('İ', 'i', $s);
}
return parent::strtocasefold($s, $full);
}
public static function stripos($s, $needle, $offset = 0)
{
if (false !== strpos($needle, 'I')) {
$needle = str_replace('I', 'ı', $needle);
}
if (false !== strpos($needle, 'İ')) {
$needle = str_replace('İ', 'i', $needle);
}
if (false !== strpos($s, 'I')) {
$s = str_replace('I', 'ı', $s);
}
if (false !== strpos($s, 'İ')) {
$s = str_replace('İ', 'i', $s);
}
return parent::stripos($s, $needle, $offset);
}
public static function strripos($s, $needle, $offset = 0)
{
if (false !== strpos($needle, 'I')) {
$needle = str_replace('I', 'ı', $needle);
}
if (false !== strpos($needle, 'İ')) {
$needle = str_replace('İ', 'i', $needle);
}
if (false !== strpos($s, 'I')) {
$s = str_replace('I', 'ı', $s);
}
if (false !== strpos($s, 'İ')) {
$s = str_replace('İ', 'i', $s);
}
return parent::strripos($s, $needle, $offset);
}
public static function stristr($s, $needle, $before_needle = false)
{
$needle = self::stripos($s, $needle);
if (false === $needle) {
return false;
}
if ($before_needle) {
return self::substr($s, 0, $needle);
}
return self::substr($s, $needle);
}
public static function strrichr($s, $needle, $before_needle = false)
{
$needle = self::strripos($s, $needle);
if (false === $needle) {
return false;
}
if ($before_needle) {
return self::substr($s, 0, $needle);
}
return self::substr($s, $needle);
}
public static function strtolower($s)
{
if (false !== strpos($s, 'İ')) {
$s = str_replace('İ', 'i', $s);
}
if (false !== strpos($s, 'I')) {
$s = str_replace('I', 'ı', $s);
}
return parent::strtolower($s);
}
public static function strtoupper($s)
{
if (false !== strpos($s, 'i')) {
$s = str_replace('i', 'İ', $s);
}
return parent::strtoupper($s);
}
public static function str_ireplace($search, $replace, $subject, &$count = null)
{
$search = (array) $search;
foreach ($search as $i => $s) {
if ('' === $s .= '') {
$s = '/^(?<=.)$/';
} else {
$s = preg_quote($s, '/');
$s = strtr($s, array(
'i' => '(?-i:[iİ])',
'İ' => '(?-i:[iİ])',
'ı' => '(?-i:[ıI])',
'I' => '(?-i:[ıI])',
));
$s = "/{$s}/ui";
}
$search[$i] = $s;
}
$subject = preg_replace($search, $replace, $subject, -1, $replace);
$count = $replace;
return $subject;
}
public static function ucfirst($s)
{
if ('i' === substr($s, 0, 1)) {
return 'İ'.substr($s, 1);
} else {
return parent::ucfirst($s);
}
}
public static function ucwords($s)
{
if (false !== strpos($s, 'i')) {
$s = preg_replace('/\bi/u', 'İ', $s);
}
return parent::ucwords($s);
}
}

View File

@@ -0,0 +1,775 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork;
use Normalizer as n;
/**
* UTF-8 Grapheme Cluster aware string manipulations implementing the quasi complete
* set of native PHP string functions that need UTF-8 awareness and more.
* Missing are printf-family functions.
*/
class Utf8
{
protected static $pathPrefix;
protected static $commonCaseFold = 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",'ι'),
);
protected static $cp1252 = array('€','‚','ƒ','„','…','†','‡','ˆ','‰','Š','‹','Œ','Ž','‘','’','“','”','•','–','—','˜','™','š','›','œ','ž','Ÿ');
protected static $utf8 = array('€','','ƒ','„','…','†','‡','ˆ','‰','Š','','Œ','Ž','','','“','”','•','','—','˜','™','š','','œ','ž','Ÿ');
public static function isUtf8($s)
{
return (bool) preg_match('//u', $s); // Since PHP 5.2.5, this also excludes invalid five and six bytes sequences
}
// Generic UTF-8 to ASCII transliteration
public static function toAscii($s, $subst_chr = '?')
{
if (preg_match("/[\x80-\xFF]/", $s)) {
static $translitExtra = array();
$translitExtra or $translitExtra = static::getData('translit_extra');
$s = n::normalize($s, n::NFKC);
$glibc = 'glibc' === ICONV_IMPL;
preg_match_all('/./u', $s, $s);
foreach ($s[0] as &$c) {
if (!isset($c[1])) {
continue;
}
if ($glibc) {
$t = iconv('UTF-8', 'ASCII//TRANSLIT', $c);
} else {
$t = iconv('UTF-8', 'ASCII//IGNORE//TRANSLIT', $c);
if (!isset($t[0])) {
$t = '?';
} elseif (isset($t[1])) {
$t = ltrim($t, '\'`"^~');
}
}
if ('?' === $t) {
if (isset($translitExtra[$c])) {
$t = $translitExtra[$c];
} else {
$t = n::normalize($c, n::NFD);
if ($t[0] < "\x80") {
$t = $t[0];
} else {
$t = $subst_chr;
}
}
}
$c = $t;
}
$s = implode('', $s[0]);
}
return $s;
}
public static function wrapPath($path = '')
{
if (null === static::$pathPrefix) {
static $hasWfio;
isset($hasWfio) or $hasWfio = extension_loaded('wfio');
if ($hasWfio) {
static::$pathPrefix = 'wfio://';
} elseif ('\\' === DIRECTORY_SEPARATOR && class_exists('COM', false)) {
static::$pathPrefix = 'utf8'.mt_rand();
stream_wrapper_register(static::$pathPrefix, 'Patchwork\Utf8\WindowsStreamWrapper');
static::$pathPrefix .= '://';
} else {
if ('\\' === DIRECTORY_SEPARATOR) {
trigger_error('The `wfio` or `com_dotnet` extension is required to handle UTF-8 filesystem access on Windows');
}
static::$pathPrefix = 'file://';
}
}
return static::$pathPrefix.$path;
}
public static function filter($var, $normalization_form = 4 /* n::NFC */, $leading_combining = '◌')
{
switch (gettype($var)) {
case 'array':
foreach ($var as $k => $v) {
$var[$k] = static::filter($v, $normalization_form, $leading_combining);
}
break;
case 'object':
foreach ($var as $k => $v) {
$var->$k = static::filter($v, $normalization_form, $leading_combining);
}
break;
case 'string':
if (false !== strpos($var, "\r")) {
// Workaround https://bugs.php.net/65732
$var = str_replace("\r\n", "\n", $var);
$var = strtr($var, "\r", "\n");
}
if (preg_match('/[\x80-\xFF]/', $var)) {
if (n::isNormalized($var, $normalization_form)) {
$n = '-';
} else {
$n = n::normalize($var, $normalization_form);
if (isset($n[0])) {
$var = $n;
} else {
$var = static::utf8_encode($var);
}
}
if ($var[0] >= "\x80" && isset($n[0], $leading_combining[0]) && preg_match('/^\p{Mn}/u', $var)) {
// Prevent leading combining chars
// for NFC-safe concatenations.
$var = $leading_combining.$var;
}
}
break;
}
return $var;
}
// Unicode transformation for caseless matching
// see http://unicode.org/reports/tr21/tr21-5.html
public static function strtocasefold($s, $full = true)
{
$s = str_replace(self::$commonCaseFold[0], self::$commonCaseFold[1], $s);
if ($full) {
static $fullCaseFold = false;
$fullCaseFold or $fullCaseFold = static::getData('caseFolding_full');
$s = str_replace($fullCaseFold[0], $fullCaseFold[1], $s);
}
return static::strtolower($s);
}
// Generic case sensitive collation support for self::strnatcmp()
public static function strtonatfold($s)
{
$s = n::normalize($s, n::NFD);
return preg_replace('/\p{Mn}+/u', '', $s);
}
// PHP string functions that need UTF-8 awareness
public static function filter_input($type, $var, $filter = FILTER_DEFAULT, $option = null)
{
if (4 > func_num_args()) {
$var = filter_input($type, $var, $filter);
} else {
$var = filter_input($type, $var, $filter, $option);
}
return static::filter($var);
}
public static function filter_input_array($type, $def = null, $add_empty = true)
{
if (2 > func_num_args()) {
$a = filter_input_array($type);
} else {
$a = filter_input_array($type, $def, $add_empty);
}
return static::filter($a);
}
public static function json_decode($json, $assoc = false, $depth = 512, $options = 0)
{
if (PHP_VERSION_ID < 50400) {
$json = json_decode($json, $assoc, $depth);
} else {
$json = json_decode($json, $assoc, $depth, $options);
}
return static::filter($json);
}
public static function substr($s, $start, $len = 2147483647)
{
static $bug62759;
isset($bug62759) or $bug62759 = extension_loaded('intl') && 'à' === @grapheme_substr('éà', 1, -2);
if ($bug62759) {
return PHP\Shim\Intl::grapheme_substr_workaround62759($s, $start, $len);
} else {
return grapheme_substr($s, $start, $len);
}
}
public static function strlen($s)
{
return grapheme_strlen($s);
}
public static function strpos($s, $needle, $offset = 0)
{
// ignore invalid negative offset to keep compatility
// with php < 5.5.35, < 5.6.21, < 7.0.6
return grapheme_strpos($s, $needle, $offset > 0 ? $offset : 0);
}
public static function strrpos($s, $needle, $offset = 0)
{
return grapheme_strrpos($s, $needle, $offset);
}
public static function stripos($s, $needle, $offset = 0)
{
if (50418 > PHP_VERSION_ID || 50500 == PHP_VERSION_ID) {
// Don't use grapheme_stripos because of https://bugs.php.net/61860
if (!preg_match('//u', $s .= '')) {
return false;
}
if ($offset < 0) {
$offset = 0;
}
if (!$needle = mb_stripos($s, $needle .= '', $offset, 'UTF-8')) {
return $needle;
}
return grapheme_strlen(iconv_substr($s, 0, $needle, 'UTF-8'));
}
return grapheme_stripos($s, $needle, $offset);
}
public static function strripos($s, $needle, $offset = 0)
{
if (50418 > PHP_VERSION_ID || 50500 == PHP_VERSION_ID) {
// Don't use grapheme_strripos because of https://bugs.php.net/61860
if (!preg_match('//u', $s .= '')) {
return false;
}
if ($offset < 0) {
$offset = 0;
}
if (!$needle = mb_strripos($s, $needle .= '', $offset, 'UTF-8')) {
return $needle;
}
return grapheme_strlen(iconv_substr($s, 0, $needle, 'UTF-8'));
}
return grapheme_strripos($s, $needle, $offset);
}
public static function stristr($s, $needle, $before_needle = false)
{
if ('' === $needle .= '') {
return false;
}
return mb_stristr($s, $needle, $before_needle, 'UTF-8');
}
public static function strstr($s, $needle, $before_needle = false)
{
return grapheme_strstr($s, $needle, $before_needle);
}
public static function strrchr($s, $needle, $before_needle = false)
{
return mb_strrchr($s, $needle, $before_needle, 'UTF-8');
}
public static function strrichr($s, $needle, $before_needle = false)
{
return mb_strrichr($s, $needle, $before_needle, 'UTF-8');
}
public static function strtolower($s)
{
return mb_strtolower($s, 'UTF-8');
}
public static function strtoupper($s)
{
return mb_strtoupper($s, 'UTF-8');
}
public static function wordwrap($s, $width = 75, $break = "\n", $cut = false)
{
if (false === wordwrap('-', $width, $break, $cut)) {
return false;
}
is_string($break) or $break = (string) $break;
$w = '';
$s = explode($break, $s);
$iLen = count($s);
$chars = array();
if (1 === $iLen && '' === $s[0]) {
return '';
}
for ($i = 0; $i < $iLen; ++$i) {
if ($i) {
$chars[] = $break;
$w .= '#';
}
$c = $s[$i];
unset($s[$i]);
foreach (self::str_split($c) as $c) {
$chars[] = $c;
$w .= ' ' === $c ? ' ' : '?';
}
}
$s = '';
$j = 0;
$b = $i = -1;
$w = wordwrap($w, $width, '#', $cut);
while (false !== $b = strpos($w, '#', $b + 1)) {
for (++$i; $i < $b; ++$i) {
$s .= $chars[$j];
unset($chars[$j++]);
}
if ($break === $chars[$j] || ' ' === $chars[$j]) {
unset($chars[$j++]);
}
$s .= $break;
}
return $s.implode('', $chars);
}
public static function chr($c)
{
if (0x80 > $c %= 0x200000) {
return chr($c);
}
if (0x800 > $c) {
return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
}
if (0x10000 > $c) {
return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
}
return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
}
public static function count_chars($s, $mode = 0)
{
if (1 != $mode) {
user_error(__METHOD__.'(): the only allowed $mode is 1', E_USER_WARNING);
}
$s = self::str_split($s);
return array_count_values($s);
}
public static function ltrim($s, $charlist = null)
{
$charlist = null === $charlist ? '\s' : self::rxClass($charlist);
return preg_replace("/^{$charlist}+/u", '', $s);
}
public static function ord($s)
{
$a = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
if (0xF0 <= $a) {
return (($a - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
}
if (0xE0 <= $a) {
return (($a - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
}
if (0xC0 <= $a) {
return (($a - 0xC0) << 6) + $s[2] - 0x80;
}
return $a;
}
public static function rtrim($s, $charlist = null)
{
$charlist = null === $charlist ? '\s' : self::rxClass($charlist);
return preg_replace("/{$charlist}+$/u", '', $s);
}
public static function trim($s, $charlist = null)
{
return self::rtrim(self::ltrim($s, $charlist), $charlist);
}
public static function str_ireplace($search, $replace, $subject, &$count = null)
{
$search = (array) $search;
foreach ($search as $i => $s) {
if ('' === $s .= '') {
$s = '/^(?<=.)$/';
} else {
$s = '/'.preg_quote($s, '/').'/ui';
}
$search[$i] = $s;
}
$subject = preg_replace($search, $replace, $subject, -1, $replace);
$count = $replace;
return $subject;
}
public static function str_pad($s, $len, $pad = ' ', $type = STR_PAD_RIGHT)
{
$slen = grapheme_strlen($s);
if ($len <= $slen) {
return $s;
}
$padlen = grapheme_strlen($pad);
$freelen = $len - $slen;
$len = $freelen % $padlen;
if (STR_PAD_RIGHT == $type) {
return $s.str_repeat($pad, $freelen / $padlen).($len ? grapheme_substr($pad, 0, $len) : '');
}
if (STR_PAD_LEFT == $type) {
return str_repeat($pad, $freelen / $padlen).($len ? grapheme_substr($pad, 0, $len) : '').$s;
}
if (STR_PAD_BOTH == $type) {
$freelen /= 2;
$type = ceil($freelen);
$len = $type % $padlen;
$s .= str_repeat($pad, $type / $padlen).($len ? grapheme_substr($pad, 0, $len) : '');
$type = floor($freelen);
$len = $type % $padlen;
return str_repeat($pad, $type / $padlen).($len ? grapheme_substr($pad, 0, $len) : '').$s;
}
user_error(__METHOD__.'(): Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH', E_USER_WARNING);
}
public static function str_shuffle($s)
{
$s = self::str_split($s);
shuffle($s);
return implode('', $s);
}
public static function str_split($s, $len = 1)
{
if (1 > $len = (int) $len) {
$len = func_get_arg(1);
return str_split($s, $len);
}
static $hasIntl;
isset($hasIntl) or $hasIntl = extension_loaded('intl');
if ($hasIntl) {
$a = array();
$p = 0;
$l = strlen($s);
while ($p < $l) {
$a[] = grapheme_extract($s, 1, GRAPHEME_EXTR_COUNT, $p, $p);
}
} else {
preg_match_all('/'.GRAPHEME_CLUSTER_RX.'/u', $s, $a);
$a = $a[0];
}
if (1 == $len) {
return $a;
}
$s = array();
$p = -1;
foreach ($a as $l => $a) {
if ($l % $len) {
$s[$p] .= $a;
} else {
$s[++$p] = $a;
}
}
return $s;
}
public static function str_word_count($s, $format = 0, $charlist = '')
{
$charlist = self::rxClass($charlist, '\pL');
$s = preg_split("/({$charlist}+(?:[\p{Pd}']{$charlist}+)*)/u", $s, -1, PREG_SPLIT_DELIM_CAPTURE);
$charlist = array();
$len = count($s);
if (1 == $format) {
for ($i = 1; $i < $len; $i += 2) {
$charlist[] = $s[$i];
}
} elseif (2 == $format) {
$offset = grapheme_strlen($s[0]);
for ($i = 1; $i < $len; $i += 2) {
$charlist[$offset] = $s[$i];
$offset += grapheme_strlen($s[$i]) + grapheme_strlen($s[$i + 1]);
}
} else {
$charlist = ($len - 1) / 2;
}
return $charlist;
}
public static function strcmp($a, $b)
{
return $a.'' === $b.'' ? 0 : strcmp(n::normalize($a, n::NFD), n::normalize($b, n::NFD));
}
public static function strnatcmp($a, $b)
{
return $a.'' === $b.'' ? 0 : strnatcmp(self::strtonatfold($a), self::strtonatfold($b));
}
public static function strcasecmp($a, $b)
{
return self::strcmp(static::strtocasefold($a), static::strtocasefold($b));
}
public static function strnatcasecmp($a, $b)
{
return self::strnatcmp(static::strtocasefold($a), static::strtocasefold($b));
}
public static function strncasecmp($a, $b, $len)
{
return self::strncmp(static::strtocasefold($a), static::strtocasefold($b), $len);
}
public static function strncmp($a, $b, $len)
{
return self::strcmp(self::substr($a, 0, $len), self::substr($b, 0, $len));
}
public static function strcspn($s, $charlist, $start = 0, $len = 2147483647)
{
if ('' === $charlist .= '') {
return;
}
if ($start || 2147483647 != $len) {
$s = self::substr($s, $start, $len);
}
return preg_match('/^(.*?)'.self::rxClass($charlist).'/us', $s, $len) ? grapheme_strlen($len[1]) : grapheme_strlen($s);
}
public static function strpbrk($s, $charlist)
{
if (preg_match('/'.self::rxClass($charlist).'/us', $s, $m)) {
return substr($s, strpos($s, $m[0]));
} else {
return false;
}
}
public static function strrev($s)
{
$s = self::str_split($s);
return implode('', array_reverse($s));
}
public static function strspn($s, $mask, $start = 0, $len = 2147483647)
{
if ($start || 2147483647 != $len) {
$s = self::substr($s, $start, $len);
}
return preg_match('/^'.self::rxClass($mask).'+/u', $s, $s) ? grapheme_strlen($s[0]) : 0;
}
public static function strtr($s, $from, $to = null)
{
if (null !== $to) {
$from = self::str_split($from);
$to = self::str_split($to);
$a = count($from);
$b = count($to);
if ($a > $b) {
$from = array_slice($from, 0, $b);
} elseif ($a < $b) {
$to = array_slice($to, 0, $a);
}
$from = array_combine($from, $to);
}
return strtr($s, $from);
}
public static function substr_compare($a, $b, $offset, $len = 2147483647, $i = 0)
{
$a = self::substr($a, $offset, $len);
return $i ? static::strcasecmp($a, $b) : self::strcmp($a, $b);
}
public static function substr_count($s, $needle, $offset = 0, $len = 2147483647)
{
return substr_count(self::substr($s, $offset, $len), $needle);
}
public static function substr_replace($s, $replace, $start, $len = 2147483647)
{
$s = self::str_split($s);
$replace = self::str_split($replace);
array_splice($s, $start, $len, $replace);
return implode('', $s);
}
public static function ucfirst($s)
{
$c = iconv_substr($s, 0, 1, 'UTF-8');
return static::ucwords($c).substr($s, strlen($c));
}
public static function lcfirst($s)
{
$c = iconv_substr($s, 0, 1, 'UTF-8');
return static::strtolower($c).substr($s, strlen($c));
}
public static function ucwords($s)
{
return preg_replace_callback(
"/\b(.)/u",
function ($matches) {
return mb_convert_case($matches[1], MB_CASE_TITLE, 'UTF-8');
},
$s
);
}
public static function number_format($number, $decimals = 0, $dec_point = '.', $thousands_sep = ',')
{
if (PHP_VERSION_ID < 50400) {
if (isset($thousands_sep[1]) || isset($dec_point[1])) {
return str_replace(
array('.', ','),
array($dec_point, $thousands_sep),
number_format($number, $decimals, '.', ',')
);
}
}
return number_format($number, $decimals, $dec_point, $thousands_sep);
}
public static function utf8_encode($s)
{
$s = utf8_encode($s);
if (false === strpos($s, "\xC2")) {
return $s;
} else {
return str_replace(self::$cp1252, self::$utf8, $s);
}
}
public static function utf8_decode($s)
{
$s = str_replace(self::$utf8, self::$cp1252, $s);
return utf8_decode($s);
}
public static function strwidth($s)
{
if (false !== strpos($s, "\r")) {
$s = str_replace("\r\n", "\n", $s);
$s = strtr($s, "\r", "\n");
}
$width = 0;
foreach (explode("\n", $s) as $s) {
$s = preg_replace('/\x1B\[[\d;]*m/', '', $s);
$c = substr_count($s, "\xAD") - substr_count($s, "\x08");
$s = preg_replace('/[\x00\x05\x07\p{Mn}\p{Me}\p{Cf}\x{1160}-\x{11FF}\x{200B}]+/u', '', $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);
if ($width < $c = iconv_strlen($s, 'UTF-8') + $wide + $c) {
$width = $c;
}
}
return $width;
}
protected static function rxClass($s, $class = '')
{
$class = array($class);
foreach (self::str_split($s) as $s) {
if ('-' === $s) {
$class[0] = '-'.$class[0];
} elseif (!isset($s[2])) {
$class[0] .= preg_quote($s, '/');
} elseif (1 === iconv_strlen($s, 'UTF-8')) {
$class[0] .= $s;
} else {
$class[] = $s;
}
}
$class[0] = '['.$class[0].']';
if (1 === count($class)) {
return $class[0];
} else {
return '(?:'.implode('|', $class).')';
}
}
protected static function getData($file)
{
$file = __DIR__.'/Utf8/data/'.$file.'.ser';
if (file_exists($file)) {
return unserialize(file_get_contents($file));
} else {
return false;
}
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\Utf8;
/**
* UTF-8 to Code Page conversion using best fit mappings
* See http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/.
*/
class BestFit
{
public static function fit($cp, $s, $placeholder = '?')
{
if (!$len = strlen($s)) {
return 0 === $len ? '' : false;
}
static $map = array();
static $ulen_mask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
$s .= '';
$cp = (string) (int) $cp;
$result = '9' === $cp[0] ? $s.$s : $s;
if ('932' === $cp && 2 === func_num_args()) {
$placeholder = "\x81\x45"; // Katakana Middle Dot in CP932
}
if (!isset($map[$cp])) {
$i = static::getData('to.bestfit'.$cp);
if (false === $i) {
return false;
}
$map[$cp] = $i;
}
$i = $j = 0;
$cp = $map[$cp];
while ($i < $len) {
if ($s[$i] < "\x80") {
$uchr = $s[$i++];
} else {
$ulen = $ulen_mask[$s[$i] & "\xF0"];
$uchr = substr($s, $i, $ulen);
$i += $ulen;
}
if (isset($cp[$uchr])) {
$uchr = $cp[$uchr];
} else {
$uchr = $placeholder;
}
isset($uchr[0]) and $result[$j++] = $uchr[0];
isset($uchr[1]) and $result[$j++] = $uchr[1];
}
return substr($result, 0, $j);
}
protected static function getData($file)
{
$file = __DIR__.'/data/'.$file.'.ser';
if (file_exists($file)) {
return unserialize(file_get_contents($file));
} else {
return false;
}
}
}

View File

@@ -0,0 +1,230 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\Utf8;
use Normalizer as n;
use Patchwork\Utf8 as u;
use Patchwork\PHP\Shim as s;
class Bootup
{
public static function initAll()
{
ini_set('default_charset', 'UTF-8');
self::initUtf8Encode();
self::initIconv();
self::initMbstring();
self::initExif();
self::initIntl();
self::initLocale();
}
public static function initUtf8Encode()
{
function_exists('utf8_encode') or require __DIR__.'/Bootup/utf8_encode.php';
}
public static function initMbstring()
{
if (extension_loaded('mbstring')) {
if (((int) ini_get('mbstring.encoding_translation') || in_array(strtolower(ini_get('mbstring.encoding_translation')), array('on', 'yes', 'true')))
&& !in_array(strtolower(ini_get('mbstring.http_input')), array('pass', '8bit', 'utf-8'))) {
user_error('php.ini settings: Please disable mbstring.encoding_translation or set mbstring.http_input to "pass"', E_USER_WARNING);
}
if (defined('MB_OVERLOAD_STRING') && (MB_OVERLOAD_STRING & (int) ini_get('mbstring.func_overload'))) {
user_error('php.ini settings: Please disable mbstring.func_overload', E_USER_WARNING);
}
if (function_exists('mb_regex_encoding')) {
mb_regex_encoding('UTF-8');
}
ini_set('mbstring.script_encoding', 'pass');
if ('utf-8' !== strtolower(mb_internal_encoding())) {
mb_internal_encoding('UTF-8');
}
if ('none' !== strtolower(mb_substitute_character())) {
mb_substitute_character('none');
}
if (!in_array(strtolower(mb_http_output()), array('pass', '8bit'))) {
mb_http_output('pass');
}
if (!in_array(strtolower(mb_language()), array('uni', 'neutral'))) {
mb_language('uni');
}
} elseif (!function_exists('mb_strlen')) {
extension_loaded('iconv') or static::initIconv();
require __DIR__.'/Bootup/mbstring.php';
}
}
public static function initIconv()
{
if (extension_loaded('iconv')) {
if ('UTF-8' !== strtoupper(iconv_get_encoding('input_encoding'))) {
iconv_set_encoding('input_encoding', 'UTF-8');
}
if ('UTF-8' !== strtoupper(iconv_get_encoding('internal_encoding'))) {
iconv_set_encoding('internal_encoding', 'UTF-8');
}
if ('UTF-8' !== strtoupper(iconv_get_encoding('output_encoding'))) {
iconv_set_encoding('output_encoding', 'UTF-8');
}
} elseif (!function_exists('iconv')) {
require __DIR__.'/Bootup/iconv.php';
}
}
public static function initExif()
{
if (extension_loaded('exif')) {
if (ini_get('exif.encode_unicode') && 'UTF-8' !== strtoupper(ini_get('exif.encode_unicode'))) {
ini_set('exif.encode_unicode', 'UTF-8');
}
if (ini_get('exif.encode_jis') && 'UTF-8' !== strtoupper(ini_get('exif.encode_jis'))) {
ini_set('exif.encode_jis', 'UTF-8');
}
}
}
public static function initIntl()
{
if (defined('GRAPHEME_CLUSTER_RX')) {
return;
}
define('GRAPHEME_CLUSTER_RX', PCRE_VERSION >= '8.32' ? '\X' : s\Intl::GRAPHEME_CLUSTER_RX);
if (!function_exists('grapheme_strlen')) {
extension_loaded('iconv') or static::initIconv();
extension_loaded('mbstring') or static::initMbstring();
require __DIR__.'/Bootup/intl.php';
}
}
public static function initLocale()
{
// With non-UTF-8 locale, basename() bugs.
// Be aware that setlocale() can be slow.
// You'd better properly configure your LANG environment variable to an UTF-8 locale.
if ('' === basename('§')) {
setlocale(LC_ALL, 'C.UTF-8', 'C');
setlocale(LC_CTYPE, 'en_US.UTF-8', 'fr_FR.UTF-8', 'es_ES.UTF-8', 'de_DE.UTF-8', 'ru_RU.UTF-8', 'pt_BR.UTF-8', 'it_IT.UTF-8', 'ja_JP.UTF-8', 'zh_CN.UTF-8', '0');
}
}
public static function filterRequestUri($uri = null, $exit = true)
{
if (!isset($uri)) {
if (!isset($_SERVER['REQUEST_URI'])) {
return;
} else {
$uri = $_SERVER['REQUEST_URI'];
}
}
// Ensures the URL is well formed UTF-8
// When not, assumes Windows-1252 and redirects to the corresponding UTF-8 encoded URL
if (!preg_match('//u', urldecode($uri))) {
$uri = preg_replace_callback(
'/[\x80-\xFF]+/',
function ($m) {return urlencode($m[0]);},
$uri
);
$uri = preg_replace_callback(
'/(?:%[89A-F][0-9A-F])+/i',
function ($m) {return urlencode(u::utf8_encode(urldecode($m[0])));},
$uri
);
if ($exit) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: '.$uri);
exit; // TODO: remove this in 1.2 (BC)
}
}
return $uri;
}
public static function filterRequestInputs($normalization_form = 4 /* n::NFC */, $leading_combining = '◌')
{
// Ensures inputs are well formed UTF-8
// When not, assumes Windows-1252 and converts to UTF-8
// Tests only values, not keys
$a = array(&$_FILES, &$_ENV, &$_GET, &$_POST, &$_COOKIE, &$_SERVER, &$_REQUEST);
foreach ($a[0] as &$r) {
$a[] = array(&$r['name'], &$r['type']);
}
unset($a[0]);
$len = count($a) + 1;
for ($i = 1; $i < $len; ++$i) {
foreach ($a[$i] as &$r) {
$s = $r; // $r is a ref, $s a copy
if (is_array($s)) {
$a[$len++] = &$r;
} else {
$r = static::filterString($s, $normalization_form, $leading_combining);
}
}
unset($a[$i]);
}
}
public static function filterString($s, $normalization_form = 4 /* n::NFC */, $leading_combining = '◌')
{
if (false !== strpos($s, "\r")) {
// Workaround https://bugs.php.net/65732
$s = str_replace("\r\n", "\n", $s);
$s = strtr($s, "\r", "\n");
}
if (preg_match('/[\x80-\xFF]/', $s)) {
if (n::isNormalized($s, $normalization_form)) {
$n = '-';
} else {
$n = n::normalize($s, $normalization_form);
if (isset($n[0])) {
$s = $n;
} else {
$s = u::utf8_encode($s);
}
}
if ($s[0] >= "\x80" && isset($n[0], $leading_combining[0]) && preg_match('/^\p{Mn}/u', $s)) {
// Prevent leading combining chars
// for NFC-safe concatenations.
$s = $leading_combining.$s;
}
}
return $s;
}
}

View File

@@ -0,0 +1,51 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
use Patchwork\PHP\Shim as s;
const ICONV_IMPL = 'Patchwork';
const ICONV_VERSION = '1.0';
const ICONV_MIME_DECODE_STRICT = 1;
const ICONV_MIME_DECODE_CONTINUE_ON_ERROR = 2;
@trigger_error('You are using a fallback implementation of the iconv extension. Installing the native one is highly recommended instead.', E_USER_DEPRECATED);
function iconv($from, $to, $s) {return s\Iconv::iconv($from, $to, $s);}
function iconv_get_encoding($type = 'all') {return s\Iconv::iconv_get_encoding($type);}
function iconv_set_encoding($type, $charset) {return s\Iconv::iconv_set_encoding($type, $charset);}
function iconv_mime_encode($name, $value, $pref = null) {return s\Iconv::iconv_mime_encode($name, $value, $pref);}
function ob_iconv_handler($buffer, $mode) {return s\Iconv::ob_iconv_handler($buffer, $mode);}
function iconv_mime_decode_headers($encoded_headers, $mode = 0, $enc = null) {return s\Iconv::iconv_mime_decode_headers($encoded_headers, $mode, $enc);}
if (extension_loaded('mbstring'))
{
function iconv_strlen($s, $enc = null) {null === $enc and $enc = s\Iconv::$internal_encoding; return mb_strlen($s, $enc);}
function iconv_strpos($s, $needle, $offset = 0, $enc = null) {null === $enc and $enc = s\Iconv::$internal_encoding; return mb_strpos($s, $needle, $offset, $enc);}
function iconv_strrpos($s, $needle, $enc = null) {null === $enc and $enc = s\Iconv::$internal_encoding; return mb_strrpos($s, $needle, 0, $enc);}
function iconv_substr($s, $start, $length = 2147483647, $enc = null) {null === $enc and $enc = s\Iconv::$internal_encoding; return mb_substr($s, $start, $length, $enc);}
function iconv_mime_decode($encoded_headers, $mode = 0, $enc = null) {null === $enc and $enc = s\Iconv::$internal_encoding; return mb_decode_mimeheader($encoded_headers, $mode, $enc);}
}
else
{
if (extension_loaded('xml'))
{
function iconv_strlen($s, $enc = null) {return s\Iconv::strlen1($s, $enc);}
}
else
{
function iconv_strlen($s, $enc = null) {return s\Iconv::strlen2($s, $enc);}
}
function iconv_strpos($s, $needle, $offset = 0, $enc = null) {return s\Iconv::iconv_strpos($s, $needle, $offset, $enc);}
function iconv_strrpos($s, $needle, $enc = null) {return s\Iconv::iconv_strrpos($s, $needle, $enc);}
function iconv_substr($s, $start, $length = 2147483647, $enc = null) {return s\Iconv::iconv_substr($s, $start, $length, $enc);}
function iconv_mime_decode($encoded_headers, $mode = 0, $enc = null) {return s\Iconv::iconv_mime_decode($encoded_headers, $mode, $enc);}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
use Patchwork\PHP\Shim as s;
const GRAPHEME_EXTR_COUNT = 0;
const GRAPHEME_EXTR_MAXBYTES = 1;
const GRAPHEME_EXTR_MAXCHARS = 2;
@trigger_error('You are using a fallback implementation of the intl extension. Installing the native one is highly recommended instead.', E_USER_DEPRECATED);
if (!function_exists('normalizer_is_normalized')) {
function normalizer_is_normalized($s, $form = s\Normalizer::NFC) {return s\Normalizer::isNormalized($s, $form);}
}
if (!function_exists('normalizer_normalize')) {
function normalizer_normalize($s, $form = s\Normalizer::NFC) {return s\Normalizer::normalize($s, $form);}
}
function grapheme_extract($s, $size, $type = 0, $start = 0, &$next = 0) {return s\Intl::grapheme_extract($s, $size, $type, $start, $next);}
function grapheme_stripos($s, $needle, $offset = 0) {return s\Intl::grapheme_stripos($s, $needle, $offset);}
function grapheme_stristr($s, $needle, $before_needle = false) {return s\Intl::grapheme_stristr($s, $needle, $before_needle);}
function grapheme_strlen($s) {return s\Intl::grapheme_strlen($s);}
function grapheme_strpos($s, $needle, $offset = 0) {return s\Intl::grapheme_strpos($s, $needle, $offset);}
function grapheme_strripos($s, $needle, $offset = 0) {return s\Intl::grapheme_strripos($s, $needle, $offset);}
function grapheme_strrpos($s, $needle, $offset = 0) {return s\Intl::grapheme_strrpos($s, $needle, $offset);}
function grapheme_strstr($s, $needle, $before_needle = false) {return s\Intl::grapheme_strstr($s, $needle, $before_needle);}
function grapheme_substr($s, $start, $len = 2147483647) {return s\Intl::grapheme_substr($s, $start, $len);}

View File

@@ -0,0 +1,54 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
use Patchwork\PHP\Shim as s;
const MB_OVERLOAD_MAIL = 1;
const MB_OVERLOAD_STRING = 2;
const MB_OVERLOAD_REGEX = 4;
const MB_CASE_UPPER = 0;
const MB_CASE_LOWER = 1;
const MB_CASE_TITLE = 2;
@trigger_error('You are using a fallback implementation of the mbstring extension. Installing the native one is highly recommended instead.', E_USER_DEPRECATED);
function mb_convert_encoding($s, $to, $from = null) {return s\Mbstring::mb_convert_encoding($s, $to, $from);}
function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) {return s\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f);}
function mb_decode_mimeheader($s) {return s\Mbstring::mb_decode_mimeheader($s);}
function mb_encode_mimeheader($s, $charset = null, $transfer_enc = null, $lf = null, $indent = null) {return s\Mbstring::mb_encode_mimeheader($s, $charset, $transfer_enc, $lf, $indent);}
function mb_convert_case($s, $mode, $enc = null) {return s\Mbstring::mb_convert_case($s, $mode, $enc);}
function mb_internal_encoding($enc = null) {return s\Mbstring::mb_internal_encoding($enc);}
function mb_language($lang = null) {return s\Mbstring::mb_language($lang);}
function mb_list_encodings() {return s\Mbstring::mb_list_encodings();}
function mb_encoding_aliases($encoding) {return s\Mbstring::mb_encoding_aliases($encoding);}
function mb_check_encoding($var = null, $encoding = null) {return s\Mbstring::mb_check_encoding($var, $encoding);}
function mb_detect_encoding($str, $encoding_list = null, $strict = false) {return s\Mbstring::mb_detect_encoding($str, $encoding_list, $strict);}
function mb_detect_order($encoding_list = null) {return s\Mbstring::mb_detect_order($encoding_list);}
function mb_parse_str($s, &$result = array()) {parse_str($s, $result);}
function mb_strlen($s, $enc = null) {return s\Mbstring::mb_strlen($s, $enc);}
function mb_strpos($s, $needle, $offset = 0, $enc = null) {return s\Mbstring::mb_strpos($s, $needle, $offset, $enc);}
function mb_strtolower($s, $enc = null) {return s\Mbstring::mb_strtolower($s, $enc);}
function mb_strtoupper($s, $enc = null) {return s\Mbstring::mb_strtoupper($s, $enc);}
function mb_substitute_character($char = null) {return s\Mbstring::mb_substitute_character($char);}
function mb_substr($s, $start, $length = 2147483647, $enc = null) {return s\Mbstring::mb_substr($s, $start, $length, $enc);}
function mb_stripos($s, $needle, $offset = 0, $enc = null) {return s\Mbstring::mb_stripos($s, $needle, $offset, $enc);}
function mb_stristr($s, $needle, $part = false, $enc = null) {return s\Mbstring::mb_stristr($s, $needle, $part, $enc);}
function mb_strrchr($s, $needle, $part = false, $enc = null) {return s\Mbstring::mb_strrchr($s, $needle, $part, $enc);}
function mb_strrichr($s, $needle, $part = false, $enc = null) {return s\Mbstring::mb_strrichr($s, $needle, $part, $enc);}
function mb_strripos($s, $needle, $offset = 0, $enc = null) {return s\Mbstring::mb_strripos($s, $needle, $offset, $enc);}
function mb_strrpos($s, $needle, $offset = 0, $enc = null) {return s\Mbstring::mb_strrpos($s, $needle, $offset, $enc);}
function mb_strstr($s, $needle, $part = false, $enc = null) {return s\Mbstring::mb_strstr($s, $needle, $part, $enc);}
function mb_get_info($type = 'all') {return s\Mbstring::mb_get_info($type);}
function mb_http_output($enc = null) {return s\Mbstring::mb_http_output($enc);}
function mb_strwidth($s, $enc = null) {return s\Mbstring::mb_strwidth($s, $enc);}
function mb_substr_count($haystack, $needle, $enc = null) {return s\Mbstring::mb_substr_count($haystack, $needle, $enc);}
function mb_output_handler($contents, $status) {return s\Mbstring::mb_output_handler($contents, $status);}
function mb_http_input($type = '') {return s\Mbstring::mb_http_input($type);}

View File

@@ -0,0 +1,17 @@
<?php
/*
* Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
use Patchwork\PHP\Shim as s;
@trigger_error('You are using a fallback implementation of the xml extension. Installing the native one is highly recommended instead.', E_USER_DEPRECATED);
function utf8_encode($s) {return s\Xml::utf8_encode($s);}
function utf8_decode($s) {return s\Xml::utf8_decode($s);}

View File

@@ -0,0 +1,405 @@
<?php
/*
* Copyright (C) 2014 Nicolas Grekas - p@tchwork.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the (at your option):
* Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
* GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
*/
namespace Patchwork\Utf8;
/**
* Unicode UTF-8 aware stream based filesystem access on MS-Windows.
*
* Based on COM Scripting.FileSystemObject object and short paths.
* See Patchwork\Utf8::wrapPath()
*
* See also https://code.google.com/p/php-wfio/ for a PHP extension
* and comments on http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php
*/
class WindowsStreamWrapper
{
public $context;
protected $handle;
public static function hide($path)
{
list($fs, $path) = self::fs($path);
if ($fs->FileExists($path)) {
$fs->GetFile($path)->Attributes |= 2;
} elseif ($fs->FolderExists($path)) {
$fs->GetFolder($path)->Attributes |= 2;
} else {
return false;
}
return true;
}
public static function fs($path, $is_utf8 = true)
{
static $fs;
if (!class_exists('COM', false)) {
throw new \RuntimeException('The `wfio` or `com_dotnet` extension is required to handle UTF-8 filesystem access on Windows');
}
isset($fs) or $fs = new \COM('Scripting.FileSystemObject', null, CP_UTF8);
$path = explode('://', $path, 2);
$path = $path[(int) isset($path[1])];
$path = strtr($path, '/', '\\');
$pre = '';
if (!isset($path[0]) || ('/' !== $path[0] && '\\' !== $path[0] && false === strpos($path, ':'))) {
$pre = getcwd().'\\';
}
$pre = new \VARIANT($pre);
if ($is_utf8) {
$path = new \VARIANT($path, VT_BSTR, CP_UTF8);
} else {
$path = new \VARIANT($path);
}
return array($fs, $fs->getAbsolutePathName(variant_cat($pre, $path)));
}
public function dir_closedir()
{
$this->handle = null;
return true;
}
public function dir_opendir($path, $options)
{
list($fs, $path) = self::fs($path);
if (!$fs->FolderExists($path)) {
return false;
}
$dir = $fs->GetFolder($path);
try {
$f = array('.', '..');
foreach ($dir->SubFolders() as $v) {
$f[] = $v->Name;
}
foreach ($dir->Files as $v) {
$f[] = $v->Name;
}
} catch (\Exception $f) {
$f = array();
}
$this->handle = $f;
return true;
}
public function dir_readdir()
{
if (($c = current($this->handle)) !== false) {
next($this->handle);
return $c;
}
return false;
}
public function dir_rewinddir()
{
reset($this->handle);
return true;
}
public function mkdir($path, $mode, $options)
{
list($fs, $path) = self::fs($path);
try {
if ($options & STREAM_MKDIR_RECURSIVE) {
$path = $fs->GetAbsolutePathName($path);
$path = explode('\\', $path);
if (isset($path[3]) && '' === $path[0].$path[1]) {
$pre = '\\\\'.$path[2].'\\'.$path[3].'\\';
$i = 4;
} elseif (isset($path[1])) {
$pre = $path[0].'\\';
$i = 1;
} else {
$pre = '';
$i = 0;
}
while (isset($path[$i]) && $fs->FolderExists($pre.$path[$i])) {
$pre .= $path[$i++].'\\';
}
if (!isset($path[$i])) {
return false;
}
while (isset($path[$i])) {
$fs->CreateFolder($pre .= $path[$i++].'\\');
}
return true;
} else {
$fs->CreateFolder($path);
}
return true;
} catch (\Exception $e) {
return false;
}
}
public function rename($from, $to)
{
list($fs, $to) = self::fs($to);
if ($fs->FileExists($to) || $fs->FolderExists($to)) {
return false;
}
list(, $from) = self::fs($from);
try {
if ($fs->FileExists($from)) {
$fs->MoveFile($from, $to);
return true;
}
if ($fs->FolderExists($from)) {
$fs->MoveFolder($from, $to);
return true;
}
} catch (\Exception $e) {
}
return false;
}
public function rmdir($path, $options)
{
list($fs, $path) = self::fs($path);
if ($fs->FolderExists($path)) {
return rmdir($fs->GetFolder($path)->ShortPath);
}
return false;
}
public function stream_close()
{
fclose($this->handle);
$this->handle = null;
}
public function stream_eof()
{
return feof($this->handle);
}
public function stream_flush()
{
return fflush($this->handle);
}
public function stream_lock($operation)
{
return flock($this->handle, $operation);
}
public function stream_metadata($path, $option, $value)
{
list($fs, $path) = self::fs($path);
if ($fs->FileExists($path)) {
$f = $fs->GetFile($path);
} elseif ($fs->FileExists($path)) {
$f = $fs->GetFolder($path);
} else {
$f = false;
}
if (STREAM_META_TOUCH === $option) {
if ($f) {
return touch($f->ShortPath);
}
try {
$fs->OpenTextFile($path, 8, true, 0)->Close();
return true;
} catch (\Exception $e) {
}
}
if (!$f) {
return false;
}
switch ($option) {
case STREAM_META_ACCESS: return chmod($f->ShortPath, $value);
case STREAM_META_OWNER:
case STREAM_META_OWNER_NAME: return chown($f->ShortPath, $value);
case STREAM_META_GROUP:
case STREAM_META_GROUP_NAME: return chgrp($f->ShortPath, $value);
default: return false;
}
}
public function stream_open($path, $mode, $options, &$opened_path)
{
$mode .= '';
list($fs, $path) = self::fs($path);
if ($fs->FolderExists($path)) {
return false;
}
try {
if ('x' === $m = substr($mode, 0, 1)) {
$fs->CreateTextFile($path, false)->Close();
$f = $fs->GetFile($path);
$mode[0] = 'w';
} else {
$f = $fs->GetFile($path);
}
} catch (\Exception $f) {
try {
switch ($m) {
case 'w':
case 'c':
case 'a':
$h = $fs->CreateTextFile($path, true);
$f = $fs->GetFile($path);
$h->Close();
break;
default: return false;
}
} catch (\Exception $e) {
return false;
}
}
if (!(STREAM_REPORT_ERRORS & $options)) {
set_error_handler('var_dump', 0);
$e = error_reporting(0);
}
$this->handle = fopen($f->ShortPath, $mode);
if (!(STREAM_REPORT_ERRORS & $options)) {
error_reporting($e);
restore_error_handler();
}
if ($this->handle) {
return true;
}
if (isset($h)) {
$f->Delete(true);
}
return false;
}
public function stream_read($count)
{
return fread($this->handle, $count);
}
public function stream_seek($offset, $whence = SEEK_SET)
{
return fseek($this->handle, $offset, $whence);
}
public function stream_set_option($option, $arg1, $arg2)
{
switch ($option) {
case STREAM_OPTION_BLOCKING: return stream_set_blocking($this->handle, $arg1);
case STREAM_OPTION_READ_TIMEOUT: return stream_set_timeout($this->handle, $arg1, $arg2);
case STREAM_OPTION_WRITE_BUFFER: return stream_set_write_buffer($this->handle, $arg1, $arg2);
default: return false;
}
}
public function stream_stat()
{
return fstat($this->handle);
}
public function stream_tell()
{
return ftell($this->handle);
}
public function stream_truncate($new_size)
{
return ftruncate($this->handle, $new_size);
}
public function stream_write($data)
{
return fwrite($this->handle, $data, strlen($data));
}
public function unlink($path)
{
list($fs, $path) = self::fs($path);
if ($fs->FileExists($path)) {
return unlink($fs->GetFile($path)->ShortPath);
}
return false;
}
public function url_stat($path, $flags)
{
list($fs, $path) = self::fs($path);
if ($fs->FileExists($path)) {
$f = $fs->GetFile($path);
} elseif ($fs->FolderExists($path)) {
$f = $fs->GetFolder($path);
} else {
return false;
}
if (STREAM_URL_STAT_QUIET & $flags) {
set_error_handler('var_dump', 0);
$e = error_reporting(0);
}
if (STREAM_URL_STAT_LINK & $flags) {
$f = @lstat($f->ShortPath) ?: stat($f->ShortPath);
} else {
$f = stat($f->ShortPath);
}
if (STREAM_URL_STAT_QUIET & $flags) {
error_reporting($e);
restore_error_handler();
}
return $f;
}
}

View File

@@ -0,0 +1 @@
a:2:{i:0;a:104:{i:0;s:2:"ß";i:1;s:2:"İ";i:2;s:2:"ʼn";i:3;s:2:"ǰ";i:4;s:2:"ΐ";i:5;s:2:"ΰ";i:6;s:2:"և";i:7;s:3:"ẖ";i:8;s:3:"ẗ";i:9;s:3:"ẘ";i:10;s:3:"ẙ";i:11;s:3:"ẚ";i:12;s:3:"ẞ";i:13;s:3:"ὐ";i:14;s:3:"ὒ";i:15;s:3:"ὔ";i:16;s:3:"ὖ";i:17;s:3:"ᾀ";i:18;s:3:"ᾁ";i:19;s:3:"ᾂ";i:20;s:3:"ᾃ";i:21;s:3:"ᾄ";i:22;s:3:"ᾅ";i:23;s:3:"ᾆ";i:24;s:3:"ᾇ";i:25;s:3:"ᾈ";i:26;s:3:"ᾉ";i:27;s:3:"ᾊ";i:28;s:3:"ᾋ";i:29;s:3:"ᾌ";i:30;s:3:"ᾍ";i:31;s:3:"ᾎ";i:32;s:3:"ᾏ";i:33;s:3:"ᾐ";i:34;s:3:"ᾑ";i:35;s:3:"ᾒ";i:36;s:3:"ᾓ";i:37;s:3:"ᾔ";i:38;s:3:"ᾕ";i:39;s:3:"ᾖ";i:40;s:3:"ᾗ";i:41;s:3:"ᾘ";i:42;s:3:"ᾙ";i:43;s:3:"ᾚ";i:44;s:3:"ᾛ";i:45;s:3:"ᾜ";i:46;s:3:"ᾝ";i:47;s:3:"ᾞ";i:48;s:3:"ᾟ";i:49;s:3:"ᾠ";i:50;s:3:"ᾡ";i:51;s:3:"ᾢ";i:52;s:3:"ᾣ";i:53;s:3:"ᾤ";i:54;s:3:"ᾥ";i:55;s:3:"ᾦ";i:56;s:3:"ᾧ";i:57;s:3:"ᾨ";i:58;s:3:"ᾩ";i:59;s:3:"ᾪ";i:60;s:3:"ᾫ";i:61;s:3:"ᾬ";i:62;s:3:"ᾭ";i:63;s:3:"ᾮ";i:64;s:3:"ᾯ";i:65;s:3:"ᾲ";i:66;s:3:"ᾳ";i:67;s:3:"ᾴ";i:68;s:3:"ᾶ";i:69;s:3:"ᾷ";i:70;s:3:"ᾼ";i:71;s:3:"ῂ";i:72;s:3:"ῃ";i:73;s:3:"ῄ";i:74;s:3:"ῆ";i:75;s:3:"ῇ";i:76;s:3:"ῌ";i:77;s:3:"ῒ";i:78;s:3:"ΐ";i:79;s:3:"ῖ";i:80;s:3:"ῗ";i:81;s:3:"ῢ";i:82;s:3:"ΰ";i:83;s:3:"ῤ";i:84;s:3:"ῦ";i:85;s:3:"ῧ";i:86;s:3:"ῲ";i:87;s:3:"ῳ";i:88;s:3:"ῴ";i:89;s:3:"ῶ";i:90;s:3:"ῷ";i:91;s:3:"ῼ";i:92;s:3:"ff";i:93;s:3:"fi";i:94;s:3:"fl";i:95;s:3:"ffi";i:96;s:3:"ffl";i:97;s:3:"ſt";i:98;s:3:"st";i:99;s:3:"ﬓ";i:100;s:3:"ﬔ";i:101;s:3:"ﬕ";i:102;s:3:"ﬖ";i:103;s:3:"ﬗ";}i:1;a:104:{i:0;s:2:"ss";i:1;s:3:"i̇";i:2;s:3:"ʼn";i:3;s:3:"ǰ";i:4;s:6:"ΐ";i:5;s:6:"ΰ";i:6;s:4:"եւ";i:7;s:3:"ẖ";i:8;s:3:"ẗ";i:9;s:3:"ẘ";i:10;s:3:"ẙ";i:11;s:3:"aʾ";i:12;s:2:"ss";i:13;s:4:"ὐ";i:14;s:6:"ὒ";i:15;s:6:"ὔ";i:16;s:6:"ὖ";i:17;s:5:"ἀι";i:18;s:5:"ἁι";i:19;s:5:"ἂι";i:20;s:5:"ἃι";i:21;s:5:"ἄι";i:22;s:5:"ἅι";i:23;s:5:"ἆι";i:24;s:5:"ἇι";i:25;s:5:"ἀι";i:26;s:5:"ἁι";i:27;s:5:"ἂι";i:28;s:5:"ἃι";i:29;s:5:"ἄι";i:30;s:5:"ἅι";i:31;s:5:"ἆι";i:32;s:5:"ἇι";i:33;s:5:"ἠι";i:34;s:5:"ἡι";i:35;s:5:"ἢι";i:36;s:5:"ἣι";i:37;s:5:"ἤι";i:38;s:5:"ἥι";i:39;s:5:"ἦι";i:40;s:5:"ἧι";i:41;s:5:"ἠι";i:42;s:5:"ἡι";i:43;s:5:"ἢι";i:44;s:5:"ἣι";i:45;s:5:"ἤι";i:46;s:5:"ἥι";i:47;s:5:"ἦι";i:48;s:5:"ἧι";i:49;s:5:"ὠι";i:50;s:5:"ὡι";i:51;s:5:"ὢι";i:52;s:5:"ὣι";i:53;s:5:"ὤι";i:54;s:5:"ὥι";i:55;s:5:"ὦι";i:56;s:5:"ὧι";i:57;s:5:"ὠι";i:58;s:5:"ὡι";i:59;s:5:"ὢι";i:60;s:5:"ὣι";i:61;s:5:"ὤι";i:62;s:5:"ὥι";i:63;s:5:"ὦι";i:64;s:5:"ὧι";i:65;s:5:"ὰι";i:66;s:4:"αι";i:67;s:4:"άι";i:68;s:4:"ᾶ";i:69;s:6:"ᾶι";i:70;s:4:"αι";i:71;s:5:"ὴι";i:72;s:4:"ηι";i:73;s:4:"ήι";i:74;s:4:"ῆ";i:75;s:6:"ῆι";i:76;s:4:"ηι";i:77;s:6:"ῒ";i:78;s:6:"ΐ";i:79;s:4:"ῖ";i:80;s:6:"ῗ";i:81;s:6:"ῢ";i:82;s:6:"ΰ";i:83;s:4:"ῤ";i:84;s:4:"ῦ";i:85;s:6:"ῧ";i:86;s:5:"ὼι";i:87;s:4:"ωι";i:88;s:4:"ώι";i:89;s:4:"ῶ";i:90;s:6:"ῶι";i:91;s:4:"ωι";i:92;s:2:"ff";i:93;s:2:"fi";i:94;s:2:"fl";i:95;s:3:"ffi";i:96;s:3:"ffl";i:97;s:2:"st";i:98;s:2:"st";i:99;s:4:"մն";i:100;s:4:"մե";i:101;s:4:"մի";i:102;s:4:"վն";i:103;s:4:"մխ";}}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More