diff options
author | Nicolas Lœuillet <nicolas@loeuillet.org> | 2015-01-19 21:27:22 +0100 |
---|---|---|
committer | Nicolas Lœuillet <nicolas@loeuillet.org> | 2015-01-19 21:27:22 +0100 |
commit | c78c1a3f08815aab99752026ccdf1dcf63cf43c1 (patch) | |
tree | 99fb545cda7c0850e047aaf6d0060330236fb6e7 /inc/3rdparty/libraries | |
parent | 9e7f6caf03b90076ba7b448aa7f11d40f584045f (diff) | |
download | wallabag-c78c1a3f08815aab99752026ccdf1dcf63cf43c1.tar.gz wallabag-c78c1a3f08815aab99752026ccdf1dcf63cf43c1.tar.zst wallabag-c78c1a3f08815aab99752026ccdf1dcf63cf43c1.zip |
@fivefilters via composer
Diffstat (limited to 'inc/3rdparty/libraries')
28 files changed, 0 insertions, 15257 deletions
diff --git a/inc/3rdparty/libraries/Zend/Cache.php b/inc/3rdparty/libraries/Zend/Cache.php deleted file mode 100644 index d28cb559..00000000 --- a/inc/3rdparty/libraries/Zend/Cache.php +++ /dev/null | |||
@@ -1,250 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend_Cache | ||
17 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
18 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
19 | * @version $Id: Cache.php 24656 2012-02-26 06:02:53Z adamlundrigan $ | ||
20 | */ | ||
21 | |||
22 | |||
23 | /** | ||
24 | * @package Zend_Cache | ||
25 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
26 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
27 | */ | ||
28 | abstract class Zend_Cache | ||
29 | { | ||
30 | |||
31 | /** | ||
32 | * Standard frontends | ||
33 | * | ||
34 | * @var array | ||
35 | */ | ||
36 | public static $standardFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page'); | ||
37 | |||
38 | /** | ||
39 | * Standard backends | ||
40 | * | ||
41 | * @var array | ||
42 | */ | ||
43 | public static $standardBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform', | ||
44 | 'Xcache', 'TwoLevels', 'WinCache', 'ZendServer_Disk', 'ZendServer_ShMem'); | ||
45 | |||
46 | /** | ||
47 | * Standard backends which implement the ExtendedInterface | ||
48 | * | ||
49 | * @var array | ||
50 | */ | ||
51 | public static $standardExtendedBackends = array('File', 'Apc', 'TwoLevels', 'Memcached', 'Libmemcached', 'Sqlite', 'WinCache'); | ||
52 | |||
53 | /** | ||
54 | * Only for backward compatibility (may be removed in next major release) | ||
55 | * | ||
56 | * @var array | ||
57 | * @deprecated | ||
58 | */ | ||
59 | public static $availableFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page'); | ||
60 | |||
61 | /** | ||
62 | * Only for backward compatibility (may be removed in next major release) | ||
63 | * | ||
64 | * @var array | ||
65 | * @deprecated | ||
66 | */ | ||
67 | public static $availableBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform', 'Xcache', 'WinCache', 'TwoLevels'); | ||
68 | |||
69 | /** | ||
70 | * Consts for clean() method | ||
71 | */ | ||
72 | const CLEANING_MODE_ALL = 'all'; | ||
73 | const CLEANING_MODE_OLD = 'old'; | ||
74 | const CLEANING_MODE_MATCHING_TAG = 'matchingTag'; | ||
75 | const CLEANING_MODE_NOT_MATCHING_TAG = 'notMatchingTag'; | ||
76 | const CLEANING_MODE_MATCHING_ANY_TAG = 'matchingAnyTag'; | ||
77 | |||
78 | /** | ||
79 | * Factory | ||
80 | * | ||
81 | * @param mixed $frontend frontend name (string) or Zend_Cache_Frontend_ object | ||
82 | * @param mixed $backend backend name (string) or Zend_Cache_Backend_ object | ||
83 | * @param array $frontendOptions associative array of options for the corresponding frontend constructor | ||
84 | * @param array $backendOptions associative array of options for the corresponding backend constructor | ||
85 | * @param boolean $customFrontendNaming if true, the frontend argument is used as a complete class name ; if false, the frontend argument is used as the end of "Zend_Cache_Frontend_[...]" class name | ||
86 | * @param boolean $customBackendNaming if true, the backend argument is used as a complete class name ; if false, the backend argument is used as the end of "Zend_Cache_Backend_[...]" class name | ||
87 | * @param boolean $autoload if true, there will no require_once for backend and frontend (useful only for custom backends/frontends) | ||
88 | * @throws Zend_Cache_Exception | ||
89 | * @return Zend_Cache_Core|Zend_Cache_Frontend | ||
90 | */ | ||
91 | public static function factory($frontend, $backend, $frontendOptions = array(), $backendOptions = array(), $customFrontendNaming = false, $customBackendNaming = false, $autoload = false) | ||
92 | { | ||
93 | if (is_string($backend)) { | ||
94 | $backendObject = self::_makeBackend($backend, $backendOptions, $customBackendNaming, $autoload); | ||
95 | } else { | ||
96 | if ((is_object($backend)) && (in_array('Zend_Cache_Backend_Interface', class_implements($backend)))) { | ||
97 | $backendObject = $backend; | ||
98 | } else { | ||
99 | self::throwException('backend must be a backend name (string) or an object which implements Zend_Cache_Backend_Interface'); | ||
100 | } | ||
101 | } | ||
102 | if (is_string($frontend)) { | ||
103 | $frontendObject = self::_makeFrontend($frontend, $frontendOptions, $customFrontendNaming, $autoload); | ||
104 | } else { | ||
105 | if (is_object($frontend)) { | ||
106 | $frontendObject = $frontend; | ||
107 | } else { | ||
108 | self::throwException('frontend must be a frontend name (string) or an object'); | ||
109 | } | ||
110 | } | ||
111 | $frontendObject->setBackend($backendObject); | ||
112 | return $frontendObject; | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * Backend Constructor | ||
117 | * | ||
118 | * @param string $backend | ||
119 | * @param array $backendOptions | ||
120 | * @param boolean $customBackendNaming | ||
121 | * @param boolean $autoload | ||
122 | * @return Zend_Cache_Backend | ||
123 | */ | ||
124 | public static function _makeBackend($backend, $backendOptions, $customBackendNaming = false, $autoload = false) | ||
125 | { | ||
126 | if (!$customBackendNaming) { | ||
127 | $backend = self::_normalizeName($backend); | ||
128 | } | ||
129 | if (in_array($backend, Zend_Cache::$standardBackends)) { | ||
130 | // we use a standard backend | ||
131 | $backendClass = 'Zend_Cache_Backend_' . $backend; | ||
132 | // security controls are explicit | ||
133 | require_once realpath(dirname(__FILE__).'/..').DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; | ||
134 | } else { | ||
135 | // we use a custom backend | ||
136 | if (!preg_match('~^[\w\\\\]+$~D', $backend)) { | ||
137 | Zend_Cache::throwException("Invalid backend name [$backend]"); | ||
138 | } | ||
139 | if (!$customBackendNaming) { | ||
140 | // we use this boolean to avoid an API break | ||
141 | $backendClass = 'Zend_Cache_Backend_' . $backend; | ||
142 | } else { | ||
143 | $backendClass = $backend; | ||
144 | } | ||
145 | if (!$autoload) { | ||
146 | $file = str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; | ||
147 | if (!(self::_isReadable($file))) { | ||
148 | self::throwException("file $file not found in include_path"); | ||
149 | } | ||
150 | require_once $file; | ||
151 | } | ||
152 | } | ||
153 | return new $backendClass($backendOptions); | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * Frontend Constructor | ||
158 | * | ||
159 | * @param string $frontend | ||
160 | * @param array $frontendOptions | ||
161 | * @param boolean $customFrontendNaming | ||
162 | * @param boolean $autoload | ||
163 | * @return Zend_Cache_Core|Zend_Cache_Frontend | ||
164 | */ | ||
165 | public static function _makeFrontend($frontend, $frontendOptions = array(), $customFrontendNaming = false, $autoload = false) | ||
166 | { | ||
167 | if (!$customFrontendNaming) { | ||
168 | $frontend = self::_normalizeName($frontend); | ||
169 | } | ||
170 | if (in_array($frontend, self::$standardFrontends)) { | ||
171 | // we use a standard frontend | ||
172 | // For perfs reasons, with frontend == 'Core', we can interact with the Core itself | ||
173 | $frontendClass = 'Zend_Cache_' . ($frontend != 'Core' ? 'Frontend_' : '') . $frontend; | ||
174 | // security controls are explicit | ||
175 | require_once realpath(dirname(__FILE__).'/..').DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; | ||
176 | } else { | ||
177 | // we use a custom frontend | ||
178 | if (!preg_match('~^[\w\\\\]+$~D', $frontend)) { | ||
179 | Zend_Cache::throwException("Invalid frontend name [$frontend]"); | ||
180 | } | ||
181 | if (!$customFrontendNaming) { | ||
182 | // we use this boolean to avoid an API break | ||
183 | $frontendClass = 'Zend_Cache_Frontend_' . $frontend; | ||
184 | } else { | ||
185 | $frontendClass = $frontend; | ||
186 | } | ||
187 | if (!$autoload) { | ||
188 | $file = str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; | ||
189 | if (!(self::_isReadable($file))) { | ||
190 | self::throwException("file $file not found in include_path"); | ||
191 | } | ||
192 | require_once $file; | ||
193 | } | ||
194 | } | ||
195 | return new $frontendClass($frontendOptions); | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * Throw an exception | ||
200 | * | ||
201 | * Note : for perf reasons, the "load" of Zend/Cache/Exception is dynamic | ||
202 | * @param string $msg Message for the exception | ||
203 | * @throws Zend_Cache_Exception | ||
204 | */ | ||
205 | public static function throwException($msg, Exception $e = null) | ||
206 | { | ||
207 | // For perfs reasons, we use this dynamic inclusion | ||
208 | require_once 'Zend/Cache/Exception.php'; | ||
209 | throw new Zend_Cache_Exception($msg, 0, $e); | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * Normalize frontend and backend names to allow multiple words TitleCased | ||
214 | * | ||
215 | * @param string $name Name to normalize | ||
216 | * @return string | ||
217 | */ | ||
218 | protected static function _normalizeName($name) | ||
219 | { | ||
220 | $name = ucfirst(strtolower($name)); | ||
221 | $name = str_replace(array('-', '_', '.'), ' ', $name); | ||
222 | $name = ucwords($name); | ||
223 | $name = str_replace(' ', '', $name); | ||
224 | if (stripos($name, 'ZendServer') === 0) { | ||
225 | $name = 'ZendServer_' . substr($name, strlen('ZendServer')); | ||
226 | } | ||
227 | |||
228 | return $name; | ||
229 | } | ||
230 | |||
231 | /** | ||
232 | * Returns TRUE if the $filename is readable, or FALSE otherwise. | ||
233 | * This function uses the PHP include_path, where PHP's is_readable() | ||
234 | * does not. | ||
235 | * | ||
236 | * Note : this method comes from Zend_Loader (see #ZF-2891 for details) | ||
237 | * | ||
238 | * @param string $filename | ||
239 | * @return boolean | ||
240 | */ | ||
241 | private static function _isReadable($filename) | ||
242 | { | ||
243 | if (!$fh = @fopen($filename, 'r', true)) { | ||
244 | return false; | ||
245 | } | ||
246 | @fclose($fh); | ||
247 | return true; | ||
248 | } | ||
249 | |||
250 | } | ||
diff --git a/inc/3rdparty/libraries/Zend/Cache/Backend.php b/inc/3rdparty/libraries/Zend/Cache/Backend.php deleted file mode 100644 index 803fd446..00000000 --- a/inc/3rdparty/libraries/Zend/Cache/Backend.php +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend_Cache | ||
17 | * @subpackage Zend_Cache_Backend | ||
18 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
19 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
20 | * @version $Id: Backend.php 24989 2012-06-21 07:24:13Z mabe $ | ||
21 | */ | ||
22 | |||
23 | |||
24 | /** | ||
25 | * @package Zend_Cache | ||
26 | * @subpackage Zend_Cache_Backend | ||
27 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
28 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
29 | */ | ||
30 | class Zend_Cache_Backend | ||
31 | { | ||
32 | /** | ||
33 | * Frontend or Core directives | ||
34 | * | ||
35 | * =====> (int) lifetime : | ||
36 | * - Cache lifetime (in seconds) | ||
37 | * - If null, the cache is valid forever | ||
38 | * | ||
39 | * =====> (int) logging : | ||
40 | * - if set to true, a logging is activated throw Zend_Log | ||
41 | * | ||
42 | * @var array directives | ||
43 | */ | ||
44 | protected $_directives = array( | ||
45 | 'lifetime' => 3600, | ||
46 | 'logging' => false, | ||
47 | 'logger' => null | ||
48 | ); | ||
49 | |||
50 | /** | ||
51 | * Available options | ||
52 | * | ||
53 | * @var array available options | ||
54 | */ | ||
55 | protected $_options = array(); | ||
56 | |||
57 | /** | ||
58 | * Constructor | ||
59 | * | ||
60 | * @param array $options Associative array of options | ||
61 | * @throws Zend_Cache_Exception | ||
62 | * @return void | ||
63 | */ | ||
64 | public function __construct(array $options = array()) | ||
65 | { | ||
66 | while (list($name, $value) = each($options)) { | ||
67 | $this->setOption($name, $value); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * Set the frontend directives | ||
73 | * | ||
74 | * @param array $directives Assoc of directives | ||
75 | * @throws Zend_Cache_Exception | ||
76 | * @return void | ||
77 | */ | ||
78 | public function setDirectives($directives) | ||
79 | { | ||
80 | if (!is_array($directives)) Zend_Cache::throwException('Directives parameter must be an array'); | ||
81 | while (list($name, $value) = each($directives)) { | ||
82 | if (!is_string($name)) { | ||
83 | Zend_Cache::throwException("Incorrect option name : $name"); | ||
84 | } | ||
85 | $name = strtolower($name); | ||
86 | if (array_key_exists($name, $this->_directives)) { | ||
87 | $this->_directives[$name] = $value; | ||
88 | } | ||
89 | |||
90 | } | ||
91 | |||
92 | $this->_loggerSanity(); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Set an option | ||
97 | * | ||
98 | * @param string $name | ||
99 | * @param mixed $value | ||
100 | * @throws Zend_Cache_Exception | ||
101 | * @return void | ||
102 | */ | ||
103 | public function setOption($name, $value) | ||
104 | { | ||
105 | if (!is_string($name)) { | ||
106 | Zend_Cache::throwException("Incorrect option name : $name"); | ||
107 | } | ||
108 | $name = strtolower($name); | ||
109 | if (array_key_exists($name, $this->_options)) { | ||
110 | $this->_options[$name] = $value; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Returns an option | ||
116 | * | ||
117 | * @param string $name Optional, the options name to return | ||
118 | * @throws Zend_Cache_Exceptions | ||
119 | * @return mixed | ||
120 | */ | ||
121 | public function getOption($name) | ||
122 | { | ||
123 | $name = strtolower($name); | ||
124 | |||
125 | if (array_key_exists($name, $this->_options)) { | ||
126 | return $this->_options[$name]; | ||
127 | } | ||
128 | |||
129 | if (array_key_exists($name, $this->_directives)) { | ||
130 | return $this->_directives[$name]; | ||
131 | } | ||
132 | |||
133 | Zend_Cache::throwException("Incorrect option name : {$name}"); | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * Get the life time | ||
138 | * | ||
139 | * if $specificLifetime is not false, the given specific life time is used | ||
140 | * else, the global lifetime is used | ||
141 | * | ||
142 | * @param int $specificLifetime | ||
143 | * @return int Cache life time | ||
144 | */ | ||
145 | public function getLifetime($specificLifetime) | ||
146 | { | ||
147 | if ($specificLifetime === false) { | ||
148 | return $this->_directives['lifetime']; | ||
149 | } | ||
150 | return $specificLifetime; | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * Return true if the automatic cleaning is available for the backend | ||
155 | * | ||
156 | * DEPRECATED : use getCapabilities() instead | ||
157 | * | ||
158 | * @deprecated | ||
159 | * @return boolean | ||
160 | */ | ||
161 | public function isAutomaticCleaningAvailable() | ||
162 | { | ||
163 | return true; | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * Determine system TMP directory and detect if we have read access | ||
168 | * | ||
169 | * inspired from Zend_File_Transfer_Adapter_Abstract | ||
170 | * | ||
171 | * @return string | ||
172 | * @throws Zend_Cache_Exception if unable to determine directory | ||
173 | */ | ||
174 | public function getTmpDir() | ||
175 | { | ||
176 | $tmpdir = array(); | ||
177 | foreach (array($_ENV, $_SERVER) as $tab) { | ||
178 | foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $key) { | ||
179 | if (isset($tab[$key]) && is_string($tab[$key])) { | ||
180 | if (($key == 'windir') or ($key == 'SystemRoot')) { | ||
181 | $dir = realpath($tab[$key] . '\\temp'); | ||
182 | } else { | ||
183 | $dir = realpath($tab[$key]); | ||
184 | } | ||
185 | if ($this->_isGoodTmpDir($dir)) { | ||
186 | return $dir; | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | $upload = ini_get('upload_tmp_dir'); | ||
192 | if ($upload) { | ||
193 | $dir = realpath($upload); | ||
194 | if ($this->_isGoodTmpDir($dir)) { | ||
195 | return $dir; | ||
196 | } | ||
197 | } | ||
198 | if (function_exists('sys_get_temp_dir')) { | ||
199 | $dir = sys_get_temp_dir(); | ||
200 | if ($this->_isGoodTmpDir($dir)) { | ||
201 | return $dir; | ||
202 | } | ||
203 | } | ||
204 | // Attemp to detect by creating a temporary file | ||
205 | $tempFile = tempnam(md5(uniqid(rand(), TRUE)), ''); | ||
206 | if ($tempFile) { | ||
207 | $dir = realpath(dirname($tempFile)); | ||
208 | unlink($tempFile); | ||
209 | if ($this->_isGoodTmpDir($dir)) { | ||
210 | return $dir; | ||
211 | } | ||
212 | } | ||
213 | if ($this->_isGoodTmpDir('/tmp')) { | ||
214 | return '/tmp'; | ||
215 | } | ||
216 | if ($this->_isGoodTmpDir('\\temp')) { | ||
217 | return '\\temp'; | ||
218 | } | ||
219 | Zend_Cache::throwException('Could not determine temp directory, please specify a cache_dir manually'); | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * Verify if the given temporary directory is readable and writable | ||
224 | * | ||
225 | * @param string $dir temporary directory | ||
226 | * @return boolean true if the directory is ok | ||
227 | */ | ||
228 | protected function _isGoodTmpDir($dir) | ||
229 | { | ||
230 | if (is_readable($dir)) { | ||
231 | if (is_writable($dir)) { | ||
232 | return true; | ||
233 | } | ||
234 | } | ||
235 | return false; | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * Make sure if we enable logging that the Zend_Log class | ||
240 | * is available. | ||
241 | * Create a default log object if none is set. | ||
242 | * | ||
243 | * @throws Zend_Cache_Exception | ||
244 | * @return void | ||
245 | */ | ||
246 | protected function _loggerSanity() | ||
247 | { | ||
248 | if (!isset($this->_directives['logging']) || !$this->_directives['logging']) { | ||
249 | return; | ||
250 | } | ||
251 | |||
252 | if (isset($this->_directives['logger'])) { | ||
253 | if ($this->_directives['logger'] instanceof Zend_Log) { | ||
254 | return; | ||
255 | } | ||
256 | Zend_Cache::throwException('Logger object is not an instance of Zend_Log class.'); | ||
257 | } | ||
258 | |||
259 | // Create a default logger to the standard output stream | ||
260 | require_once 'Zend/Log.php'; | ||
261 | require_once 'Zend/Log/Writer/Stream.php'; | ||
262 | require_once 'Zend/Log/Filter/Priority.php'; | ||
263 | $logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output')); | ||
264 | $logger->addFilter(new Zend_Log_Filter_Priority(Zend_Log::WARN, '<=')); | ||
265 | $this->_directives['logger'] = $logger; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * Log a message at the WARN (4) priority. | ||
270 | * | ||
271 | * @param string $message | ||
272 | * @throws Zend_Cache_Exception | ||
273 | * @return void | ||
274 | */ | ||
275 | protected function _log($message, $priority = 4) | ||
276 | { | ||
277 | if (!$this->_directives['logging']) { | ||
278 | return; | ||
279 | } | ||
280 | |||
281 | if (!isset($this->_directives['logger'])) { | ||
282 | Zend_Cache::throwException('Logging is enabled but logger is not set.'); | ||
283 | } | ||
284 | $logger = $this->_directives['logger']; | ||
285 | if (!$logger instanceof Zend_Log) { | ||
286 | Zend_Cache::throwException('Logger object is not an instance of Zend_Log class.'); | ||
287 | } | ||
288 | $logger->log($message, $priority); | ||
289 | } | ||
290 | } | ||
diff --git a/inc/3rdparty/libraries/Zend/Cache/Backend/ExtendedInterface.php b/inc/3rdparty/libraries/Zend/Cache/Backend/ExtendedInterface.php deleted file mode 100644 index c192baaf..00000000 --- a/inc/3rdparty/libraries/Zend/Cache/Backend/ExtendedInterface.php +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend_Cache | ||
17 | * @subpackage Zend_Cache_Backend | ||
18 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
19 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
20 | * @version $Id: ExtendedInterface.php 24593 2012-01-05 20:35:02Z matthew $ | ||
21 | */ | ||
22 | |||
23 | /** | ||
24 | * @see Zend_Cache_Backend_Interface | ||
25 | */ | ||
26 | //require_once 'Zend/Cache/Backend/Interface.php'; | ||
27 | require_once dirname(__FILE__).'/Interface.php'; | ||
28 | |||
29 | /** | ||
30 | * @package Zend_Cache | ||
31 | * @subpackage Zend_Cache_Backend | ||
32 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
33 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
34 | */ | ||
35 | interface Zend_Cache_Backend_ExtendedInterface extends Zend_Cache_Backend_Interface | ||
36 | { | ||
37 | |||
38 | /** | ||
39 | * Return an array of stored cache ids | ||
40 | * | ||
41 | * @return array array of stored cache ids (string) | ||
42 | */ | ||
43 | public function getIds(); | ||
44 | |||
45 | /** | ||
46 | * Return an array of stored tags | ||
47 | * | ||
48 | * @return array array of stored tags (string) | ||
49 | */ | ||
50 | public function getTags(); | ||
51 | |||
52 | /** | ||
53 | * Return an array of stored cache ids which match given tags | ||
54 | * | ||
55 | * In case of multiple tags, a logical AND is made between tags | ||
56 | * | ||
57 | * @param array $tags array of tags | ||
58 | * @return array array of matching cache ids (string) | ||
59 | */ | ||
60 | public function getIdsMatchingTags($tags = array()); | ||
61 | |||
62 | /** | ||
63 | * Return an array of stored cache ids which don't match given tags | ||
64 | * | ||
65 | * In case of multiple tags, a logical OR is made between tags | ||
66 | * | ||
67 | * @param array $tags array of tags | ||
68 | * @return array array of not matching cache ids (string) | ||
69 | */ | ||
70 | public function getIdsNotMatchingTags($tags = array()); | ||
71 | |||
72 | /** | ||
73 | * Return an array of stored cache ids which match any given tags | ||
74 | * | ||
75 | * In case of multiple tags, a logical AND is made between tags | ||
76 | * | ||
77 | * @param array $tags array of tags | ||
78 | * @return array array of any matching cache ids (string) | ||
79 | */ | ||
80 | public function getIdsMatchingAnyTags($tags = array()); | ||
81 | |||
82 | /** | ||
83 | * Return the filling percentage of the backend storage | ||
84 | * | ||
85 | * @return int integer between 0 and 100 | ||
86 | */ | ||
87 | public function getFillingPercentage(); | ||
88 | |||
89 | /** | ||
90 | * Return an array of metadatas for the given cache id | ||
91 | * | ||
92 | * The array must include these keys : | ||
93 | * - expire : the expire timestamp | ||
94 | * - tags : a string array of tags | ||
95 | * - mtime : timestamp of last modification time | ||
96 | * | ||
97 | * @param string $id cache id | ||
98 | * @return array array of metadatas (false if the cache id is not found) | ||
99 | */ | ||
100 | public function getMetadatas($id); | ||
101 | |||
102 | /** | ||
103 | * Give (if possible) an extra lifetime to the given cache id | ||
104 | * | ||
105 | * @param string $id cache id | ||
106 | * @param int $extraLifetime | ||
107 | * @return boolean true if ok | ||
108 | */ | ||
109 | public function touch($id, $extraLifetime); | ||
110 | |||
111 | /** | ||
112 | * Return an associative array of capabilities (booleans) of the backend | ||
113 | * | ||
114 | * The array must include these keys : | ||
115 | * - automatic_cleaning (is automating cleaning necessary) | ||
116 | * - tags (are tags supported) | ||
117 | * - expired_read (is it possible to read expired cache records | ||
118 | * (for doNotTestCacheValidity option for example)) | ||
119 | * - priority does the backend deal with priority when saving | ||
120 | * - infinite_lifetime (is infinite lifetime can work with this backend) | ||
121 | * - get_list (is it possible to get the list of cache ids and the complete list of tags) | ||
122 | * | ||
123 | * @return array associative of with capabilities | ||
124 | */ | ||
125 | public function getCapabilities(); | ||
126 | |||
127 | } | ||
diff --git a/inc/3rdparty/libraries/Zend/Cache/Backend/File.php b/inc/3rdparty/libraries/Zend/Cache/Backend/File.php deleted file mode 100644 index 5affbcb3..00000000 --- a/inc/3rdparty/libraries/Zend/Cache/Backend/File.php +++ /dev/null | |||
@@ -1,1034 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend_Cache | ||
17 | * @subpackage Zend_Cache_Backend | ||
18 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
19 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
20 | * @version $Id: File.php 24844 2012-05-31 19:01:36Z rob $ | ||
21 | */ | ||
22 | |||
23 | /** | ||
24 | * @see Zend_Cache_Backend_Interface | ||
25 | */ | ||
26 | //require_once 'Zend/Cache/Backend/ExtendedInterface.php'; | ||
27 | require_once dirname(__FILE__).'/ExtendedInterface.php'; | ||
28 | |||
29 | /** | ||
30 | * @see Zend_Cache_Backend | ||
31 | */ | ||
32 | //require_once 'Zend/Cache/Backend.php'; | ||
33 | require_once realpath(dirname(__FILE__).'/..').DIRECTORY_SEPARATOR.'Backend.php'; | ||
34 | |||
35 | |||
36 | |||
37 | /** | ||
38 | * @package Zend_Cache | ||
39 | * @subpackage Zend_Cache_Backend | ||
40 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
41 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
42 | */ | ||
43 | class Zend_Cache_Backend_File extends Zend_Cache_Backend implements Zend_Cache_Backend_ExtendedInterface | ||
44 | { | ||
45 | /** | ||
46 | * Available options | ||
47 | * | ||
48 | * =====> (string) cache_dir : | ||
49 | * - Directory where to put the cache files | ||
50 | * | ||
51 | * =====> (boolean) file_locking : | ||
52 | * - Enable / disable file_locking | ||
53 | * - Can avoid cache corruption under bad circumstances but it doesn't work on multithread | ||
54 | * webservers and on NFS filesystems for example | ||
55 | * | ||
56 | * =====> (boolean) read_control : | ||
57 | * - Enable / disable read control | ||
58 | * - If enabled, a control key is embeded in cache file and this key is compared with the one | ||
59 | * calculated after the reading. | ||
60 | * | ||
61 | * =====> (string) read_control_type : | ||
62 | * - Type of read control (only if read control is enabled). Available values are : | ||
63 | * 'md5' for a md5 hash control (best but slowest) | ||
64 | * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice) | ||
65 | * 'adler32' for an adler32 hash control (excellent choice too, faster than crc32) | ||
66 | * 'strlen' for a length only test (fastest) | ||
67 | * | ||
68 | * =====> (int) hashed_directory_level : | ||
69 | * - Hashed directory level | ||
70 | * - Set the hashed directory structure level. 0 means "no hashed directory | ||
71 | * structure", 1 means "one level of directory", 2 means "two levels"... | ||
72 | * This option can speed up the cache only when you have many thousands of | ||
73 | * cache file. Only specific benchs can help you to choose the perfect value | ||
74 | * for you. Maybe, 1 or 2 is a good start. | ||
75 | * | ||
76 | * =====> (int) hashed_directory_umask : | ||
77 | * - deprecated | ||
78 | * - Permissions for hashed directory structure | ||
79 | * | ||
80 | * =====> (int) hashed_directory_perm : | ||
81 | * - Permissions for hashed directory structure | ||
82 | * | ||
83 | * =====> (string) file_name_prefix : | ||
84 | * - prefix for cache files | ||
85 | * - be really carefull with this option because a too generic value in a system cache dir | ||
86 | * (like /tmp) can cause disasters when cleaning the cache | ||
87 | * | ||
88 | * =====> (int) cache_file_umask : | ||
89 | * - deprecated | ||
90 | * - Permissions for cache files | ||
91 | * | ||
92 | * =====> (int) cache_file_perm : | ||
93 | * - Permissions for cache files | ||
94 | * | ||
95 | * =====> (int) metatadatas_array_max_size : | ||
96 | * - max size for the metadatas array (don't change this value unless you | ||
97 | * know what you are doing) | ||
98 | * | ||
99 | * @var array available options | ||
100 | */ | ||
101 | protected $_options = array( | ||
102 | 'cache_dir' => null, | ||
103 | 'file_locking' => true, | ||
104 | 'read_control' => true, | ||
105 | 'read_control_type' => 'crc32', | ||
106 | 'hashed_directory_level' => 0, | ||
107 | 'hashed_directory_perm' => 0700, | ||
108 | 'file_name_prefix' => 'zend_cache', | ||
109 | 'cache_file_perm' => 0600, | ||
110 | 'metadatas_array_max_size' => 100 | ||
111 | ); | ||
112 | |||
113 | /** | ||
114 | * Array of metadatas (each item is an associative array) | ||
115 | * | ||
116 | * @var array | ||
117 | */ | ||
118 | protected $_metadatasArray = array(); | ||
119 | |||
120 | |||
121 | /** | ||
122 | * Constructor | ||
123 | * | ||
124 | * @param array $options associative array of options | ||
125 | * @throws Zend_Cache_Exception | ||
126 | * @return void | ||
127 | */ | ||
128 | public function __construct(array $options = array()) | ||
129 | { | ||
130 | parent::__construct($options); | ||
131 | if ($this->_options['cache_dir'] !== null) { // particular case for this option | ||
132 | $this->setCacheDir($this->_options['cache_dir']); | ||
133 | } else { | ||
134 | $this->setCacheDir(self::getTmpDir() . DIRECTORY_SEPARATOR, false); | ||
135 | } | ||
136 | if (isset($this->_options['file_name_prefix'])) { // particular case for this option | ||
137 | if (!preg_match('~^[a-zA-Z0-9_]+$~D', $this->_options['file_name_prefix'])) { | ||
138 | Zend_Cache::throwException('Invalid file_name_prefix : must use only [a-zA-Z0-9_]'); | ||
139 | } | ||
140 | } | ||
141 | if ($this->_options['metadatas_array_max_size'] < 10) { | ||
142 | Zend_Cache::throwException('Invalid metadatas_array_max_size, must be > 10'); | ||
143 | } | ||
144 | |||
145 | if (isset($options['hashed_directory_umask'])) { | ||
146 | // See #ZF-12047 | ||
147 | trigger_error("'hashed_directory_umask' is deprecated -> please use 'hashed_directory_perm' instead", E_USER_NOTICE); | ||
148 | if (!isset($options['hashed_directory_perm'])) { | ||
149 | $options['hashed_directory_perm'] = $options['hashed_directory_umask']; | ||
150 | } | ||
151 | } | ||
152 | if (isset($options['hashed_directory_perm']) && is_string($options['hashed_directory_perm'])) { | ||
153 | // See #ZF-4422 | ||
154 | $this->_options['hashed_directory_perm'] = octdec($this->_options['hashed_directory_perm']); | ||
155 | } | ||
156 | |||
157 | if (isset($options['cache_file_umask'])) { | ||
158 | // See #ZF-12047 | ||
159 | trigger_error("'cache_file_umask' is deprecated -> please use 'cache_file_perm' instead", E_USER_NOTICE); | ||
160 | if (!isset($options['cache_file_perm'])) { | ||
161 | $options['cache_file_perm'] = $options['cache_file_umask']; | ||
162 | } | ||
163 | } | ||
164 | if (isset($options['cache_file_perm']) && is_string($options['cache_file_perm'])) { | ||
165 | // See #ZF-4422 | ||
166 | $this->_options['cache_file_perm'] = octdec($this->_options['cache_file_perm']); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * Set the cache_dir (particular case of setOption() method) | ||
172 | * | ||
173 | * @param string $value | ||
174 | * @param boolean $trailingSeparator If true, add a trailing separator is necessary | ||
175 | * @throws Zend_Cache_Exception | ||
176 | * @return void | ||
177 | */ | ||
178 | public function setCacheDir($value, $trailingSeparator = true) | ||
179 | { | ||
180 | if (!is_dir($value)) { | ||
181 | Zend_Cache::throwException(sprintf('cache_dir "%s" must be a directory', $value)); | ||
182 | } | ||
183 | if (!is_writable($value)) { | ||
184 | Zend_Cache::throwException(sprintf('cache_dir "%s" is not writable', $value)); | ||
185 | } | ||
186 | if ($trailingSeparator) { | ||
187 | // add a trailing DIRECTORY_SEPARATOR if necessary | ||
188 | $value = rtrim(realpath($value), '\\/') . DIRECTORY_SEPARATOR; | ||
189 | } | ||
190 | $this->_options['cache_dir'] = $value; | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * Test if a cache is available for the given id and (if yes) return it (false else) | ||
195 | * | ||
196 | * @param string $id cache id | ||
197 | * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested | ||
198 | * @return string|false cached datas | ||
199 | */ | ||
200 | public function load($id, $doNotTestCacheValidity = false) | ||
201 | { | ||
202 | if (!($this->_test($id, $doNotTestCacheValidity))) { | ||
203 | // The cache is not hit ! | ||
204 | return false; | ||
205 | } | ||
206 | $metadatas = $this->_getMetadatas($id); | ||
207 | $file = $this->_file($id); | ||
208 | $data = $this->_fileGetContents($file); | ||
209 | if ($this->_options['read_control']) { | ||
210 | $hashData = $this->_hash($data, $this->_options['read_control_type']); | ||
211 | $hashControl = $metadatas['hash']; | ||
212 | if ($hashData != $hashControl) { | ||
213 | // Problem detected by the read control ! | ||
214 | $this->_log('Zend_Cache_Backend_File::load() / read_control : stored hash and computed hash do not match'); | ||
215 | $this->remove($id); | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | return $data; | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * Test if a cache is available or not (for the given id) | ||
224 | * | ||
225 | * @param string $id cache id | ||
226 | * @return mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record | ||
227 | */ | ||
228 | public function test($id) | ||
229 | { | ||
230 | clearstatcache(); | ||
231 | return $this->_test($id, false); | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * Save some string datas into a cache record | ||
236 | * | ||
237 | * Note : $data is always "string" (serialization is done by the | ||
238 | * core not by the backend) | ||
239 | * | ||
240 | * @param string $data Datas to cache | ||
241 | * @param string $id Cache id | ||
242 | * @param array $tags Array of strings, the cache record will be tagged by each string entry | ||
243 | * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) | ||
244 | * @return boolean true if no problem | ||
245 | */ | ||
246 | public function save($data, $id, $tags = array(), $specificLifetime = false) | ||
247 | { | ||
248 | clearstatcache(); | ||
249 | $file = $this->_file($id); | ||
250 | $path = $this->_path($id); | ||
251 | if ($this->_options['hashed_directory_level'] > 0) { | ||
252 | if (!is_writable($path)) { | ||
253 | // maybe, we just have to build the directory structure | ||
254 | $this->_recursiveMkdirAndChmod($id); | ||
255 | } | ||
256 | if (!is_writable($path)) { | ||
257 | return false; | ||
258 | } | ||
259 | } | ||
260 | if ($this->_options['read_control']) { | ||
261 | $hash = $this->_hash($data, $this->_options['read_control_type']); | ||
262 | } else { | ||
263 | $hash = ''; | ||
264 | } | ||
265 | $metadatas = array( | ||
266 | 'hash' => $hash, | ||
267 | 'mtime' => time(), | ||
268 | 'expire' => $this->_expireTime($this->getLifetime($specificLifetime)), | ||
269 | 'tags' => $tags | ||
270 | ); | ||
271 | $res = $this->_setMetadatas($id, $metadatas); | ||
272 | if (!$res) { | ||
273 | $this->_log('Zend_Cache_Backend_File::save() / error on saving metadata'); | ||
274 | return false; | ||
275 | } | ||
276 | $res = $this->_filePutContents($file, $data); | ||
277 | return $res; | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * Remove a cache record | ||
282 | * | ||
283 | * @param string $id cache id | ||
284 | * @return boolean true if no problem | ||
285 | */ | ||
286 | public function remove($id) | ||
287 | { | ||
288 | $file = $this->_file($id); | ||
289 | $boolRemove = $this->_remove($file); | ||
290 | $boolMetadata = $this->_delMetadatas($id); | ||
291 | return $boolMetadata && $boolRemove; | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * Clean some cache records | ||
296 | * | ||
297 | * Available modes are : | ||
298 | * | ||
299 | * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) | ||
300 | * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) | ||
301 | * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags | ||
302 | * ($tags can be an array of strings or a single string) | ||
303 | * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} | ||
304 | * ($tags can be an array of strings or a single string) | ||
305 | * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags | ||
306 | * ($tags can be an array of strings or a single string) | ||
307 | * | ||
308 | * @param string $mode clean mode | ||
309 | * @param tags array $tags array of tags | ||
310 | * @return boolean true if no problem | ||
311 | */ | ||
312 | public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) | ||
313 | { | ||
314 | // We use this protected method to hide the recursive stuff | ||
315 | clearstatcache(); | ||
316 | return $this->_clean($this->_options['cache_dir'], $mode, $tags); | ||
317 | } | ||
318 | |||
319 | /** | ||
320 | * Return an array of stored cache ids | ||
321 | * | ||
322 | * @return array array of stored cache ids (string) | ||
323 | */ | ||
324 | public function getIds() | ||
325 | { | ||
326 | return $this->_get($this->_options['cache_dir'], 'ids', array()); | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * Return an array of stored tags | ||
331 | * | ||
332 | * @return array array of stored tags (string) | ||
333 | */ | ||
334 | public function getTags() | ||
335 | { | ||
336 | return $this->_get($this->_options['cache_dir'], 'tags', array()); | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * Return an array of stored cache ids which match given tags | ||
341 | * | ||
342 | * In case of multiple tags, a logical AND is made between tags | ||
343 | * | ||
344 | * @param array $tags array of tags | ||
345 | * @return array array of matching cache ids (string) | ||
346 | */ | ||
347 | public function getIdsMatchingTags($tags = array()) | ||
348 | { | ||
349 | return $this->_get($this->_options['cache_dir'], 'matching', $tags); | ||
350 | } | ||
351 | |||
352 | /** | ||
353 | * Return an array of stored cache ids which don't match given tags | ||
354 | * | ||
355 | * In case of multiple tags, a logical OR is made between tags | ||
356 | * | ||
357 | * @param array $tags array of tags | ||
358 | * @return array array of not matching cache ids (string) | ||
359 | */ | ||
360 | public function getIdsNotMatchingTags($tags = array()) | ||
361 | { | ||
362 | return $this->_get($this->_options['cache_dir'], 'notMatching', $tags); | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * Return an array of stored cache ids which match any given tags | ||
367 | * | ||
368 | * In case of multiple tags, a logical AND is made between tags | ||
369 | * | ||
370 | * @param array $tags array of tags | ||
371 | * @return array array of any matching cache ids (string) | ||
372 | */ | ||
373 | public function getIdsMatchingAnyTags($tags = array()) | ||
374 | { | ||
375 | return $this->_get($this->_options['cache_dir'], 'matchingAny', $tags); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Return the filling percentage of the backend storage | ||
380 | * | ||
381 | * @throws Zend_Cache_Exception | ||
382 | * @return int integer between 0 and 100 | ||
383 | */ | ||
384 | public function getFillingPercentage() | ||
385 | { | ||
386 | $free = disk_free_space($this->_options['cache_dir']); | ||
387 | $total = disk_total_space($this->_options['cache_dir']); | ||
388 | if ($total == 0) { | ||
389 | Zend_Cache::throwException('can\'t get disk_total_space'); | ||
390 | } else { | ||
391 | if ($free >= $total) { | ||
392 | return 100; | ||
393 | } | ||
394 | return ((int) (100. * ($total - $free) / $total)); | ||
395 | } | ||
396 | } | ||
397 | |||
398 | /** | ||
399 | * Return an array of metadatas for the given cache id | ||
400 | * | ||
401 | * The array must include these keys : | ||
402 | * - expire : the expire timestamp | ||
403 | * - tags : a string array of tags | ||
404 | * - mtime : timestamp of last modification time | ||
405 | * | ||
406 | * @param string $id cache id | ||
407 | * @return array array of metadatas (false if the cache id is not found) | ||
408 | */ | ||
409 | public function getMetadatas($id) | ||
410 | { | ||
411 | $metadatas = $this->_getMetadatas($id); | ||
412 | if (!$metadatas) { | ||
413 | return false; | ||
414 | } | ||
415 | if (time() > $metadatas['expire']) { | ||
416 | return false; | ||
417 | } | ||
418 | return array( | ||
419 | 'expire' => $metadatas['expire'], | ||
420 | 'tags' => $metadatas['tags'], | ||
421 | 'mtime' => $metadatas['mtime'] | ||
422 | ); | ||
423 | } | ||
424 | |||
425 | /** | ||
426 | * Give (if possible) an extra lifetime to the given cache id | ||
427 | * | ||
428 | * @param string $id cache id | ||
429 | * @param int $extraLifetime | ||
430 | * @return boolean true if ok | ||
431 | */ | ||
432 | public function touch($id, $extraLifetime) | ||
433 | { | ||
434 | $metadatas = $this->_getMetadatas($id); | ||
435 | if (!$metadatas) { | ||
436 | return false; | ||
437 | } | ||
438 | if (time() > $metadatas['expire']) { | ||
439 | return false; | ||
440 | } | ||
441 | $newMetadatas = array( | ||
442 | 'hash' => $metadatas['hash'], | ||
443 | 'mtime' => time(), | ||
444 | 'expire' => $metadatas['expire'] + $extraLifetime, | ||
445 | 'tags' => $metadatas['tags'] | ||
446 | ); | ||
447 | $res = $this->_setMetadatas($id, $newMetadatas); | ||
448 | if (!$res) { | ||
449 | return false; | ||
450 | } | ||
451 | return true; | ||
452 | } | ||
453 | |||
454 | /** | ||
455 | * Return an associative array of capabilities (booleans) of the backend | ||
456 | * | ||
457 | * The array must include these keys : | ||
458 | * - automatic_cleaning (is automating cleaning necessary) | ||
459 | * - tags (are tags supported) | ||
460 | * - expired_read (is it possible to read expired cache records | ||
461 | * (for doNotTestCacheValidity option for example)) | ||
462 | * - priority does the backend deal with priority when saving | ||
463 | * - infinite_lifetime (is infinite lifetime can work with this backend) | ||
464 | * - get_list (is it possible to get the list of cache ids and the complete list of tags) | ||
465 | * | ||
466 | * @return array associative of with capabilities | ||
467 | */ | ||
468 | public function getCapabilities() | ||
469 | { | ||
470 | return array( | ||
471 | 'automatic_cleaning' => true, | ||
472 | 'tags' => true, | ||
473 | 'expired_read' => true, | ||
474 | 'priority' => false, | ||
475 | 'infinite_lifetime' => true, | ||
476 | 'get_list' => true | ||
477 | ); | ||
478 | } | ||
479 | |||
480 | /** | ||
481 | * PUBLIC METHOD FOR UNIT TESTING ONLY ! | ||
482 | * | ||
483 | * Force a cache record to expire | ||
484 | * | ||
485 | * @param string $id cache id | ||
486 | */ | ||
487 | public function ___expire($id) | ||
488 | { | ||
489 | $metadatas = $this->_getMetadatas($id); | ||
490 | if ($metadatas) { | ||
491 | $metadatas['expire'] = 1; | ||
492 | $this->_setMetadatas($id, $metadatas); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | /** | ||
497 | * Get a metadatas record | ||
498 | * | ||
499 | * @param string $id Cache id | ||
500 | * @return array|false Associative array of metadatas | ||
501 | */ | ||
502 | protected function _getMetadatas($id) | ||
503 | { | ||
504 | if (isset($this->_metadatasArray[$id])) { | ||
505 | return $this->_metadatasArray[$id]; | ||
506 | } else { | ||
507 | $metadatas = $this->_loadMetadatas($id); | ||
508 | if (!$metadatas) { | ||
509 | return false; | ||
510 | } | ||
511 | $this->_setMetadatas($id, $metadatas, false); | ||
512 | return $metadatas; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | /** | ||
517 | * Set a metadatas record | ||
518 | * | ||
519 | * @param string $id Cache id | ||
520 | * @param array $metadatas Associative array of metadatas | ||
521 | * @param boolean $save optional pass false to disable saving to file | ||
522 | * @return boolean True if no problem | ||
523 | */ | ||
524 | protected function _setMetadatas($id, $metadatas, $save = true) | ||
525 | { | ||
526 | if (count($this->_metadatasArray) >= $this->_options['metadatas_array_max_size']) { | ||
527 | $n = (int) ($this->_options['metadatas_array_max_size'] / 10); | ||
528 | $this->_metadatasArray = array_slice($this->_metadatasArray, $n); | ||
529 | } | ||
530 | if ($save) { | ||
531 | $result = $this->_saveMetadatas($id, $metadatas); | ||
532 | if (!$result) { | ||
533 | return false; | ||
534 | } | ||
535 | } | ||
536 | $this->_metadatasArray[$id] = $metadatas; | ||
537 | return true; | ||
538 | } | ||
539 | |||
540 | /** | ||
541 | * Drop a metadata record | ||
542 | * | ||
543 | * @param string $id Cache id | ||
544 | * @return boolean True if no problem | ||
545 | */ | ||
546 | protected function _delMetadatas($id) | ||
547 | { | ||
548 | if (isset($this->_metadatasArray[$id])) { | ||
549 | unset($this->_metadatasArray[$id]); | ||
550 | } | ||
551 | $file = $this->_metadatasFile($id); | ||
552 | return $this->_remove($file); | ||
553 | } | ||
554 | |||
555 | /** | ||
556 | * Clear the metadatas array | ||
557 | * | ||
558 | * @return void | ||
559 | */ | ||
560 | protected function _cleanMetadatas() | ||
561 | { | ||
562 | $this->_metadatasArray = array(); | ||
563 | } | ||
564 | |||
565 | /** | ||
566 | * Load metadatas from disk | ||
567 | * | ||
568 | * @param string $id Cache id | ||
569 | * @return array|false Metadatas associative array | ||
570 | */ | ||
571 | protected function _loadMetadatas($id) | ||
572 | { | ||
573 | $file = $this->_metadatasFile($id); | ||
574 | $result = $this->_fileGetContents($file); | ||
575 | if (!$result) { | ||
576 | return false; | ||
577 | } | ||
578 | $tmp = @unserialize($result); | ||
579 | return $tmp; | ||
580 | } | ||
581 | |||
582 | /** | ||
583 | * Save metadatas to disk | ||
584 | * | ||
585 | * @param string $id Cache id | ||
586 | * @param array $metadatas Associative array | ||
587 | * @return boolean True if no problem | ||
588 | */ | ||
589 | protected function _saveMetadatas($id, $metadatas) | ||
590 | { | ||
591 | $file = $this->_metadatasFile($id); | ||
592 | $result = $this->_filePutContents($file, serialize($metadatas)); | ||
593 | if (!$result) { | ||
594 | return false; | ||
595 | } | ||
596 | return true; | ||
597 | } | ||
598 | |||
599 | /** | ||
600 | * Make and return a file name (with path) for metadatas | ||
601 | * | ||
602 | * @param string $id Cache id | ||
603 | * @return string Metadatas file name (with path) | ||
604 | */ | ||
605 | protected function _metadatasFile($id) | ||
606 | { | ||
607 | $path = $this->_path($id); | ||
608 | $fileName = $this->_idToFileName('internal-metadatas---' . $id); | ||
609 | return $path . $fileName; | ||
610 | } | ||
611 | |||
612 | /** | ||
613 | * Check if the given filename is a metadatas one | ||
614 | * | ||
615 | * @param string $fileName File name | ||
616 | * @return boolean True if it's a metadatas one | ||
617 | */ | ||
618 | protected function _isMetadatasFile($fileName) | ||
619 | { | ||
620 | $id = $this->_fileNameToId($fileName); | ||
621 | if (substr($id, 0, 21) == 'internal-metadatas---') { | ||
622 | return true; | ||
623 | } else { | ||
624 | return false; | ||
625 | } | ||
626 | } | ||
627 | |||
628 | /** | ||
629 | * Remove a file | ||
630 | * | ||
631 | * If we can't remove the file (because of locks or any problem), we will touch | ||
632 | * the file to invalidate it | ||
633 | * | ||
634 | * @param string $file Complete file path | ||
635 | * @return boolean True if ok | ||
636 | */ | ||
637 | protected function _remove($file) | ||
638 | { | ||
639 | if (!is_file($file)) { | ||
640 | return false; | ||
641 | } | ||
642 | if (!@unlink($file)) { | ||
643 | # we can't remove the file (because of locks or any problem) | ||
644 | $this->_log("Zend_Cache_Backend_File::_remove() : we can't remove $file"); | ||
645 | return false; | ||
646 | } | ||
647 | return true; | ||
648 | } | ||
649 | |||
650 | /** | ||
651 | * Clean some cache records (protected method used for recursive stuff) | ||
652 | * | ||
653 | * Available modes are : | ||
654 | * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) | ||
655 | * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) | ||
656 | * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags | ||
657 | * ($tags can be an array of strings or a single string) | ||
658 | * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} | ||
659 | * ($tags can be an array of strings or a single string) | ||
660 | * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags | ||
661 | * ($tags can be an array of strings or a single string) | ||
662 | * | ||
663 | * @param string $dir Directory to clean | ||
664 | * @param string $mode Clean mode | ||
665 | * @param array $tags Array of tags | ||
666 | * @throws Zend_Cache_Exception | ||
667 | * @return boolean True if no problem | ||
668 | */ | ||
669 | protected function _clean($dir, $mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) | ||
670 | { | ||
671 | if (!is_dir($dir)) { | ||
672 | return false; | ||
673 | } | ||
674 | $result = true; | ||
675 | $prefix = $this->_options['file_name_prefix']; | ||
676 | $glob = @glob($dir . $prefix . '--*'); | ||
677 | if ($glob === false) { | ||
678 | // On some systems it is impossible to distinguish between empty match and an error. | ||
679 | return true; | ||
680 | } | ||
681 | foreach ($glob as $file) { | ||
682 | if (is_file($file)) { | ||
683 | $fileName = basename($file); | ||
684 | if ($this->_isMetadatasFile($fileName)) { | ||
685 | // in CLEANING_MODE_ALL, we drop anything, even remainings old metadatas files | ||
686 | if ($mode != Zend_Cache::CLEANING_MODE_ALL) { | ||
687 | continue; | ||
688 | } | ||
689 | } | ||
690 | $id = $this->_fileNameToId($fileName); | ||
691 | $metadatas = $this->_getMetadatas($id); | ||
692 | if ($metadatas === FALSE) { | ||
693 | $metadatas = array('expire' => 1, 'tags' => array()); | ||
694 | } | ||
695 | switch ($mode) { | ||
696 | case Zend_Cache::CLEANING_MODE_ALL: | ||
697 | $res = $this->remove($id); | ||
698 | if (!$res) { | ||
699 | // in this case only, we accept a problem with the metadatas file drop | ||
700 | $res = $this->_remove($file); | ||
701 | } | ||
702 | $result = $result && $res; | ||
703 | break; | ||
704 | case Zend_Cache::CLEANING_MODE_OLD: | ||
705 | if (time() > $metadatas['expire']) { | ||
706 | $result = $this->remove($id) && $result; | ||
707 | } | ||
708 | break; | ||
709 | case Zend_Cache::CLEANING_MODE_MATCHING_TAG: | ||
710 | $matching = true; | ||
711 | foreach ($tags as $tag) { | ||
712 | if (!in_array($tag, $metadatas['tags'])) { | ||
713 | $matching = false; | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | if ($matching) { | ||
718 | $result = $this->remove($id) && $result; | ||
719 | } | ||
720 | break; | ||
721 | case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: | ||
722 | $matching = false; | ||
723 | foreach ($tags as $tag) { | ||
724 | if (in_array($tag, $metadatas['tags'])) { | ||
725 | $matching = true; | ||
726 | break; | ||
727 | } | ||
728 | } | ||
729 | if (!$matching) { | ||
730 | $result = $this->remove($id) && $result; | ||
731 | } | ||
732 | break; | ||
733 | case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: | ||
734 | $matching = false; | ||
735 | foreach ($tags as $tag) { | ||
736 | if (in_array($tag, $metadatas['tags'])) { | ||
737 | $matching = true; | ||
738 | break; | ||
739 | } | ||
740 | } | ||
741 | if ($matching) { | ||
742 | $result = $this->remove($id) && $result; | ||
743 | } | ||
744 | break; | ||
745 | default: | ||
746 | Zend_Cache::throwException('Invalid mode for clean() method'); | ||
747 | break; | ||
748 | } | ||
749 | } | ||
750 | if ((is_dir($file)) and ($this->_options['hashed_directory_level']>0)) { | ||
751 | // Recursive call | ||
752 | $result = $this->_clean($file . DIRECTORY_SEPARATOR, $mode, $tags) && $result; | ||
753 | if ($mode == Zend_Cache::CLEANING_MODE_ALL) { | ||
754 | // we try to drop the structure too | ||
755 | @rmdir($file); | ||
756 | } | ||
757 | } | ||
758 | } | ||
759 | return $result; | ||
760 | } | ||
761 | |||
762 | protected function _get($dir, $mode, $tags = array()) | ||
763 | { | ||
764 | if (!is_dir($dir)) { | ||
765 | return false; | ||
766 | } | ||
767 | $result = array(); | ||
768 | $prefix = $this->_options['file_name_prefix']; | ||
769 | $glob = @glob($dir . $prefix . '--*'); | ||
770 | if ($glob === false) { | ||
771 | // On some systems it is impossible to distinguish between empty match and an error. | ||
772 | return array(); | ||
773 | } | ||
774 | foreach ($glob as $file) { | ||
775 | if (is_file($file)) { | ||
776 | $fileName = basename($file); | ||
777 | $id = $this->_fileNameToId($fileName); | ||
778 | $metadatas = $this->_getMetadatas($id); | ||
779 | if ($metadatas === FALSE) { | ||
780 | continue; | ||
781 | } | ||
782 | if (time() > $metadatas['expire']) { | ||
783 | continue; | ||
784 | } | ||
785 | switch ($mode) { | ||
786 | case 'ids': | ||
787 | $result[] = $id; | ||
788 | break; | ||
789 | case 'tags': | ||
790 | $result = array_unique(array_merge($result, $metadatas['tags'])); | ||
791 | break; | ||
792 | case 'matching': | ||
793 | $matching = true; | ||
794 | foreach ($tags as $tag) { | ||
795 | if (!in_array($tag, $metadatas['tags'])) { | ||
796 | $matching = false; | ||
797 | break; | ||
798 | } | ||
799 | } | ||
800 | if ($matching) { | ||
801 | $result[] = $id; | ||
802 | } | ||
803 | break; | ||
804 | case 'notMatching': | ||
805 | $matching = false; | ||
806 | foreach ($tags as $tag) { | ||
807 | if (in_array($tag, $metadatas['tags'])) { | ||
808 | $matching = true; | ||
809 | break; | ||
810 | } | ||
811 | } | ||
812 | if (!$matching) { | ||
813 | $result[] = $id; | ||
814 | } | ||
815 | break; | ||
816 | case 'matchingAny': | ||
817 | $matching = false; | ||
818 | foreach ($tags as $tag) { | ||
819 | if (in_array($tag, $metadatas['tags'])) { | ||
820 | $matching = true; | ||
821 | break; | ||
822 | } | ||
823 | } | ||
824 | if ($matching) { | ||
825 | $result[] = $id; | ||
826 | } | ||
827 | break; | ||
828 | default: | ||
829 | Zend_Cache::throwException('Invalid mode for _get() method'); | ||
830 | break; | ||
831 | } | ||
832 | } | ||
833 | if ((is_dir($file)) and ($this->_options['hashed_directory_level']>0)) { | ||
834 | // Recursive call | ||
835 | $recursiveRs = $this->_get($file . DIRECTORY_SEPARATOR, $mode, $tags); | ||
836 | if ($recursiveRs === false) { | ||
837 | $this->_log('Zend_Cache_Backend_File::_get() / recursive call : can\'t list entries of "'.$file.'"'); | ||
838 | } else { | ||
839 | $result = array_unique(array_merge($result, $recursiveRs)); | ||
840 | } | ||
841 | } | ||
842 | } | ||
843 | return array_unique($result); | ||
844 | } | ||
845 | |||
846 | /** | ||
847 | * Compute & return the expire time | ||
848 | * | ||
849 | * @return int expire time (unix timestamp) | ||
850 | */ | ||
851 | protected function _expireTime($lifetime) | ||
852 | { | ||
853 | if ($lifetime === null) { | ||
854 | return 9999999999; | ||
855 | } | ||
856 | return time() + $lifetime; | ||
857 | } | ||
858 | |||
859 | /** | ||
860 | * Make a control key with the string containing datas | ||
861 | * | ||
862 | * @param string $data Data | ||
863 | * @param string $controlType Type of control 'md5', 'crc32' or 'strlen' | ||
864 | * @throws Zend_Cache_Exception | ||
865 | * @return string Control key | ||
866 | */ | ||
867 | protected function _hash($data, $controlType) | ||
868 | { | ||
869 | switch ($controlType) { | ||
870 | case 'md5': | ||
871 | return md5($data); | ||
872 | case 'crc32': | ||
873 | return crc32($data); | ||
874 | case 'strlen': | ||
875 | return strlen($data); | ||
876 | case 'adler32': | ||
877 | return hash('adler32', $data); | ||
878 | default: | ||
879 | Zend_Cache::throwException("Incorrect hash function : $controlType"); | ||
880 | } | ||
881 | } | ||
882 | |||
883 | /** | ||
884 | * Transform a cache id into a file name and return it | ||
885 | * | ||
886 | * @param string $id Cache id | ||
887 | * @return string File name | ||
888 | */ | ||
889 | protected function _idToFileName($id) | ||
890 | { | ||
891 | $prefix = $this->_options['file_name_prefix']; | ||
892 | $result = $prefix . '---' . $id; | ||
893 | return $result; | ||
894 | } | ||
895 | |||
896 | /** | ||
897 | * Make and return a file name (with path) | ||
898 | * | ||
899 | * @param string $id Cache id | ||
900 | * @return string File name (with path) | ||
901 | */ | ||
902 | protected function _file($id) | ||
903 | { | ||
904 | $path = $this->_path($id); | ||
905 | $fileName = $this->_idToFileName($id); | ||
906 | return $path . $fileName; | ||
907 | } | ||
908 | |||
909 | /** | ||
910 | * Return the complete directory path of a filename (including hashedDirectoryStructure) | ||
911 | * | ||
912 | * @param string $id Cache id | ||
913 | * @param boolean $parts if true, returns array of directory parts instead of single string | ||
914 | * @return string Complete directory path | ||
915 | */ | ||
916 | protected function _path($id, $parts = false) | ||
917 | { | ||
918 | $partsArray = array(); | ||
919 | $root = $this->_options['cache_dir']; | ||
920 | $prefix = $this->_options['file_name_prefix']; | ||
921 | if ($this->_options['hashed_directory_level']>0) { | ||
922 | $hash = hash('adler32', $id); | ||
923 | for ($i=0 ; $i < $this->_options['hashed_directory_level'] ; $i++) { | ||
924 | $root = $root . $prefix . '--' . substr($hash, 0, $i + 1) . DIRECTORY_SEPARATOR; | ||
925 | $partsArray[] = $root; | ||
926 | } | ||
927 | } | ||
928 | if ($parts) { | ||
929 | return $partsArray; | ||
930 | } else { | ||
931 | return $root; | ||
932 | } | ||
933 | } | ||
934 | |||
935 | /** | ||
936 | * Make the directory strucuture for the given id | ||
937 | * | ||
938 | * @param string $id cache id | ||
939 | * @return boolean true | ||
940 | */ | ||
941 | protected function _recursiveMkdirAndChmod($id) | ||
942 | { | ||
943 | if ($this->_options['hashed_directory_level'] <=0) { | ||
944 | return true; | ||
945 | } | ||
946 | $partsArray = $this->_path($id, true); | ||
947 | foreach ($partsArray as $part) { | ||
948 | if (!is_dir($part)) { | ||
949 | @mkdir($part, $this->_options['hashed_directory_perm']); | ||
950 | @chmod($part, $this->_options['hashed_directory_perm']); // see #ZF-320 (this line is required in some configurations) | ||
951 | } | ||
952 | } | ||
953 | return true; | ||
954 | } | ||
955 | |||
956 | /** | ||
957 | * Test if the given cache id is available (and still valid as a cache record) | ||
958 | * | ||
959 | * @param string $id Cache id | ||
960 | * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested | ||
961 | * @return boolean|mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record | ||
962 | */ | ||
963 | protected function _test($id, $doNotTestCacheValidity) | ||
964 | { | ||
965 | $metadatas = $this->_getMetadatas($id); | ||
966 | if (!$metadatas) { | ||
967 | return false; | ||
968 | } | ||
969 | if ($doNotTestCacheValidity || (time() <= $metadatas['expire'])) { | ||
970 | return $metadatas['mtime']; | ||
971 | } | ||
972 | return false; | ||
973 | } | ||
974 | |||
975 | /** | ||
976 | * Return the file content of the given file | ||
977 | * | ||
978 | * @param string $file File complete path | ||
979 | * @return string File content (or false if problem) | ||
980 | */ | ||
981 | protected function _fileGetContents($file) | ||
982 | { | ||
983 | $result = false; | ||
984 | if (!is_file($file)) { | ||
985 | return false; | ||
986 | } | ||
987 | $f = @fopen($file, 'rb'); | ||
988 | if ($f) { | ||
989 | if ($this->_options['file_locking']) @flock($f, LOCK_SH); | ||
990 | $result = stream_get_contents($f); | ||
991 | if ($this->_options['file_locking']) @flock($f, LOCK_UN); | ||
992 | @fclose($f); | ||
993 | } | ||
994 | return $result; | ||
995 | } | ||
996 | |||
997 | /** | ||
998 | * Put the given string into the given file | ||
999 | * | ||
1000 | * @param string $file File complete path | ||
1001 | * @param string $string String to put in file | ||
1002 | * @return boolean true if no problem | ||
1003 | */ | ||
1004 | protected function _filePutContents($file, $string) | ||
1005 | { | ||
1006 | $result = false; | ||
1007 | $f = @fopen($file, 'ab+'); | ||
1008 | if ($f) { | ||
1009 | if ($this->_options['file_locking']) @flock($f, LOCK_EX); | ||
1010 | fseek($f, 0); | ||
1011 | ftruncate($f, 0); | ||
1012 | $tmp = @fwrite($f, $string); | ||
1013 | if (!($tmp === FALSE)) { | ||
1014 | $result = true; | ||
1015 | } | ||
1016 | @fclose($f); | ||
1017 | } | ||
1018 | @chmod($file, $this->_options['cache_file_perm']); | ||
1019 | return $result; | ||
1020 | } | ||
1021 | |||
1022 | /** | ||
1023 | * Transform a file name into cache id and return it | ||
1024 | * | ||
1025 | * @param string $fileName File name | ||
1026 | * @return string Cache id | ||
1027 | */ | ||
1028 | protected function _fileNameToId($fileName) | ||
1029 | { | ||
1030 | $prefix = $this->_options['file_name_prefix']; | ||
1031 | return preg_replace('~^' . $prefix . '---(.*)$~', '$1', $fileName); | ||
1032 | } | ||
1033 | |||
1034 | } | ||
diff --git a/inc/3rdparty/libraries/Zend/Cache/Backend/Interface.php b/inc/3rdparty/libraries/Zend/Cache/Backend/Interface.php deleted file mode 100644 index 3f44e2e1..00000000 --- a/inc/3rdparty/libraries/Zend/Cache/Backend/Interface.php +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend_Cache | ||
17 | * @subpackage Zend_Cache_Backend | ||
18 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
19 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
20 | * @version $Id: Interface.php 24593 2012-01-05 20:35:02Z matthew $ | ||
21 | */ | ||
22 | |||
23 | |||
24 | /** | ||
25 | * @package Zend_Cache | ||
26 | * @subpackage Zend_Cache_Backend | ||
27 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
28 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
29 | */ | ||
30 | interface Zend_Cache_Backend_Interface | ||
31 | { | ||
32 | /** | ||
33 | * Set the frontend directives | ||
34 | * | ||
35 | * @param array $directives assoc of directives | ||
36 | */ | ||
37 | public function setDirectives($directives); | ||
38 | |||
39 | /** | ||
40 | * Test if a cache is available for the given id and (if yes) return it (false else) | ||
41 | * | ||
42 | * Note : return value is always "string" (unserialization is done by the core not by the backend) | ||
43 | * | ||
44 | * @param string $id Cache id | ||
45 | * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested | ||
46 | * @return string|false cached datas | ||
47 | */ | ||
48 | public function load($id, $doNotTestCacheValidity = false); | ||
49 | |||
50 | /** | ||
51 | * Test if a cache is available or not (for the given id) | ||
52 | * | ||
53 | * @param string $id cache id | ||
54 | * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record | ||
55 | */ | ||
56 | public function test($id); | ||
57 | |||
58 | /** | ||
59 | * Save some string datas into a cache record | ||
60 | * | ||
61 | * Note : $data is always "string" (serialization is done by the | ||
62 | * core not by the backend) | ||
63 | * | ||
64 | * @param string $data Datas to cache | ||
65 | * @param string $id Cache id | ||
66 | * @param array $tags Array of strings, the cache record will be tagged by each string entry | ||
67 | * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) | ||
68 | * @return boolean true if no problem | ||
69 | */ | ||
70 | public function save($data, $id, $tags = array(), $specificLifetime = false); | ||
71 | |||
72 | /** | ||
73 | * Remove a cache record | ||
74 | * | ||
75 | * @param string $id Cache id | ||
76 | * @return boolean True if no problem | ||
77 | */ | ||
78 | public function remove($id); | ||
79 | |||
80 | /** | ||
81 | * Clean some cache records | ||
82 | * | ||
83 | * Available modes are : | ||
84 | * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) | ||
85 | * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) | ||
86 | * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags | ||
87 | * ($tags can be an array of strings or a single string) | ||
88 | * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} | ||
89 | * ($tags can be an array of strings or a single string) | ||
90 | * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags | ||
91 | * ($tags can be an array of strings or a single string) | ||
92 | * | ||
93 | * @param string $mode Clean mode | ||
94 | * @param array $tags Array of tags | ||
95 | * @return boolean true if no problem | ||
96 | */ | ||
97 | public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()); | ||
98 | |||
99 | } | ||
diff --git a/inc/3rdparty/libraries/Zend/Cache/Core.php b/inc/3rdparty/libraries/Zend/Cache/Core.php deleted file mode 100644 index e3588636..00000000 --- a/inc/3rdparty/libraries/Zend/Cache/Core.php +++ /dev/null | |||
@@ -1,765 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend_Cache | ||
17 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
18 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
19 | * @version $Id: Core.php 24989 2012-06-21 07:24:13Z mabe $ | ||
20 | */ | ||
21 | |||
22 | |||
23 | /** | ||
24 | * @package Zend_Cache | ||
25 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
26 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
27 | */ | ||
28 | class Zend_Cache_Core | ||
29 | { | ||
30 | /** | ||
31 | * Messages | ||
32 | */ | ||
33 | const BACKEND_NOT_SUPPORTS_TAG = 'tags are not supported by the current backend'; | ||
34 | const BACKEND_NOT_IMPLEMENTS_EXTENDED_IF = 'Current backend doesn\'t implement the Zend_Cache_Backend_ExtendedInterface, so this method is not available'; | ||
35 | |||
36 | /** | ||
37 | * Backend Object | ||
38 | * | ||
39 | * @var Zend_Cache_Backend_Interface $_backend | ||
40 | */ | ||
41 | protected $_backend = null; | ||
42 | |||
43 | /** | ||
44 | * Available options | ||
45 | * | ||
46 | * ====> (boolean) write_control : | ||
47 | * - Enable / disable write control (the cache is read just after writing to detect corrupt entries) | ||
48 | * - Enable write control will lightly slow the cache writing but not the cache reading | ||
49 | * Write control can detect some corrupt cache files but maybe it's not a perfect control | ||
50 | * | ||
51 | * ====> (boolean) caching : | ||
52 | * - Enable / disable caching | ||
53 | * (can be very useful for the debug of cached scripts) | ||
54 | * | ||
55 | * =====> (string) cache_id_prefix : | ||
56 | * - prefix for cache ids (namespace) | ||
57 | * | ||
58 | * ====> (boolean) automatic_serialization : | ||
59 | * - Enable / disable automatic serialization | ||
60 | * - It can be used to save directly datas which aren't strings (but it's slower) | ||
61 | * | ||
62 | * ====> (int) automatic_cleaning_factor : | ||
63 | * - Disable / Tune the automatic cleaning process | ||
64 | * - The automatic cleaning process destroy too old (for the given life time) | ||
65 | * cache files when a new cache file is written : | ||
66 | * 0 => no automatic cache cleaning | ||
67 | * 1 => systematic cache cleaning | ||
68 | * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write | ||
69 | * | ||
70 | * ====> (int) lifetime : | ||
71 | * - Cache lifetime (in seconds) | ||
72 | * - If null, the cache is valid forever. | ||
73 | * | ||
74 | * ====> (boolean) logging : | ||
75 | * - If set to true, logging is activated (but the system is slower) | ||
76 | * | ||
77 | * ====> (boolean) ignore_user_abort | ||
78 | * - If set to true, the core will set the ignore_user_abort PHP flag inside the | ||
79 | * save() method to avoid cache corruptions in some cases (default false) | ||
80 | * | ||
81 | * @var array $_options available options | ||
82 | */ | ||
83 | protected $_options = array( | ||
84 | 'write_control' => true, | ||
85 | 'caching' => true, | ||
86 | 'cache_id_prefix' => null, | ||
87 | 'automatic_serialization' => false, | ||
88 | 'automatic_cleaning_factor' => 10, | ||
89 | 'lifetime' => 3600, | ||
90 | 'logging' => false, | ||
91 | 'logger' => null, | ||
92 | 'ignore_user_abort' => false | ||
93 | ); | ||
94 | |||
95 | /** | ||
96 | * Array of options which have to be transfered to backend | ||
97 | * | ||
98 | * @var array $_directivesList | ||
99 | */ | ||
100 | protected static $_directivesList = array('lifetime', 'logging', 'logger'); | ||
101 | |||
102 | /** | ||
103 | * Not used for the core, just a sort a hint to get a common setOption() method (for the core and for frontends) | ||
104 | * | ||
105 | * @var array $_specificOptions | ||
106 | */ | ||
107 | protected $_specificOptions = array(); | ||
108 | |||
109 | /** | ||
110 | * Last used cache id | ||
111 | * | ||
112 | * @var string $_lastId | ||
113 | */ | ||
114 | private $_lastId = null; | ||
115 | |||
116 | /** | ||
117 | * True if the backend implements Zend_Cache_Backend_ExtendedInterface | ||
118 | * | ||
119 | * @var boolean $_extendedBackend | ||
120 | */ | ||
121 | protected $_extendedBackend = false; | ||
122 | |||
123 | /** | ||
124 | * Array of capabilities of the backend (only if it implements Zend_Cache_Backend_ExtendedInterface) | ||
125 | * | ||
126 | * @var array | ||
127 | */ | ||
128 | protected $_backendCapabilities = array(); | ||
129 | |||
130 | /** | ||
131 | * Constructor | ||
132 | * | ||
133 | * @param array|Zend_Config $options Associative array of options or Zend_Config instance | ||
134 | * @throws Zend_Cache_Exception | ||
135 | * @return void | ||
136 | */ | ||
137 | public function __construct($options = array()) | ||
138 | { | ||
139 | if ($options instanceof Zend_Config) { | ||
140 | $options = $options->toArray(); | ||
141 | } | ||
142 | if (!is_array($options)) { | ||
143 | Zend_Cache::throwException("Options passed were not an array" | ||
144 | . " or Zend_Config instance."); | ||
145 | } | ||
146 | while (list($name, $value) = each($options)) { | ||
147 | $this->setOption($name, $value); | ||
148 | } | ||
149 | $this->_loggerSanity(); | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * Set options using an instance of type Zend_Config | ||
154 | * | ||
155 | * @param Zend_Config $config | ||
156 | * @return Zend_Cache_Core | ||
157 | */ | ||
158 | public function setConfig(Zend_Config $config) | ||
159 | { | ||
160 | $options = $config->toArray(); | ||
161 | while (list($name, $value) = each($options)) { | ||
162 | $this->setOption($name, $value); | ||
163 | } | ||
164 | return $this; | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Set the backend | ||
169 | * | ||
170 | * @param Zend_Cache_Backend $backendObject | ||
171 | * @throws Zend_Cache_Exception | ||
172 | * @return void | ||
173 | */ | ||
174 | public function setBackend(Zend_Cache_Backend $backendObject) | ||
175 | { | ||
176 | $this->_backend= $backendObject; | ||
177 | // some options (listed in $_directivesList) have to be given | ||
178 | // to the backend too (even if they are not "backend specific") | ||
179 | $directives = array(); | ||
180 | foreach (Zend_Cache_Core::$_directivesList as $directive) { | ||
181 | $directives[$directive] = $this->_options[$directive]; | ||
182 | } | ||
183 | $this->_backend->setDirectives($directives); | ||
184 | if (in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_backend))) { | ||
185 | $this->_extendedBackend = true; | ||
186 | $this->_backendCapabilities = $this->_backend->getCapabilities(); | ||
187 | } | ||
188 | |||
189 | } | ||
190 | |||
191 | /** | ||
192 | * Returns the backend | ||
193 | * | ||
194 | * @return Zend_Cache_Backend backend object | ||
195 | */ | ||
196 | public function getBackend() | ||
197 | { | ||
198 | return $this->_backend; | ||
199 | } | ||
200 | |||
201 | /** | ||
202 | * Public frontend to set an option | ||
203 | * | ||
204 | * There is an additional validation (relatively to the protected _setOption method) | ||
205 | * | ||
206 | * @param string $name Name of the option | ||
207 | * @param mixed $value Value of the option | ||
208 | * @throws Zend_Cache_Exception | ||
209 | * @return void | ||
210 | */ | ||
211 | public function setOption($name, $value) | ||
212 | { | ||
213 | if (!is_string($name)) { | ||
214 | Zend_Cache::throwException("Incorrect option name!"); | ||
215 | } | ||
216 | $name = strtolower($name); | ||
217 | if (array_key_exists($name, $this->_options)) { | ||
218 | // This is a Core option | ||
219 | $this->_setOption($name, $value); | ||
220 | return; | ||
221 | } | ||
222 | if (array_key_exists($name, $this->_specificOptions)) { | ||
223 | // This a specic option of this frontend | ||
224 | $this->_specificOptions[$name] = $value; | ||
225 | return; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * Public frontend to get an option value | ||
231 | * | ||
232 | * @param string $name Name of the option | ||
233 | * @throws Zend_Cache_Exception | ||
234 | * @return mixed option value | ||
235 | */ | ||
236 | public function getOption($name) | ||
237 | { | ||
238 | $name = strtolower($name); | ||
239 | |||
240 | if (array_key_exists($name, $this->_options)) { | ||
241 | // This is a Core option | ||
242 | return $this->_options[$name]; | ||
243 | } | ||
244 | |||
245 | if (array_key_exists($name, $this->_specificOptions)) { | ||
246 | // This a specic option of this frontend | ||
247 | return $this->_specificOptions[$name]; | ||
248 | } | ||
249 | |||
250 | Zend_Cache::throwException("Incorrect option name : $name"); | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * Set an option | ||
255 | * | ||
256 | * @param string $name Name of the option | ||
257 | * @param mixed $value Value of the option | ||
258 | * @throws Zend_Cache_Exception | ||
259 | * @return void | ||
260 | */ | ||
261 | private function _setOption($name, $value) | ||
262 | { | ||
263 | if (!is_string($name) || !array_key_exists($name, $this->_options)) { | ||
264 | Zend_Cache::throwException("Incorrect option name : $name"); | ||
265 | } | ||
266 | if ($name == 'lifetime' && empty($value)) { | ||
267 | $value = null; | ||
268 | } | ||
269 | $this->_options[$name] = $value; | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Force a new lifetime | ||
274 | * | ||
275 | * The new value is set for the core/frontend but for the backend too (directive) | ||
276 | * | ||
277 | * @param int $newLifetime New lifetime (in seconds) | ||
278 | * @return void | ||
279 | */ | ||
280 | public function setLifetime($newLifetime) | ||
281 | { | ||
282 | $this->_options['lifetime'] = $newLifetime; | ||
283 | $this->_backend->setDirectives(array( | ||
284 | 'lifetime' => $newLifetime | ||
285 | )); | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * Test if a cache is available for the given id and (if yes) return it (false else) | ||
290 | * | ||
291 | * @param string $id Cache id | ||
292 | * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested | ||
293 | * @param boolean $doNotUnserialize Do not serialize (even if automatic_serialization is true) => for internal use | ||
294 | * @return mixed|false Cached datas | ||
295 | */ | ||
296 | public function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false) | ||
297 | { | ||
298 | if (!$this->_options['caching']) { | ||
299 | return false; | ||
300 | } | ||
301 | $id = $this->_id($id); // cache id may need prefix | ||
302 | $this->_lastId = $id; | ||
303 | self::_validateIdOrTag($id); | ||
304 | |||
305 | $this->_log("Zend_Cache_Core: load item '{$id}'", 7); | ||
306 | $data = $this->_backend->load($id, $doNotTestCacheValidity); | ||
307 | if ($data===false) { | ||
308 | // no cache available | ||
309 | return false; | ||
310 | } | ||
311 | if ((!$doNotUnserialize) && $this->_options['automatic_serialization']) { | ||
312 | // we need to unserialize before sending the result | ||
313 | return unserialize($data); | ||
314 | } | ||
315 | return $data; | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Test if a cache is available for the given id | ||
320 | * | ||
321 | * @param string $id Cache id | ||
322 | * @return int|false Last modified time of cache entry if it is available, false otherwise | ||
323 | */ | ||
324 | public function test($id) | ||
325 | { | ||
326 | if (!$this->_options['caching']) { | ||
327 | return false; | ||
328 | } | ||
329 | $id = $this->_id($id); // cache id may need prefix | ||
330 | self::_validateIdOrTag($id); | ||
331 | $this->_lastId = $id; | ||
332 | |||
333 | $this->_log("Zend_Cache_Core: test item '{$id}'", 7); | ||
334 | return $this->_backend->test($id); | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * Save some data in a cache | ||
339 | * | ||
340 | * @param mixed $data Data to put in cache (can be another type than string if automatic_serialization is on) | ||
341 | * @param string $id Cache id (if not set, the last cache id will be used) | ||
342 | * @param array $tags Cache tags | ||
343 | * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) | ||
344 | * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends | ||
345 | * @throws Zend_Cache_Exception | ||
346 | * @return boolean True if no problem | ||
347 | */ | ||
348 | public function save($data, $id = null, $tags = array(), $specificLifetime = false, $priority = 8) | ||
349 | { | ||
350 | if (!$this->_options['caching']) { | ||
351 | return true; | ||
352 | } | ||
353 | if ($id === null) { | ||
354 | $id = $this->_lastId; | ||
355 | } else { | ||
356 | $id = $this->_id($id); | ||
357 | } | ||
358 | self::_validateIdOrTag($id); | ||
359 | self::_validateTagsArray($tags); | ||
360 | if ($this->_options['automatic_serialization']) { | ||
361 | // we need to serialize datas before storing them | ||
362 | $data = serialize($data); | ||
363 | } else { | ||
364 | if (!is_string($data)) { | ||
365 | Zend_Cache::throwException("Datas must be string or set automatic_serialization = true"); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | // automatic cleaning | ||
370 | if ($this->_options['automatic_cleaning_factor'] > 0) { | ||
371 | $rand = rand(1, $this->_options['automatic_cleaning_factor']); | ||
372 | if ($rand==1) { | ||
373 | // new way || deprecated way | ||
374 | if ($this->_extendedBackend || method_exists($this->_backend, 'isAutomaticCleaningAvailable')) { | ||
375 | $this->_log("Zend_Cache_Core::save(): automatic cleaning running", 7); | ||
376 | $this->clean(Zend_Cache::CLEANING_MODE_OLD); | ||
377 | } else { | ||
378 | $this->_log("Zend_Cache_Core::save(): automatic cleaning is not available/necessary with current backend", 4); | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | |||
383 | $this->_log("Zend_Cache_Core: save item '{$id}'", 7); | ||
384 | if ($this->_options['ignore_user_abort']) { | ||
385 | $abort = ignore_user_abort(true); | ||
386 | } | ||
387 | if (($this->_extendedBackend) && ($this->_backendCapabilities['priority'])) { | ||
388 | $result = $this->_backend->save($data, $id, $tags, $specificLifetime, $priority); | ||
389 | } else { | ||
390 | $result = $this->_backend->save($data, $id, $tags, $specificLifetime); | ||
391 | } | ||
392 | if ($this->_options['ignore_user_abort']) { | ||
393 | ignore_user_abort($abort); | ||
394 | } | ||
395 | |||
396 | if (!$result) { | ||
397 | // maybe the cache is corrupted, so we remove it ! | ||
398 | $this->_log("Zend_Cache_Core::save(): failed to save item '{$id}' -> removing it", 4); | ||
399 | $this->_backend->remove($id); | ||
400 | return false; | ||
401 | } | ||
402 | |||
403 | if ($this->_options['write_control']) { | ||
404 | $data2 = $this->_backend->load($id, true); | ||
405 | if ($data!=$data2) { | ||
406 | $this->_log("Zend_Cache_Core::save(): write control of item '{$id}' failed -> removing it", 4); | ||
407 | $this->_backend->remove($id); | ||
408 | return false; | ||
409 | } | ||
410 | } | ||
411 | |||
412 | return true; | ||
413 | } | ||
414 | |||
415 | /** | ||
416 | * Remove a cache | ||
417 | * | ||
418 | * @param string $id Cache id to remove | ||
419 | * @return boolean True if ok | ||
420 | */ | ||
421 | public function remove($id) | ||
422 | { | ||
423 | if (!$this->_options['caching']) { | ||
424 | return true; | ||
425 | } | ||
426 | $id = $this->_id($id); // cache id may need prefix | ||
427 | self::_validateIdOrTag($id); | ||
428 | |||
429 | $this->_log("Zend_Cache_Core: remove item '{$id}'", 7); | ||
430 | return $this->_backend->remove($id); | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * Clean cache entries | ||
435 | * | ||
436 | * Available modes are : | ||
437 | * 'all' (default) => remove all cache entries ($tags is not used) | ||
438 | * 'old' => remove too old cache entries ($tags is not used) | ||
439 | * 'matchingTag' => remove cache entries matching all given tags | ||
440 | * ($tags can be an array of strings or a single string) | ||
441 | * 'notMatchingTag' => remove cache entries not matching one of the given tags | ||
442 | * ($tags can be an array of strings or a single string) | ||
443 | * 'matchingAnyTag' => remove cache entries matching any given tags | ||
444 | * ($tags can be an array of strings or a single string) | ||
445 | * | ||
446 | * @param string $mode | ||
447 | * @param array|string $tags | ||
448 | * @throws Zend_Cache_Exception | ||
449 | * @return boolean True if ok | ||
450 | */ | ||
451 | public function clean($mode = 'all', $tags = array()) | ||
452 | { | ||
453 | if (!$this->_options['caching']) { | ||
454 | return true; | ||
455 | } | ||
456 | if (!in_array($mode, array(Zend_Cache::CLEANING_MODE_ALL, | ||
457 | Zend_Cache::CLEANING_MODE_OLD, | ||
458 | Zend_Cache::CLEANING_MODE_MATCHING_TAG, | ||
459 | Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG, | ||
460 | Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG))) { | ||
461 | Zend_Cache::throwException('Invalid cleaning mode'); | ||
462 | } | ||
463 | self::_validateTagsArray($tags); | ||
464 | |||
465 | return $this->_backend->clean($mode, $tags); | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * Return an array of stored cache ids which match given tags | ||
470 | * | ||
471 | * In case of multiple tags, a logical AND is made between tags | ||
472 | * | ||
473 | * @param array $tags array of tags | ||
474 | * @return array array of matching cache ids (string) | ||
475 | */ | ||
476 | public function getIdsMatchingTags($tags = array()) | ||
477 | { | ||
478 | if (!$this->_extendedBackend) { | ||
479 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
480 | } | ||
481 | if (!($this->_backendCapabilities['tags'])) { | ||
482 | Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); | ||
483 | } | ||
484 | |||
485 | $ids = $this->_backend->getIdsMatchingTags($tags); | ||
486 | |||
487 | // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) | ||
488 | if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { | ||
489 | $prefix = & $this->_options['cache_id_prefix']; | ||
490 | $prefixLen = strlen($prefix); | ||
491 | foreach ($ids as &$id) { | ||
492 | if (strpos($id, $prefix) === 0) { | ||
493 | $id = substr($id, $prefixLen); | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | |||
498 | return $ids; | ||
499 | } | ||
500 | |||
501 | /** | ||
502 | * Return an array of stored cache ids which don't match given tags | ||
503 | * | ||
504 | * In case of multiple tags, a logical OR is made between tags | ||
505 | * | ||
506 | * @param array $tags array of tags | ||
507 | * @return array array of not matching cache ids (string) | ||
508 | */ | ||
509 | public function getIdsNotMatchingTags($tags = array()) | ||
510 | { | ||
511 | if (!$this->_extendedBackend) { | ||
512 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
513 | } | ||
514 | if (!($this->_backendCapabilities['tags'])) { | ||
515 | Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); | ||
516 | } | ||
517 | |||
518 | $ids = $this->_backend->getIdsNotMatchingTags($tags); | ||
519 | |||
520 | // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) | ||
521 | if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { | ||
522 | $prefix = & $this->_options['cache_id_prefix']; | ||
523 | $prefixLen = strlen($prefix); | ||
524 | foreach ($ids as &$id) { | ||
525 | if (strpos($id, $prefix) === 0) { | ||
526 | $id = substr($id, $prefixLen); | ||
527 | } | ||
528 | } | ||
529 | } | ||
530 | |||
531 | return $ids; | ||
532 | } | ||
533 | |||
534 | /** | ||
535 | * Return an array of stored cache ids which match any given tags | ||
536 | * | ||
537 | * In case of multiple tags, a logical OR is made between tags | ||
538 | * | ||
539 | * @param array $tags array of tags | ||
540 | * @return array array of matching any cache ids (string) | ||
541 | */ | ||
542 | public function getIdsMatchingAnyTags($tags = array()) | ||
543 | { | ||
544 | if (!$this->_extendedBackend) { | ||
545 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
546 | } | ||
547 | if (!($this->_backendCapabilities['tags'])) { | ||
548 | Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); | ||
549 | } | ||
550 | |||
551 | $ids = $this->_backend->getIdsMatchingAnyTags($tags); | ||
552 | |||
553 | // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) | ||
554 | if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { | ||
555 | $prefix = & $this->_options['cache_id_prefix']; | ||
556 | $prefixLen = strlen($prefix); | ||
557 | foreach ($ids as &$id) { | ||
558 | if (strpos($id, $prefix) === 0) { | ||
559 | $id = substr($id, $prefixLen); | ||
560 | } | ||
561 | } | ||
562 | } | ||
563 | |||
564 | return $ids; | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * Return an array of stored cache ids | ||
569 | * | ||
570 | * @return array array of stored cache ids (string) | ||
571 | */ | ||
572 | public function getIds() | ||
573 | { | ||
574 | if (!$this->_extendedBackend) { | ||
575 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
576 | } | ||
577 | |||
578 | $ids = $this->_backend->getIds(); | ||
579 | |||
580 | // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) | ||
581 | if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { | ||
582 | $prefix = & $this->_options['cache_id_prefix']; | ||
583 | $prefixLen = strlen($prefix); | ||
584 | foreach ($ids as &$id) { | ||
585 | if (strpos($id, $prefix) === 0) { | ||
586 | $id = substr($id, $prefixLen); | ||
587 | } | ||
588 | } | ||
589 | } | ||
590 | |||
591 | return $ids; | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * Return an array of stored tags | ||
596 | * | ||
597 | * @return array array of stored tags (string) | ||
598 | */ | ||
599 | public function getTags() | ||
600 | { | ||
601 | if (!$this->_extendedBackend) { | ||
602 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
603 | } | ||
604 | if (!($this->_backendCapabilities['tags'])) { | ||
605 | Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG); | ||
606 | } | ||
607 | return $this->_backend->getTags(); | ||
608 | } | ||
609 | |||
610 | /** | ||
611 | * Return the filling percentage of the backend storage | ||
612 | * | ||
613 | * @return int integer between 0 and 100 | ||
614 | */ | ||
615 | public function getFillingPercentage() | ||
616 | { | ||
617 | if (!$this->_extendedBackend) { | ||
618 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
619 | } | ||
620 | return $this->_backend->getFillingPercentage(); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * Return an array of metadatas for the given cache id | ||
625 | * | ||
626 | * The array will include these keys : | ||
627 | * - expire : the expire timestamp | ||
628 | * - tags : a string array of tags | ||
629 | * - mtime : timestamp of last modification time | ||
630 | * | ||
631 | * @param string $id cache id | ||
632 | * @return array array of metadatas (false if the cache id is not found) | ||
633 | */ | ||
634 | public function getMetadatas($id) | ||
635 | { | ||
636 | if (!$this->_extendedBackend) { | ||
637 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
638 | } | ||
639 | $id = $this->_id($id); // cache id may need prefix | ||
640 | return $this->_backend->getMetadatas($id); | ||
641 | } | ||
642 | |||
643 | /** | ||
644 | * Give (if possible) an extra lifetime to the given cache id | ||
645 | * | ||
646 | * @param string $id cache id | ||
647 | * @param int $extraLifetime | ||
648 | * @return boolean true if ok | ||
649 | */ | ||
650 | public function touch($id, $extraLifetime) | ||
651 | { | ||
652 | if (!$this->_extendedBackend) { | ||
653 | Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); | ||
654 | } | ||
655 | $id = $this->_id($id); // cache id may need prefix | ||
656 | |||
657 | $this->_log("Zend_Cache_Core: touch item '{$id}'", 7); | ||
658 | return $this->_backend->touch($id, $extraLifetime); | ||
659 | } | ||
660 | |||
661 | /** | ||
662 | * Validate a cache id or a tag (security, reliable filenames, reserved prefixes...) | ||
663 | * | ||
664 | * Throw an exception if a problem is found | ||
665 | * | ||
666 | * @param string $string Cache id or tag | ||
667 | * @throws Zend_Cache_Exception | ||
668 | * @return void | ||
669 | */ | ||
670 | protected static function _validateIdOrTag($string) | ||
671 | { | ||
672 | if (!is_string($string)) { | ||
673 | Zend_Cache::throwException('Invalid id or tag : must be a string'); | ||
674 | } | ||
675 | if (substr($string, 0, 9) == 'internal-') { | ||
676 | Zend_Cache::throwException('"internal-*" ids or tags are reserved'); | ||
677 | } | ||
678 | if (!preg_match('~^[a-zA-Z0-9_]+$~D', $string)) { | ||
679 | Zend_Cache::throwException("Invalid id or tag '$string' : must use only [a-zA-Z0-9_]"); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | /** | ||
684 | * Validate a tags array (security, reliable filenames, reserved prefixes...) | ||
685 | * | ||
686 | * Throw an exception if a problem is found | ||
687 | * | ||
688 | * @param array $tags Array of tags | ||
689 | * @throws Zend_Cache_Exception | ||
690 | * @return void | ||
691 | */ | ||
692 | protected static function _validateTagsArray($tags) | ||
693 | { | ||
694 | if (!is_array($tags)) { | ||
695 | Zend_Cache::throwException('Invalid tags array : must be an array'); | ||
696 | } | ||
697 | foreach($tags as $tag) { | ||
698 | self::_validateIdOrTag($tag); | ||
699 | } | ||
700 | reset($tags); | ||
701 | } | ||
702 | |||
703 | /** | ||
704 | * Make sure if we enable logging that the Zend_Log class | ||
705 | * is available. | ||
706 | * Create a default log object if none is set. | ||
707 | * | ||
708 | * @throws Zend_Cache_Exception | ||
709 | * @return void | ||
710 | */ | ||
711 | protected function _loggerSanity() | ||
712 | { | ||
713 | if (!isset($this->_options['logging']) || !$this->_options['logging']) { | ||
714 | return; | ||
715 | } | ||
716 | |||
717 | if (isset($this->_options['logger']) && $this->_options['logger'] instanceof Zend_Log) { | ||
718 | return; | ||
719 | } | ||
720 | |||
721 | // Create a default logger to the standard output stream | ||
722 | require_once 'Zend/Log.php'; | ||
723 | require_once 'Zend/Log/Writer/Stream.php'; | ||
724 | require_once 'Zend/Log/Filter/Priority.php'; | ||
725 | $logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output')); | ||
726 | $logger->addFilter(new Zend_Log_Filter_Priority(Zend_Log::WARN, '<=')); | ||
727 | $this->_options['logger'] = $logger; | ||
728 | } | ||
729 | |||
730 | /** | ||
731 | * Log a message at the WARN (4) priority. | ||
732 | * | ||
733 | * @param string $message | ||
734 | * @throws Zend_Cache_Exception | ||
735 | * @return void | ||
736 | */ | ||
737 | protected function _log($message, $priority = 4) | ||
738 | { | ||
739 | if (!$this->_options['logging']) { | ||
740 | return; | ||
741 | } | ||
742 | if (!(isset($this->_options['logger']) || $this->_options['logger'] instanceof Zend_Log)) { | ||
743 | Zend_Cache::throwException('Logging is enabled but logger is not set'); | ||
744 | } | ||
745 | $logger = $this->_options['logger']; | ||
746 | $logger->log($message, $priority); | ||
747 | } | ||
748 | |||
749 | /** | ||
750 | * Make and return a cache id | ||
751 | * | ||
752 | * Checks 'cache_id_prefix' and returns new id with prefix or simply the id if null | ||
753 | * | ||
754 | * @param string $id Cache id | ||
755 | * @return string Cache id (with or without prefix) | ||
756 | */ | ||
757 | protected function _id($id) | ||
758 | { | ||
759 | if (($id !== null) && isset($this->_options['cache_id_prefix'])) { | ||
760 | return $this->_options['cache_id_prefix'] . $id; // return with prefix | ||
761 | } | ||
762 | return $id; // no prefix, just return the $id passed | ||
763 | } | ||
764 | |||
765 | } | ||
diff --git a/inc/3rdparty/libraries/Zend/Cache/Exception.php b/inc/3rdparty/libraries/Zend/Cache/Exception.php deleted file mode 100644 index 44884515..00000000 --- a/inc/3rdparty/libraries/Zend/Cache/Exception.php +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend_Cache | ||
17 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
18 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
19 | * @version $Id: Exception.php 24593 2012-01-05 20:35:02Z matthew $ | ||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * @see Zend_Exception | ||
24 | */ | ||
25 | require_once 'Zend/Exception.php'; | ||
26 | |||
27 | /** | ||
28 | * @package Zend_Cache | ||
29 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
30 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
31 | */ | ||
32 | class Zend_Cache_Exception extends Zend_Exception {} | ||
diff --git a/inc/3rdparty/libraries/Zend/Exception.php b/inc/3rdparty/libraries/Zend/Exception.php deleted file mode 100644 index 92b2e460..00000000 --- a/inc/3rdparty/libraries/Zend/Exception.php +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Zend Framework | ||
4 | * | ||
5 | * LICENSE | ||
6 | * | ||
7 | * This source file is subject to the new BSD license that is bundled | ||
8 | * with this package in the file LICENSE.txt. | ||
9 | * It is also available through the world-wide-web at this URL: | ||
10 | * http://framework.zend.com/license/new-bsd | ||
11 | * If you did not receive a copy of the license and are unable to | ||
12 | * obtain it through the world-wide-web, please send an email | ||
13 | * to license@zend.com so we can send you a copy immediately. | ||
14 | * | ||
15 | * @category Zend | ||
16 | * @package Zend | ||
17 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
18 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
19 | * @version $Id: Exception.php 24593 2012-01-05 20:35:02Z matthew $ | ||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * @category Zend | ||
24 | * @package Zend | ||
25 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | ||
26 | * @license http://framework.zend.com/license/new-bsd New BSD License | ||
27 | */ | ||
28 | class Zend_Exception extends Exception | ||
29 | { | ||
30 | /** | ||
31 | * @var null|Exception | ||
32 | */ | ||
33 | private $_previous = null; | ||
34 | |||
35 | /** | ||
36 | * Construct the exception | ||
37 | * | ||
38 | * @param string $msg | ||
39 | * @param int $code | ||
40 | * @param Exception $previous | ||
41 | * @return void | ||
42 | */ | ||
43 | public function __construct($msg = '', $code = 0, Exception $previous = null) | ||
44 | { | ||
45 | if (version_compare(PHP_VERSION, '5.3.0', '<')) { | ||
46 | parent::__construct($msg, (int) $code); | ||
47 | $this->_previous = $previous; | ||
48 | } else { | ||
49 | parent::__construct($msg, (int) $code, $previous); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Overloading | ||
55 | * | ||
56 | * For PHP < 5.3.0, provides access to the getPrevious() method. | ||
57 | * | ||
58 | * @param string $method | ||
59 | * @param array $args | ||
60 | * @return mixed | ||
61 | */ | ||
62 | public function __call($method, array $args) | ||
63 | { | ||
64 | if ('getprevious' == strtolower($method)) { | ||
65 | return $this->_getPrevious(); | ||
66 | } | ||
67 | return null; | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * String representation of the exception | ||
72 | * | ||
73 | * @return string | ||
74 | */ | ||
75 | public function __toString() | ||
76 | { | ||
77 | if (version_compare(PHP_VERSION, '5.3.0', '<')) { | ||
78 | if (null !== ($e = $this->getPrevious())) { | ||
79 | return $e->__toString() | ||
80 | . "\n\nNext " | ||
81 | . parent::__toString(); | ||
82 | } | ||
83 | } | ||
84 | return parent::__toString(); | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * Returns previous Exception | ||
89 | * | ||
90 | * @return Exception|null | ||
91 | */ | ||
92 | protected function _getPrevious() | ||
93 | { | ||
94 | return $this->_previous; | ||
95 | } | ||
96 | } | ||
diff --git a/inc/3rdparty/libraries/content-extractor/ContentExtractor.php b/inc/3rdparty/libraries/content-extractor/ContentExtractor.php deleted file mode 100644 index 21e693e7..00000000 --- a/inc/3rdparty/libraries/content-extractor/ContentExtractor.php +++ /dev/null | |||
@@ -1,727 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Content Extractor | ||
4 | * | ||
5 | * Uses patterns specified in site config files and auto detection (hNews/PHP Readability) | ||
6 | * to extract content from HTML files. | ||
7 | * | ||
8 | * @version 1.0 | ||
9 | * @date 2013-02-05 | ||
10 | * @author Keyvan Minoukadeh | ||
11 | * @copyright 2013 Keyvan Minoukadeh | ||
12 | * @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3 | ||
13 | */ | ||
14 | |||
15 | class ContentExtractor | ||
16 | { | ||
17 | protected static $tidy_config = array( | ||
18 | 'clean' => true, | ||
19 | 'output-xhtml' => true, | ||
20 | 'logical-emphasis' => true, | ||
21 | 'show-body-only' => false, | ||
22 | 'new-blocklevel-tags' => 'article, aside, footer, header, hgroup, menu, nav, section, details, datagrid', | ||
23 | 'new-inline-tags' => 'mark, time, meter, progress, data', | ||
24 | 'wrap' => 0, | ||
25 | 'drop-empty-paras' => true, | ||
26 | 'drop-proprietary-attributes' => false, | ||
27 | 'enclose-text' => true, | ||
28 | 'enclose-block-text' => true, | ||
29 | 'merge-divs' => true, | ||
30 | 'merge-spans' => true, | ||
31 | 'char-encoding' => 'utf8', | ||
32 | 'hide-comments' => true | ||
33 | ); | ||
34 | protected $html; | ||
35 | protected $config; | ||
36 | protected $title; | ||
37 | protected $author = array(); | ||
38 | protected $language; | ||
39 | protected $date; | ||
40 | protected $body; | ||
41 | protected $success = false; | ||
42 | protected $nextPageUrl; | ||
43 | public $allowedParsers = array('libxml', 'html5lib'); | ||
44 | public $fingerprints = array(); | ||
45 | public $readability; | ||
46 | public $debug = false; | ||
47 | public $debugVerbose = false; | ||
48 | |||
49 | function __construct($path, $fallback=null) { | ||
50 | SiteConfig::set_config_path($path, $fallback); | ||
51 | } | ||
52 | |||
53 | protected function debug($msg) { | ||
54 | if ($this->debug) { | ||
55 | $mem = round(memory_get_usage()/1024, 2); | ||
56 | $memPeak = round(memory_get_peak_usage()/1024, 2); | ||
57 | echo '* ',$msg; | ||
58 | if ($this->debugVerbose) echo ' - mem used: ',$mem," (peak: $memPeak)"; | ||
59 | echo "\n"; | ||
60 | ob_flush(); | ||
61 | flush(); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | public function reset() { | ||
66 | $this->html = null; | ||
67 | $this->readability = null; | ||
68 | $this->config = null; | ||
69 | $this->title = null; | ||
70 | $this->body = null; | ||
71 | $this->author = array(); | ||
72 | $this->language = null; | ||
73 | $this->date = null; | ||
74 | $this->nextPageUrl = null; | ||
75 | $this->success = false; | ||
76 | } | ||
77 | |||
78 | public function findHostUsingFingerprints($html) { | ||
79 | $this->debug('Checking fingerprints...'); | ||
80 | $head = substr($html, 0, 8000); | ||
81 | foreach ($this->fingerprints as $_fp => $_fphost) { | ||
82 | $lookin = 'html'; | ||
83 | if (is_array($_fphost)) { | ||
84 | if (isset($_fphost['head']) && $_fphost['head']) { | ||
85 | $lookin = 'head'; | ||
86 | } | ||
87 | $_fphost = $_fphost['hostname']; | ||
88 | } | ||
89 | if (strpos($$lookin, $_fp) !== false) { | ||
90 | $this->debug("Found match: $_fphost"); | ||
91 | return $_fphost; | ||
92 | } | ||
93 | } | ||
94 | $this->debug('No fingerprint matches'); | ||
95 | return false; | ||
96 | } | ||
97 | |||
98 | // returns SiteConfig instance (joined in order: exact match, wildcard, fingerprint, global, default) | ||
99 | public function buildSiteConfig($url, $html='', $add_to_cache=true) { | ||
100 | // extract host name | ||
101 | $host = @parse_url($url, PHP_URL_HOST); | ||
102 | $host = strtolower($host); | ||
103 | if (substr($host, 0, 4) == 'www.') $host = substr($host, 4); | ||
104 | // is merged version already cached? | ||
105 | if (SiteConfig::is_cached("$host.merged")) { | ||
106 | $this->debug("Returning cached and merged site config for $host"); | ||
107 | return SiteConfig::build("$host.merged"); | ||
108 | } | ||
109 | // let's build from site_config/custom/ and standard/ | ||
110 | $config = SiteConfig::build($host); | ||
111 | if ($add_to_cache && $config && !SiteConfig::is_cached("$host")) { | ||
112 | SiteConfig::add_to_cache($host, $config); | ||
113 | } | ||
114 | // if no match, use defaults | ||
115 | if (!$config) $config = new SiteConfig(); | ||
116 | // load fingerprint config? | ||
117 | if ($config->autodetect_on_failure()) { | ||
118 | // check HTML for fingerprints | ||
119 | if (!empty($this->fingerprints) && ($_fphost = $this->findHostUsingFingerprints($html))) { | ||
120 | if ($config_fingerprint = SiteConfig::build($_fphost)) { | ||
121 | $this->debug("Appending site config settings from $_fphost (fingerprint match)"); | ||
122 | $config->append($config_fingerprint); | ||
123 | if ($add_to_cache && !SiteConfig::is_cached($_fphost)) { | ||
124 | //$config_fingerprint->cache_in_apc = true; | ||
125 | SiteConfig::add_to_cache($_fphost, $config_fingerprint); | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | // load global config? | ||
131 | if ($config->autodetect_on_failure()) { | ||
132 | if ($config_global = SiteConfig::build('global', true)) { | ||
133 | $this->debug('Appending site config settings from global.txt'); | ||
134 | $config->append($config_global); | ||
135 | if ($add_to_cache && !SiteConfig::is_cached('global')) { | ||
136 | //$config_global->cache_in_apc = true; | ||
137 | SiteConfig::add_to_cache('global', $config_global); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | // store copy of merged config | ||
142 | if ($add_to_cache) { | ||
143 | // do not store in APC if wildcard match | ||
144 | $use_apc = ($host == $config->cache_key); | ||
145 | $config->cache_key = null; | ||
146 | SiteConfig::add_to_cache("$host.merged", $config, $use_apc); | ||
147 | } | ||
148 | return $config; | ||
149 | } | ||
150 | |||
151 | // returns true on success, false on failure | ||
152 | // $smart_tidy indicates that if tidy is used and no results are produced, we will | ||
153 | // try again without it. Tidy helps us deal with PHP's patchy HTML parsing most of the time | ||
154 | // but it has problems of its own which we try to avoid with this option. | ||
155 | public function process($html, $url, $smart_tidy=true) { | ||
156 | $this->reset(); | ||
157 | $this->config = $this->buildSiteConfig($url, $html); | ||
158 | |||
159 | // do string replacements | ||
160 | if (!empty($this->config->find_string)) { | ||
161 | if (count($this->config->find_string) == count($this->config->replace_string)) { | ||
162 | $html = str_replace($this->config->find_string, $this->config->replace_string, $html, $_count); | ||
163 | $this->debug("Strings replaced: $_count (find_string and/or replace_string)"); | ||
164 | } else { | ||
165 | $this->debug('Skipped string replacement - incorrect number of find-replace strings in site config'); | ||
166 | } | ||
167 | unset($_count); | ||
168 | } | ||
169 | |||
170 | // use tidy (if it exists)? | ||
171 | // This fixes problems with some sites which would otherwise | ||
172 | // trouble DOMDocument's HTML parsing. (Although sometimes it | ||
173 | // makes matters worse, which is why you can override it in site config files.) | ||
174 | $tidied = false; | ||
175 | if ($this->config->tidy() && function_exists('tidy_parse_string') && $smart_tidy) { | ||
176 | $this->debug('Using Tidy'); | ||
177 | $tidy = tidy_parse_string($html, self::$tidy_config, 'UTF8'); | ||
178 | if (tidy_clean_repair($tidy)) { | ||
179 | $original_html = $html; | ||
180 | $tidied = true; | ||
181 | $html = $tidy->value; | ||
182 | } | ||
183 | unset($tidy); | ||
184 | } | ||
185 | |||
186 | // load and parse html | ||
187 | $_parser = $this->config->parser(); | ||
188 | if (!in_array($_parser, $this->allowedParsers)) { | ||
189 | $this->debug("HTML parser $_parser not listed, using libxml instead"); | ||
190 | $_parser = 'libxml'; | ||
191 | } | ||
192 | $this->debug("Attempting to parse HTML with $_parser"); | ||
193 | $this->readability = new Readability($html, $url, $_parser); | ||
194 | |||
195 | // we use xpath to find elements in the given HTML document | ||
196 | // see http://en.wikipedia.org/wiki/XPath_1.0 | ||
197 | $xpath = new DOMXPath($this->readability->dom); | ||
198 | |||
199 | // try to get next page link | ||
200 | foreach ($this->config->next_page_link as $pattern) { | ||
201 | $elems = @$xpath->evaluate($pattern, $this->readability->dom); | ||
202 | if (is_string($elems)) { | ||
203 | $this->nextPageUrl = trim($elems); | ||
204 | break; | ||
205 | } elseif ($elems instanceof DOMNodeList && $elems->length > 0) { | ||
206 | foreach ($elems as $item) { | ||
207 | if ($item instanceof DOMElement && $item->hasAttribute('href')) { | ||
208 | $this->nextPageUrl = $item->getAttribute('href'); | ||
209 | break 2; | ||
210 | } elseif ($item instanceof DOMAttr && $item->value) { | ||
211 | $this->nextPageUrl = $item->value; | ||
212 | break 2; | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | |||
218 | // try to get title | ||
219 | foreach ($this->config->title as $pattern) { | ||
220 | // $this->debug("Trying $pattern"); | ||
221 | $elems = @$xpath->evaluate($pattern, $this->readability->dom); | ||
222 | if (is_string($elems)) { | ||
223 | $this->title = trim($elems); | ||
224 | $this->debug('Title expression evaluated as string: '.$this->title); | ||
225 | $this->debug("...XPath match: $pattern"); | ||
226 | break; | ||
227 | } elseif ($elems instanceof DOMNodeList && $elems->length > 0) { | ||
228 | $this->title = $elems->item(0)->textContent; | ||
229 | $this->debug('Title matched: '.$this->title); | ||
230 | $this->debug("...XPath match: $pattern"); | ||
231 | // remove title from document | ||
232 | try { | ||
233 | @$elems->item(0)->parentNode->removeChild($elems->item(0)); | ||
234 | } catch (DOMException $e) { | ||
235 | // do nothing | ||
236 | } | ||
237 | break; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | // try to get author (if it hasn't already been set) | ||
242 | if (empty($this->author)) { | ||
243 | foreach ($this->config->author as $pattern) { | ||
244 | $elems = @$xpath->evaluate($pattern, $this->readability->dom); | ||
245 | if (is_string($elems)) { | ||
246 | if (trim($elems) != '') { | ||
247 | $this->author[] = trim($elems); | ||
248 | $this->debug('Author expression evaluated as string: '.trim($elems)); | ||
249 | $this->debug("...XPath match: $pattern"); | ||
250 | break; | ||
251 | } | ||
252 | } elseif ($elems instanceof DOMNodeList && $elems->length > 0) { | ||
253 | foreach ($elems as $elem) { | ||
254 | if (!isset($elem->parentNode)) continue; | ||
255 | $this->author[] = trim($elem->textContent); | ||
256 | $this->debug('Author matched: '.trim($elem->textContent)); | ||
257 | } | ||
258 | if (!empty($this->author)) { | ||
259 | $this->debug("...XPath match: $pattern"); | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | } | ||
265 | |||
266 | // try to get language | ||
267 | $_lang_xpath = array('//html[@lang]/@lang', '//meta[@name="DC.language"]/@content'); | ||
268 | foreach ($_lang_xpath as $pattern) { | ||
269 | $elems = @$xpath->evaluate($pattern, $this->readability->dom); | ||
270 | if (is_string($elems)) { | ||
271 | if (trim($elems) != '') { | ||
272 | $this->language = trim($elems); | ||
273 | $this->debug('Language matched: '.$this->language); | ||
274 | break; | ||
275 | } | ||
276 | } elseif ($elems instanceof DOMNodeList && $elems->length > 0) { | ||
277 | foreach ($elems as $elem) { | ||
278 | if (!isset($elem->parentNode)) continue; | ||
279 | $this->language = trim($elem->textContent); | ||
280 | $this->debug('Language matched: '.$this->language); | ||
281 | } | ||
282 | if ($this->language) break; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | // try to get date | ||
287 | foreach ($this->config->date as $pattern) { | ||
288 | $elems = @$xpath->evaluate($pattern, $this->readability->dom); | ||
289 | if (is_string($elems)) { | ||
290 | $this->date = strtotime(trim($elems, "; \t\n\r\0\x0B")); | ||
291 | } elseif ($elems instanceof DOMNodeList && $elems->length > 0) { | ||
292 | $this->date = $elems->item(0)->textContent; | ||
293 | $this->date = strtotime(trim($this->date, "; \t\n\r\0\x0B")); | ||
294 | // remove date from document | ||
295 | // $elems->item(0)->parentNode->removeChild($elems->item(0)); | ||
296 | } | ||
297 | if (!$this->date) { | ||
298 | $this->date = null; | ||
299 | } else { | ||
300 | $this->debug('Date matched: '.date('Y-m-d H:i:s', $this->date)); | ||
301 | $this->debug("...XPath match: $pattern"); | ||
302 | break; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | // strip elements (using xpath expressions) | ||
307 | foreach ($this->config->strip as $pattern) { | ||
308 | $elems = @$xpath->query($pattern, $this->readability->dom); | ||
309 | // check for matches | ||
310 | if ($elems && $elems->length > 0) { | ||
311 | $this->debug('Stripping '.$elems->length.' elements (strip)'); | ||
312 | for ($i=$elems->length-1; $i >= 0; $i--) { | ||
313 | $elems->item($i)->parentNode->removeChild($elems->item($i)); | ||
314 | } | ||
315 | } | ||
316 | } | ||
317 | |||
318 | // strip elements (using id and class attribute values) | ||
319 | foreach ($this->config->strip_id_or_class as $string) { | ||
320 | $string = strtr($string, array("'"=>'', '"'=>'')); | ||
321 | $elems = @$xpath->query("//*[contains(@class, '$string') or contains(@id, '$string')]", $this->readability->dom); | ||
322 | // check for matches | ||
323 | if ($elems && $elems->length > 0) { | ||
324 | $this->debug('Stripping '.$elems->length.' elements (strip_id_or_class)'); | ||
325 | for ($i=$elems->length-1; $i >= 0; $i--) { | ||
326 | $elems->item($i)->parentNode->removeChild($elems->item($i)); | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | |||
331 | // strip images (using src attribute values) | ||
332 | foreach ($this->config->strip_image_src as $string) { | ||
333 | $string = strtr($string, array("'"=>'', '"'=>'')); | ||
334 | $elems = @$xpath->query("//img[contains(@src, '$string')]", $this->readability->dom); | ||
335 | // check for matches | ||
336 | if ($elems && $elems->length > 0) { | ||
337 | $this->debug('Stripping '.$elems->length.' image elements'); | ||
338 | for ($i=$elems->length-1; $i >= 0; $i--) { | ||
339 | $elems->item($i)->parentNode->removeChild($elems->item($i)); | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | // strip elements using Readability.com and Instapaper.com ignore class names | ||
344 | // .entry-unrelated and .instapaper_ignore | ||
345 | // See https://www.readability.com/publishers/guidelines/#view-plainGuidelines | ||
346 | // and http://blog.instapaper.com/post/730281947 | ||
347 | $elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' entry-unrelated ') or contains(concat(' ',normalize-space(@class),' '),' instapaper_ignore ')]", $this->readability->dom); | ||
348 | // check for matches | ||
349 | if ($elems && $elems->length > 0) { | ||
350 | $this->debug('Stripping '.$elems->length.' .entry-unrelated,.instapaper_ignore elements'); | ||
351 | for ($i=$elems->length-1; $i >= 0; $i--) { | ||
352 | $elems->item($i)->parentNode->removeChild($elems->item($i)); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | // strip elements that contain style="display: none;" | ||
357 | $elems = @$xpath->query("//*[contains(@style,'display:none')]", $this->readability->dom); | ||
358 | // check for matches | ||
359 | if ($elems && $elems->length > 0) { | ||
360 | $this->debug('Stripping '.$elems->length.' elements with inline display:none style'); | ||
361 | for ($i=$elems->length-1; $i >= 0; $i--) { | ||
362 | $elems->item($i)->parentNode->removeChild($elems->item($i)); | ||
363 | } | ||
364 | } | ||
365 | |||
366 | // try to get body | ||
367 | foreach ($this->config->body as $pattern) { | ||
368 | $elems = @$xpath->query($pattern, $this->readability->dom); | ||
369 | // check for matches | ||
370 | if ($elems && $elems->length > 0) { | ||
371 | $this->debug('Body matched'); | ||
372 | $this->debug("...XPath match: $pattern"); | ||
373 | if ($elems->length == 1) { | ||
374 | $this->body = $elems->item(0); | ||
375 | // prune (clean up elements that may not be content) | ||
376 | if ($this->config->prune()) { | ||
377 | $this->debug('...pruning content'); | ||
378 | $this->readability->prepArticle($this->body); | ||
379 | } | ||
380 | break; | ||
381 | } else { | ||
382 | $this->body = $this->readability->dom->createElement('div'); | ||
383 | $this->debug($elems->length.' body elems found'); | ||
384 | foreach ($elems as $elem) { | ||
385 | if (!isset($elem->parentNode)) continue; | ||
386 | $isDescendant = false; | ||
387 | foreach ($this->body->childNodes as $parent) { | ||
388 | if ($this->isDescendant($parent, $elem)) { | ||
389 | $isDescendant = true; | ||
390 | break; | ||
391 | } | ||
392 | } | ||
393 | if ($isDescendant) { | ||
394 | $this->debug('...element is child of another body element, skipping.'); | ||
395 | } else { | ||
396 | // prune (clean up elements that may not be content) | ||
397 | if ($this->config->prune()) { | ||
398 | $this->debug('Pruning content'); | ||
399 | $this->readability->prepArticle($elem); | ||
400 | } | ||
401 | $this->debug('...element added to body'); | ||
402 | $this->body->appendChild($elem); | ||
403 | } | ||
404 | } | ||
405 | if ($this->body->hasChildNodes()) break; | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | |||
410 | // auto detect? | ||
411 | $detect_title = $detect_body = $detect_author = $detect_date = false; | ||
412 | // detect title? | ||
413 | if (!isset($this->title)) { | ||
414 | if (empty($this->config->title) || $this->config->autodetect_on_failure()) { | ||
415 | $detect_title = true; | ||
416 | } | ||
417 | } | ||
418 | // detect body? | ||
419 | if (!isset($this->body)) { | ||
420 | if (empty($this->config->body) || $this->config->autodetect_on_failure()) { | ||
421 | $detect_body = true; | ||
422 | } | ||
423 | } | ||
424 | // detect author? | ||
425 | if (empty($this->author)) { | ||
426 | if (empty($this->config->author) || $this->config->autodetect_on_failure()) { | ||
427 | $detect_author = true; | ||
428 | } | ||
429 | } | ||
430 | // detect date? | ||
431 | if (!isset($this->date)) { | ||
432 | if (empty($this->config->date) || $this->config->autodetect_on_failure()) { | ||
433 | $detect_date = true; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | // check for hNews | ||
438 | if ($detect_title || $detect_body) { | ||
439 | // check for hentry | ||
440 | $elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' hentry ')]", $this->readability->dom); | ||
441 | if ($elems && $elems->length > 0) { | ||
442 | $this->debug('hNews: found hentry'); | ||
443 | $hentry = $elems->item(0); | ||
444 | |||
445 | if ($detect_title) { | ||
446 | // check for entry-title | ||
447 | $elems = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' entry-title ')]", $hentry); | ||
448 | if ($elems && $elems->length > 0) { | ||
449 | $this->title = $elems->item(0)->textContent; | ||
450 | $this->debug('hNews: found entry-title: '.$this->title); | ||
451 | // remove title from document | ||
452 | $elems->item(0)->parentNode->removeChild($elems->item(0)); | ||
453 | $detect_title = false; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | if ($detect_date) { | ||
458 | // check for time element with pubdate attribute | ||
459 | $elems = @$xpath->query(".//time[@pubdate] | .//abbr[contains(concat(' ',normalize-space(@class),' '),' published ')]", $hentry); | ||
460 | if ($elems && $elems->length > 0) { | ||
461 | $this->date = strtotime(trim($elems->item(0)->textContent)); | ||
462 | // remove date from document | ||
463 | //$elems->item(0)->parentNode->removeChild($elems->item(0)); | ||
464 | if ($this->date) { | ||
465 | $this->debug('hNews: found publication date: '.date('Y-m-d H:i:s', $this->date)); | ||
466 | $detect_date = false; | ||
467 | } else { | ||
468 | $this->date = null; | ||
469 | } | ||
470 | } | ||
471 | } | ||
472 | |||
473 | if ($detect_author) { | ||
474 | // check for time element with pubdate attribute | ||
475 | $elems = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' vcard ') and (contains(concat(' ',normalize-space(@class),' '),' author ') or contains(concat(' ',normalize-space(@class),' '),' byline '))]", $hentry); | ||
476 | if ($elems && $elems->length > 0) { | ||
477 | $author = $elems->item(0); | ||
478 | $fn = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' fn ')]", $author); | ||
479 | if ($fn && $fn->length > 0) { | ||
480 | foreach ($fn as $_fn) { | ||
481 | if (trim($_fn->textContent) != '') { | ||
482 | $this->author[] = trim($_fn->textContent); | ||
483 | $this->debug('hNews: found author: '.trim($_fn->textContent)); | ||
484 | } | ||
485 | } | ||
486 | } else { | ||
487 | if (trim($author->textContent) != '') { | ||
488 | $this->author[] = trim($author->textContent); | ||
489 | $this->debug('hNews: found author: '.trim($author->textContent)); | ||
490 | } | ||
491 | } | ||
492 | $detect_author = empty($this->author); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | // check for entry-content. | ||
497 | // according to hAtom spec, if there are multiple elements marked entry-content, | ||
498 | // we include all of these in the order they appear - see http://microformats.org/wiki/hatom#Entry_Content | ||
499 | if ($detect_body) { | ||
500 | $elems = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' entry-content ')]", $hentry); | ||
501 | if ($elems && $elems->length > 0) { | ||
502 | $this->debug('hNews: found entry-content'); | ||
503 | if ($elems->length == 1) { | ||
504 | // what if it's empty? (some sites misuse hNews - place their content outside an empty entry-content element) | ||
505 | $e = $elems->item(0); | ||
506 | if (($e->tagName == 'img') || (trim($e->textContent) != '')) { | ||
507 | $this->body = $elems->item(0); | ||
508 | // prune (clean up elements that may not be content) | ||
509 | if ($this->config->prune()) { | ||
510 | $this->debug('Pruning content'); | ||
511 | $this->readability->prepArticle($this->body); | ||
512 | } | ||
513 | $detect_body = false; | ||
514 | } else { | ||
515 | $this->debug('hNews: skipping entry-content - appears not to contain content'); | ||
516 | } | ||
517 | unset($e); | ||
518 | } else { | ||
519 | $this->body = $this->readability->dom->createElement('div'); | ||
520 | $this->debug($elems->length.' entry-content elems found'); | ||
521 | foreach ($elems as $elem) { | ||
522 | if (!isset($elem->parentNode)) continue; | ||
523 | $isDescendant = false; | ||
524 | foreach ($this->body->childNodes as $parent) { | ||
525 | if ($this->isDescendant($parent, $elem)) { | ||
526 | $isDescendant = true; | ||
527 | break; | ||
528 | } | ||
529 | } | ||
530 | if ($isDescendant) { | ||
531 | $this->debug('Element is child of another body element, skipping.'); | ||
532 | } else { | ||
533 | // prune (clean up elements that may not be content) | ||
534 | if ($this->config->prune()) { | ||
535 | $this->debug('Pruning content'); | ||
536 | $this->readability->prepArticle($elem); | ||
537 | } | ||
538 | $this->debug('Element added to body'); | ||
539 | $this->body->appendChild($elem); | ||
540 | } | ||
541 | } | ||
542 | $detect_body = false; | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | } | ||
548 | |||
549 | // check for elements marked with instapaper_title | ||
550 | if ($detect_title) { | ||
551 | // check for instapaper_title | ||
552 | $elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' instapaper_title ')]", $this->readability->dom); | ||
553 | if ($elems && $elems->length > 0) { | ||
554 | $this->title = $elems->item(0)->textContent; | ||
555 | $this->debug('Title found (.instapaper_title): '.$this->title); | ||
556 | // remove title from document | ||
557 | $elems->item(0)->parentNode->removeChild($elems->item(0)); | ||
558 | $detect_title = false; | ||
559 | } | ||
560 | } | ||
561 | // check for elements marked with instapaper_body | ||
562 | if ($detect_body) { | ||
563 | $elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' instapaper_body ')]", $this->readability->dom); | ||
564 | if ($elems && $elems->length > 0) { | ||
565 | $this->debug('body found (.instapaper_body)'); | ||
566 | $this->body = $elems->item(0); | ||
567 | // prune (clean up elements that may not be content) | ||
568 | if ($this->config->prune()) { | ||
569 | $this->debug('Pruning content'); | ||
570 | $this->readability->prepArticle($this->body); | ||
571 | } | ||
572 | $detect_body = false; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | // Find author in rel="author" marked element | ||
577 | // We only use this if there's exactly one. | ||
578 | // If there's more than one, it could indicate more than | ||
579 | // one author, but it could also indicate that we're processing | ||
580 | // a page listing different articles with different authors. | ||
581 | if ($detect_author) { | ||
582 | $elems = @$xpath->query("//a[contains(concat(' ',normalize-space(@rel),' '),' author ')]", $this->readability->dom); | ||
583 | if ($elems && $elems->length == 1) { | ||
584 | $author = trim($elems->item(0)->textContent); | ||
585 | if ($author != '') { | ||
586 | $this->debug("Author found (rel=\"author\"): $author"); | ||
587 | $this->author[] = $author; | ||
588 | $detect_author = false; | ||
589 | } | ||
590 | } | ||
591 | } | ||
592 | |||
593 | // Find date in pubdate marked time element | ||
594 | // For the same reason given above, we only use this | ||
595 | // if there's exactly one element. | ||
596 | if ($detect_date) { | ||
597 | $elems = @$xpath->query("//time[@pubdate]", $this->readability->dom); | ||
598 | if ($elems && $elems->length == 1) { | ||
599 | $this->date = strtotime(trim($elems->item(0)->textContent)); | ||
600 | // remove date from document | ||
601 | //$elems->item(0)->parentNode->removeChild($elems->item(0)); | ||
602 | if ($this->date) { | ||
603 | $this->debug('Date found (pubdate marked time element): '.date('Y-m-d H:i:s', $this->date)); | ||
604 | $detect_date = false; | ||
605 | } else { | ||
606 | $this->date = null; | ||
607 | } | ||
608 | } | ||
609 | } | ||
610 | |||
611 | // still missing title or body, so we detect using Readability | ||
612 | if ($detect_title || $detect_body) { | ||
613 | $this->debug('Using Readability'); | ||
614 | // clone body if we're only using Readability for title (otherwise it may interfere with body element) | ||
615 | if (isset($this->body)) $this->body = $this->body->cloneNode(true); | ||
616 | $success = $this->readability->init(); | ||
617 | } | ||
618 | if ($detect_title) { | ||
619 | $this->debug('Detecting title'); | ||
620 | $this->title = $this->readability->getTitle()->textContent; | ||
621 | } | ||
622 | if ($detect_body && $success) { | ||
623 | $this->debug('Detecting body'); | ||
624 | $this->body = $this->readability->getContent(); | ||
625 | if ($this->body->childNodes->length == 1 && $this->body->firstChild->nodeType === XML_ELEMENT_NODE) { | ||
626 | $this->body = $this->body->firstChild; | ||
627 | } | ||
628 | // prune (clean up elements that may not be content) | ||
629 | if ($this->config->prune()) { | ||
630 | $this->debug('Pruning content'); | ||
631 | $this->readability->prepArticle($this->body); | ||
632 | } | ||
633 | } | ||
634 | if (isset($this->body)) { | ||
635 | // remove scripts | ||
636 | $this->readability->removeScripts($this->body); | ||
637 | // remove any h1-h6 elements that appear as first thing in the body | ||
638 | // and which match our title | ||
639 | if (isset($this->title) && ($this->title != '')) { | ||
640 | $firstChild = $this->body->firstChild; | ||
641 | while ($firstChild->nodeType && ($firstChild->nodeType !== XML_ELEMENT_NODE)) { | ||
642 | $firstChild = $firstChild->nextSibling; | ||
643 | } | ||
644 | if (($firstChild->nodeType === XML_ELEMENT_NODE) | ||
645 | && in_array(strtolower($firstChild->tagName), array('h1', 'h2', 'h3', 'h4', 'h5', 'h6')) | ||
646 | && (strtolower(trim($firstChild->textContent)) == strtolower(trim($this->title)))) { | ||
647 | $this->body->removeChild($firstChild); | ||
648 | } | ||
649 | } | ||
650 | // prevent self-closing iframes | ||
651 | $elems = $this->body->getElementsByTagName('iframe'); | ||
652 | for ($i = $elems->length-1; $i >= 0; $i--) { | ||
653 | $e = $elems->item($i); | ||
654 | if (!$e->hasChildNodes()) { | ||
655 | $e->appendChild($this->body->ownerDocument->createTextNode('[embedded content]')); | ||
656 | } | ||
657 | } | ||
658 | // remove image lazy loading - WordPress plugin http://wordpress.org/extend/plugins/lazy-load/ | ||
659 | // the plugin replaces the src attribute to point to a 1x1 gif and puts the original src | ||
660 | // inside the data-lazy-src attribute. It also places the original image inside a noscript element | ||
661 | // next to the amended one. | ||
662 | $elems = @$xpath->query("//img[@data-lazy-src]", $this->body); | ||
663 | for ($i = $elems->length-1; $i >= 0; $i--) { | ||
664 | $e = $elems->item($i); | ||
665 | // let's see if we can grab image from noscript | ||
666 | if ($e->nextSibling !== null && $e->nextSibling->nodeName === 'noscript') { | ||
667 | $_new_elem = $e->ownerDocument->createDocumentFragment(); | ||
668 | @$_new_elem->appendXML($e->nextSibling->innerHTML); | ||
669 | $e->nextSibling->parentNode->replaceChild($_new_elem, $e->nextSibling); | ||
670 | $e->parentNode->removeChild($e); | ||
671 | } else { | ||
672 | // Use data-lazy-src as src value | ||
673 | $e->setAttribute('src', $e->getAttribute('data-lazy-src')); | ||
674 | $e->removeAttribute('data-lazy-src'); | ||
675 | } | ||
676 | } | ||
677 | |||
678 | $this->success = true; | ||
679 | } | ||
680 | |||
681 | // if we've had no success and we've used tidy, there's a chance | ||
682 | // that tidy has messed up. So let's try again without tidy... | ||
683 | if (!$this->success && $tidied && $smart_tidy) { | ||
684 | $this->debug('Trying again without tidy'); | ||
685 | $this->process($original_html, $url, false); | ||
686 | } | ||
687 | |||
688 | return $this->success; | ||
689 | } | ||
690 | |||
691 | private function isDescendant(DOMElement $parent, DOMElement $child) { | ||
692 | $node = $child->parentNode; | ||
693 | while ($node != null) { | ||
694 | if ($node->isSameNode($parent)) return true; | ||
695 | $node = $node->parentNode; | ||
696 | } | ||
697 | return false; | ||
698 | } | ||
699 | |||
700 | public function getContent() { | ||
701 | return $this->body; | ||
702 | } | ||
703 | |||
704 | public function getTitle() { | ||
705 | return $this->title; | ||
706 | } | ||
707 | |||
708 | public function getAuthors() { | ||
709 | return $this->author; | ||
710 | } | ||
711 | |||
712 | public function getLanguage() { | ||
713 | return $this->language; | ||
714 | } | ||
715 | |||
716 | public function getDate() { | ||
717 | return $this->date; | ||
718 | } | ||
719 | |||
720 | public function getSiteConfig() { | ||
721 | return $this->config; | ||
722 | } | ||
723 | |||
724 | public function getNextPageUrl() { | ||
725 | return $this->nextPageUrl; | ||
726 | } | ||
727 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/content-extractor/SiteConfig.php b/inc/3rdparty/libraries/content-extractor/SiteConfig.php deleted file mode 100644 index 1f6a7603..00000000 --- a/inc/3rdparty/libraries/content-extractor/SiteConfig.php +++ /dev/null | |||
@@ -1,343 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Site Config | ||
4 | * | ||
5 | * Each instance of this class should hold extraction patterns and other directives | ||
6 | * for a website. See ContentExtractor class to see how it's used. | ||
7 | * | ||
8 | * @version 0.8 | ||
9 | * @date 2013-04-16 | ||
10 | * @author Keyvan Minoukadeh | ||
11 | * @copyright 2013 Keyvan Minoukadeh | ||
12 | * @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3 | ||
13 | */ | ||
14 | |||
15 | class SiteConfig | ||
16 | { | ||
17 | // Use first matching element as title (0 or more xpath expressions) | ||
18 | public $title = array(); | ||
19 | |||
20 | // Use first matching element as body (0 or more xpath expressions) | ||
21 | public $body = array(); | ||
22 | |||
23 | // Use first matching element as author (0 or more xpath expressions) | ||
24 | public $author = array(); | ||
25 | |||
26 | // Use first matching element as date (0 or more xpath expressions) | ||
27 | public $date = array(); | ||
28 | |||
29 | // Strip elements matching these xpath expressions (0 or more) | ||
30 | public $strip = array(); | ||
31 | |||
32 | // Strip elements which contain these strings (0 or more) in the id or class attribute | ||
33 | public $strip_id_or_class = array(); | ||
34 | |||
35 | // Strip images which contain these strings (0 or more) in the src attribute | ||
36 | public $strip_image_src = array(); | ||
37 | |||
38 | // Additional HTTP headers to send | ||
39 | // NOT YET USED | ||
40 | public $http_header = array(); | ||
41 | |||
42 | // Process HTML with tidy before creating DOM (bool or null if undeclared) | ||
43 | public $tidy = null; | ||
44 | |||
45 | protected $default_tidy = true; // used if undeclared | ||
46 | |||
47 | // Autodetect title/body if xpath expressions fail to produce results. | ||
48 | // Note that this applies to title and body separately, ie. | ||
49 | // * if we get a body match but no title match, this option will determine whether we autodetect title | ||
50 | // * if neither match, this determines whether we autodetect title and body. | ||
51 | // Also note that this only applies when there is at least one xpath expression in title or body, ie. | ||
52 | // * if title and body are both empty (no xpath expressions), this option has no effect (both title and body will be auto-detected) | ||
53 | // * if there's an xpath expression for title and none for body, body will be auto-detected and this option will determine whether we auto-detect title if the xpath expression for it fails to produce results. | ||
54 | // Usage scenario: you want to extract something specific from a set of URLs, e.g. a table, and if the table is not found, you want to ignore the entry completely. Auto-detection is unlikely to succeed here, so you construct your patterns and set this option to false. Another scenario may be a site where auto-detection has proven to fail (or worse, picked up the wrong content). | ||
55 | // bool or null if undeclared | ||
56 | public $autodetect_on_failure = null; | ||
57 | protected $default_autodetect_on_failure = true; // used if undeclared | ||
58 | |||
59 | // Clean up content block - attempt to remove elements that appear to be superfluous | ||
60 | // bool or null if undeclared | ||
61 | public $prune = null; | ||
62 | protected $default_prune = true; // used if undeclared | ||
63 | |||
64 | // Test URL - if present, can be used to test the config above | ||
65 | public $test_url = array(); | ||
66 | |||
67 | // Single-page link - should identify a link element or URL pointing to the page holding the entire article | ||
68 | // This is useful for sites which split their articles across multiple pages. Links to such pages tend to | ||
69 | // display the first page with links to the other pages at the bottom. Often there is also a link to a page | ||
70 | // which displays the entire article on one page (e.g. 'print view'). | ||
71 | // This should be an XPath expression identifying the link to that page. If present and we find a match, | ||
72 | // we will retrieve that page and the rest of the options in this config will be applied to the new page. | ||
73 | public $single_page_link = array(); | ||
74 | |||
75 | public $next_page_link = array(); | ||
76 | |||
77 | // Single-page link in feed? - same as above, but patterns applied to item description HTML taken from feed | ||
78 | public $single_page_link_in_feed = array(); | ||
79 | |||
80 | // Which parser to use for turning raw HTML into a DOMDocument (either 'libxml' or 'html5lib') | ||
81 | // string or null if undeclared | ||
82 | public $parser = null; | ||
83 | protected $default_parser = 'libxml'; // used if undeclared | ||
84 | |||
85 | // Strings to search for in HTML before processing begins (used with $replace_string) | ||
86 | public $find_string = array(); | ||
87 | // Strings to replace those found in $find_string before HTML processing begins | ||
88 | public $replace_string = array(); | ||
89 | |||
90 | // the options below cannot be set in the config files which this class represents | ||
91 | |||
92 | //public $cache_in_apc = false; // used to decide if we should cache in apc or not | ||
93 | public $cache_key = null; | ||
94 | public static $debug = false; | ||
95 | protected static $apc = false; | ||
96 | protected static $config_path; | ||
97 | protected static $config_path_fallback; | ||
98 | protected static $config_cache = array(); | ||
99 | const HOSTNAME_REGEX = '/^(([a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9-]*[A-Za-z0-9])$/'; | ||
100 | |||
101 | protected static function debug($msg) { | ||
102 | if (self::$debug) { | ||
103 | //$mem = round(memory_get_usage()/1024, 2); | ||
104 | //$memPeak = round(memory_get_peak_usage()/1024, 2); | ||
105 | echo '* ',$msg; | ||
106 | //echo ' - mem used: ',$mem," (peak: $memPeak)\n"; | ||
107 | echo "\n"; | ||
108 | ob_flush(); | ||
109 | flush(); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | // enable APC caching of certain site config files? | ||
114 | // If enabled the following site config files will be | ||
115 | // cached in APC cache (when requested for first time): | ||
116 | // * anything in site_config/custom/ and its corresponding file in site_config/standard/ | ||
117 | // * the site config files associated with HTML fingerprints | ||
118 | // * the global site config file | ||
119 | // returns true if enabled, false otherwise | ||
120 | public static function use_apc($apc=true) { | ||
121 | if (!function_exists('apc_add')) { | ||
122 | if ($apc) self::debug('APC will not be used (function apc_add does not exist)'); | ||
123 | return false; | ||
124 | } | ||
125 | self::$apc = $apc; | ||
126 | return $apc; | ||
127 | } | ||
128 | |||
129 | // return bool or null | ||
130 | public function tidy($use_default=true) { | ||
131 | if ($use_default) return (isset($this->tidy)) ? $this->tidy : $this->default_tidy; | ||
132 | return $this->tidy; | ||
133 | } | ||
134 | |||
135 | // return bool or null | ||
136 | public function prune($use_default=true) { | ||
137 | if ($use_default) return (isset($this->prune)) ? $this->prune : $this->default_prune; | ||
138 | return $this->prune; | ||
139 | } | ||
140 | |||
141 | // return string or null | ||
142 | public function parser($use_default=true) { | ||
143 | if ($use_default) return (isset($this->parser)) ? $this->parser : $this->default_parser; | ||
144 | return $this->parser; | ||
145 | } | ||
146 | |||
147 | // return bool or null | ||
148 | public function autodetect_on_failure($use_default=true) { | ||
149 | if ($use_default) return (isset($this->autodetect_on_failure)) ? $this->autodetect_on_failure : $this->default_autodetect_on_failure; | ||
150 | return $this->autodetect_on_failure; | ||
151 | } | ||
152 | |||
153 | public static function set_config_path($path, $fallback=null) { | ||
154 | self::$config_path = $path; | ||
155 | self::$config_path_fallback = $fallback; | ||
156 | } | ||
157 | |||
158 | public static function add_to_cache($key, SiteConfig $config, $use_apc=true) { | ||
159 | $key = strtolower($key); | ||
160 | if (substr($key, 0, 4) == 'www.') $key = substr($key, 4); | ||
161 | if ($config->cache_key) $key = $config->cache_key; | ||
162 | self::$config_cache[$key] = $config; | ||
163 | if (self::$apc && $use_apc) { | ||
164 | self::debug("Adding site config to APC cache with key sc.$key"); | ||
165 | apc_add("sc.$key", $config); | ||
166 | } | ||
167 | self::debug("Cached site config with key $key"); | ||
168 | } | ||
169 | |||
170 | public static function is_cached($key) { | ||
171 | $key = strtolower($key); | ||
172 | if (substr($key, 0, 4) == 'www.') $key = substr($key, 4); | ||
173 | if (array_key_exists($key, self::$config_cache)) { | ||
174 | return true; | ||
175 | } elseif (self::$apc && (bool)apc_fetch("sc.$key")) { | ||
176 | return true; | ||
177 | } | ||
178 | return false; | ||
179 | } | ||
180 | |||
181 | public function append(SiteConfig $newconfig) { | ||
182 | // check for commands where we accept multiple statements (no test_url) | ||
183 | foreach (array('title', 'body', 'author', 'date', 'strip', 'strip_id_or_class', 'strip_image_src', 'single_page_link', 'single_page_link_in_feed', 'next_page_link', 'http_header') as $var) { | ||
184 | // append array elements for this config variable from $newconfig to this config | ||
185 | //$this->$var = $this->$var + $newconfig->$var; | ||
186 | $this->$var = array_unique(array_merge($this->$var, $newconfig->$var)); | ||
187 | } | ||
188 | // check for single statement commands | ||
189 | // we do not overwrite existing non null values | ||
190 | foreach (array('tidy', 'prune', 'parser', 'autodetect_on_failure') as $var) { | ||
191 | if ($this->$var === null) $this->$var = $newconfig->$var; | ||
192 | } | ||
193 | // treat find_string and replace_string separately (don't apply array_unique) (thanks fabrizio!) | ||
194 | foreach (array('find_string', 'replace_string') as $var) { | ||
195 | // append array elements for this config variable from $newconfig to this config | ||
196 | //$this->$var = $this->$var + $newconfig->$var; | ||
197 | $this->$var = array_merge($this->$var, $newconfig->$var); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | // returns SiteConfig instance if an appropriate one is found, false otherwise | ||
202 | // if $exact_host_match is true, we will not look for wildcard config matches | ||
203 | // by default if host is 'test.example.org' we will look for and load '.example.org.txt' if it exists | ||
204 | public static function build($host, $exact_host_match=false) { | ||
205 | $host = strtolower($host); | ||
206 | if (substr($host, 0, 4) == 'www.') $host = substr($host, 4); | ||
207 | if (!$host || (strlen($host) > 200) || !preg_match(self::HOSTNAME_REGEX, ltrim($host, '.'))) return false; | ||
208 | // check for site configuration | ||
209 | $try = array($host); | ||
210 | // should we look for wildcard matches | ||
211 | if (!$exact_host_match) { | ||
212 | $split = explode('.', $host); | ||
213 | if (count($split) > 1) { | ||
214 | array_shift($split); | ||
215 | $try[] = '.'.implode('.', $split); | ||
216 | } | ||
217 | } | ||
218 | |||
219 | // look for site config file in primary folder | ||
220 | self::debug(". looking for site config for $host in primary folder"); | ||
221 | foreach ($try as $h) { | ||
222 | if (array_key_exists($h, self::$config_cache)) { | ||
223 | self::debug("... site config for $h already loaded in this request"); | ||
224 | return self::$config_cache[$h]; | ||
225 | } elseif (self::$apc && ($sconfig = apc_fetch("sc.$h"))) { | ||
226 | self::debug("... site config for $h in APC cache"); | ||
227 | return $sconfig; | ||
228 | } elseif (file_exists(self::$config_path."/$h.txt")) { | ||
229 | self::debug("... found site config ($h.txt)"); | ||
230 | $file_primary = self::$config_path."/$h.txt"; | ||
231 | $matched_name = $h; | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | // if we found site config, process it | ||
237 | if (isset($file_primary)) { | ||
238 | $config_lines = file($file_primary, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); | ||
239 | if (!$config_lines || !is_array($config_lines)) return false; | ||
240 | $config = self::build_from_array($config_lines); | ||
241 | // if APC caching is available and enabled, mark this for cache | ||
242 | //$config->cache_in_apc = true; | ||
243 | $config->cache_key = $matched_name; | ||
244 | |||
245 | // if autodetec on failure is off (on by default) we do not need to look | ||
246 | // in secondary folder | ||
247 | if (!$config->autodetect_on_failure()) { | ||
248 | self::debug('... autodetect on failure is disabled (no other site config files will be loaded)'); | ||
249 | return $config; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | // look for site config file in secondary folder | ||
254 | if (isset(self::$config_path_fallback)) { | ||
255 | self::debug(". looking for site config for $host in secondary folder"); | ||
256 | foreach ($try as $h) { | ||
257 | if (file_exists(self::$config_path_fallback."/$h.txt")) { | ||
258 | self::debug("... found site config in secondary folder ($h.txt)"); | ||
259 | $file_secondary = self::$config_path_fallback."/$h.txt"; | ||
260 | $matched_name = $h; | ||
261 | break; | ||
262 | } | ||
263 | } | ||
264 | if (!isset($file_secondary)) { | ||
265 | self::debug("... no site config match in secondary folder"); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | // return false if no config file found | ||
270 | if (!isset($file_primary) && !isset($file_secondary)) { | ||
271 | self::debug("... no site config match for $host"); | ||
272 | return false; | ||
273 | } | ||
274 | |||
275 | // return primary config if secondary not found | ||
276 | if (!isset($file_secondary) && isset($config)) { | ||
277 | return $config; | ||
278 | } | ||
279 | |||
280 | // process secondary config file | ||
281 | $config_lines = file($file_secondary, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); | ||
282 | if (!$config_lines || !is_array($config_lines)) { | ||
283 | // failed to process secondary | ||
284 | if (isset($config)) { | ||
285 | // return primary config | ||
286 | return $config; | ||
287 | } else { | ||
288 | return false; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | // merge with primary and return | ||
293 | if (isset($config)) { | ||
294 | self::debug('. merging config files'); | ||
295 | $config->append(self::build_from_array($config_lines)); | ||
296 | return $config; | ||
297 | } else { | ||
298 | // return just secondary | ||
299 | $config = self::build_from_array($config_lines); | ||
300 | // if APC caching is available and enabled, mark this for cache | ||
301 | //$config->cache_in_apc = true; | ||
302 | $config->cache_key = $matched_name; | ||
303 | return $config; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | public static function build_from_array(array $lines) { | ||
308 | $config = new SiteConfig(); | ||
309 | foreach ($lines as $line) { | ||
310 | $line = trim($line); | ||
311 | |||
312 | // skip comments, empty lines | ||
313 | if ($line == '' || $line[0] == '#') continue; | ||
314 | |||
315 | // get command | ||
316 | $command = explode(':', $line, 2); | ||
317 | // if there's no colon ':', skip this line | ||
318 | if (count($command) != 2) continue; | ||
319 | $val = trim($command[1]); | ||
320 | $command = trim($command[0]); | ||
321 | if ($command == '' || $val == '') continue; | ||
322 | |||
323 | // check for commands where we accept multiple statements | ||
324 | if (in_array($command, array('title', 'body', 'author', 'date', 'strip', 'strip_id_or_class', 'strip_image_src', 'single_page_link', 'single_page_link_in_feed', 'next_page_link', 'http_header', 'test_url', 'find_string', 'replace_string'))) { | ||
325 | array_push($config->$command, $val); | ||
326 | // check for single statement commands that evaluate to true or false | ||
327 | } elseif (in_array($command, array('tidy', 'prune', 'autodetect_on_failure'))) { | ||
328 | $config->$command = ($val == 'yes'); | ||
329 | // check for single statement commands stored as strings | ||
330 | } elseif (in_array($command, array('parser'))) { | ||
331 | $config->$command = $val; | ||
332 | // check for replace_string(find): replace | ||
333 | } elseif ((substr($command, -1) == ')') && preg_match('!^([a-z0-9_]+)\((.*?)\)$!i', $command, $match)) { | ||
334 | if (in_array($match[1], array('replace_string'))) { | ||
335 | $command = $match[1]; | ||
336 | array_push($config->find_string, $match[2]); | ||
337 | array_push($config->$command, $val); | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | return $config; | ||
342 | } | ||
343 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/feedwriter/FeedItem.php b/inc/3rdparty/libraries/feedwriter/FeedItem.php deleted file mode 100755 index 40786598..00000000 --- a/inc/3rdparty/libraries/feedwriter/FeedItem.php +++ /dev/null | |||
@@ -1,204 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Univarsel Feed Writer | ||
4 | * | ||
5 | * FeedItem class - Used as feed element in FeedWriter class | ||
6 | * | ||
7 | * @package UnivarselFeedWriter | ||
8 | * @author Anis uddin Ahmad <anisniit@gmail.com> | ||
9 | * @link http://www.ajaxray.com/projects/rss | ||
10 | */ | ||
11 | class FeedItem | ||
12 | { | ||
13 | private $elements = array(); //Collection of feed elements | ||
14 | private $version; | ||
15 | |||
16 | /** | ||
17 | * Constructor | ||
18 | * | ||
19 | * @param contant (RSS1/RSS2/ATOM) RSS2 is default. | ||
20 | */ | ||
21 | function __construct($version = RSS2) | ||
22 | { | ||
23 | $this->version = $version; | ||
24 | } | ||
25 | |||
26 | /** | ||
27 | * Set element (overwrites existing elements with $elementName) | ||
28 | * | ||
29 | * @access public | ||
30 | * @param srting The tag name of an element | ||
31 | * @param srting The content of tag | ||
32 | * @param array Attributes(if any) in 'attrName' => 'attrValue' format | ||
33 | * @return void | ||
34 | */ | ||
35 | public function setElement($elementName, $content, $attributes = null) | ||
36 | { | ||
37 | if (isset($this->elements[$elementName])) { | ||
38 | unset($this->elements[$elementName]); | ||
39 | } | ||
40 | $this->addElement($elementName, $content, $attributes); | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * Add an element to elements array | ||
45 | * | ||
46 | * @access public | ||
47 | * @param srting The tag name of an element | ||
48 | * @param srting The content of tag | ||
49 | * @param array Attributes(if any) in 'attrName' => 'attrValue' format | ||
50 | * @return void | ||
51 | */ | ||
52 | public function addElement($elementName, $content, $attributes = null) | ||
53 | { | ||
54 | $i = 0; | ||
55 | if (isset($this->elements[$elementName])) { | ||
56 | $i = count($this->elements[$elementName]); | ||
57 | } else { | ||
58 | $this->elements[$elementName] = array(); | ||
59 | } | ||
60 | $this->elements[$elementName][$i]['name'] = $elementName; | ||
61 | $this->elements[$elementName][$i]['content'] = $content; | ||
62 | $this->elements[$elementName][$i]['attributes'] = $attributes; | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * Set multiple feed elements from an array. | ||
67 | * Elements which have attributes cannot be added by this method | ||
68 | * | ||
69 | * @access public | ||
70 | * @param array array of elements in 'tagName' => 'tagContent' format. | ||
71 | * @return void | ||
72 | */ | ||
73 | public function addElementArray($elementArray) | ||
74 | { | ||
75 | if(! is_array($elementArray)) return; | ||
76 | foreach ($elementArray as $elementName => $content) | ||
77 | { | ||
78 | $this->addElement($elementName, $content); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * Return the collection of elements in this feed item | ||
84 | * | ||
85 | * @access public | ||
86 | * @return array | ||
87 | */ | ||
88 | public function getElements() | ||
89 | { | ||
90 | return $this->elements; | ||
91 | } | ||
92 | |||
93 | // Wrapper functions ------------------------------------------------------ | ||
94 | |||
95 | /** | ||
96 | * Set the 'dscription' element of feed item | ||
97 | * | ||
98 | * @access public | ||
99 | * @param string The content of 'description' element | ||
100 | * @return void | ||
101 | */ | ||
102 | public function setDescription($description) | ||
103 | { | ||
104 | $tag = ($this->version == ATOM)? 'summary' : 'description'; | ||
105 | $this->setElement($tag, $description); | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * @desc Set the 'title' element of feed item | ||
110 | * @access public | ||
111 | * @param string The content of 'title' element | ||
112 | * @return void | ||
113 | */ | ||
114 | public function setTitle($title) | ||
115 | { | ||
116 | $this->setElement('title', $title); | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Set the 'date' element of feed item | ||
121 | * | ||
122 | * @access public | ||
123 | * @param string The content of 'date' element | ||
124 | * @return void | ||
125 | */ | ||
126 | public function setDate($date) | ||
127 | { | ||
128 | if(! is_numeric($date)) | ||
129 | { | ||
130 | $date = strtotime($date); | ||
131 | } | ||
132 | |||
133 | if($this->version == ATOM) | ||
134 | { | ||
135 | $tag = 'updated'; | ||
136 | $value = date(DATE_ATOM, $date); | ||
137 | } | ||
138 | elseif($this->version == RSS2) | ||
139 | { | ||
140 | $tag = 'pubDate'; | ||
141 | $value = date(DATE_RSS, $date); | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | $tag = 'dc:date'; | ||
146 | $value = date("Y-m-d", $date); | ||
147 | } | ||
148 | |||
149 | $this->setElement($tag, $value); | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * Set the 'link' element of feed item | ||
154 | * | ||
155 | * @access public | ||
156 | * @param string The content of 'link' element | ||
157 | * @return void | ||
158 | */ | ||
159 | public function setLink($link) | ||
160 | { | ||
161 | if($this->version == RSS2 || $this->version == RSS1) | ||
162 | { | ||
163 | $this->setElement('link', $link); | ||
164 | $this->setElement('guid', $link); | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | $this->setElement('link','',array('href'=>$link)); | ||
169 | $this->setElement('id', FeedWriter::uuid($link,'urn:uuid:')); | ||
170 | } | ||
171 | |||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Set the 'source' element of feed item | ||
176 | * | ||
177 | * @access public | ||
178 | * @param string The content of 'source' element | ||
179 | * @return void | ||
180 | */ | ||
181 | public function setSource($link) | ||
182 | { | ||
183 | $attributes = array('url'=>$link); | ||
184 | $this->setElement('source', "wallabag",$attributes); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Set the 'encloser' element of feed item | ||
189 | * For RSS 2.0 only | ||
190 | * | ||
191 | * @access public | ||
192 | * @param string The url attribute of encloser tag | ||
193 | * @param string The length attribute of encloser tag | ||
194 | * @param string The type attribute of encloser tag | ||
195 | * @return void | ||
196 | */ | ||
197 | public function setEncloser($url, $length, $type) | ||
198 | { | ||
199 | $attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type); | ||
200 | $this->setElement('enclosure','',$attributes); | ||
201 | } | ||
202 | |||
203 | } // end of class FeedItem | ||
204 | ?> \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/feedwriter/FeedWriter.php b/inc/3rdparty/libraries/feedwriter/FeedWriter.php deleted file mode 100755 index 9446cddf..00000000 --- a/inc/3rdparty/libraries/feedwriter/FeedWriter.php +++ /dev/null | |||
@@ -1,453 +0,0 @@ | |||
1 | <?php | ||
2 | define('RSS2', 1, true); | ||
3 | define('JSON', 2, true); | ||
4 | define('JSONP', 3, true); | ||
5 | define('ATOM', 4, true); | ||
6 | |||
7 | /** | ||
8 | * Univarsel Feed Writer class | ||
9 | * | ||
10 | * Genarate RSS2 or JSON (original: RSS 1.0, RSS2.0 and ATOM Feed) | ||
11 | * | ||
12 | * Modified for FiveFilters.org's Full-Text RSS project | ||
13 | * to allow for inclusion of hubs, JSON output. | ||
14 | * Stripped RSS1 and ATOM support. | ||
15 | * | ||
16 | * @package UnivarselFeedWriter | ||
17 | * @author Anis uddin Ahmad <anisniit@gmail.com> | ||
18 | * @link http://www.ajaxray.com/projects/rss | ||
19 | */ | ||
20 | class FeedWriter | ||
21 | { | ||
22 | private $self = null; // self URL - http://feed2.w3.org/docs/warning/MissingAtomSelfLink.html | ||
23 | private $hubs = array(); // PubSubHubbub hubs | ||
24 | private $channels = array(); // Collection of channel elements | ||
25 | private $items = array(); // Collection of items as object of FeedItem class. | ||
26 | private $data = array(); // Store some other version wise data | ||
27 | private $CDATAEncoding = array(); // The tag names which have to encoded as CDATA | ||
28 | private $xsl = null; // stylesheet to render RSS (used by Chrome) | ||
29 | private $json = null; // JSON object | ||
30 | |||
31 | private $version = null; | ||
32 | |||
33 | /** | ||
34 | * Constructor | ||
35 | * | ||
36 | * @param constant the version constant (RSS2 or JSON). | ||
37 | */ | ||
38 | function __construct($version = RSS2) | ||
39 | { | ||
40 | $this->version = $version; | ||
41 | |||
42 | // Setting default value for assential channel elements | ||
43 | $this->channels['title'] = $version . ' Feed'; | ||
44 | $this->channels['link'] = 'http://www.ajaxray.com/blog'; | ||
45 | |||
46 | //Tag names to encode in CDATA | ||
47 | $this->CDATAEncoding = array('description', 'content:encoded', 'content', 'subtitle', 'summary'); | ||
48 | } | ||
49 | |||
50 | public function setFormat($format) { | ||
51 | $this->version = $format; | ||
52 | } | ||
53 | |||
54 | // Start # public functions --------------------------------------------- | ||
55 | |||
56 | /** | ||
57 | * Set a channel element | ||
58 | * @access public | ||
59 | * @param srting name of the channel tag | ||
60 | * @param string content of the channel tag | ||
61 | * @return void | ||
62 | */ | ||
63 | public function setChannelElement($elementName, $content) | ||
64 | { | ||
65 | $this->channels[$elementName] = $content ; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * Set multiple channel elements from an array. Array elements | ||
70 | * should be 'channelName' => 'channelContent' format. | ||
71 | * | ||
72 | * @access public | ||
73 | * @param array array of channels | ||
74 | * @return void | ||
75 | */ | ||
76 | public function setChannelElementsFromArray($elementArray) | ||
77 | { | ||
78 | if(! is_array($elementArray)) return; | ||
79 | foreach ($elementArray as $elementName => $content) | ||
80 | { | ||
81 | $this->setChannelElement($elementName, $content); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * Genarate the actual RSS/JSON file | ||
87 | * | ||
88 | * @access public | ||
89 | * @return void | ||
90 | */ | ||
91 | public function genarateFeed($withHeaders = true) | ||
92 | { | ||
93 | if ($withHeaders) { | ||
94 | if ($this->version == RSS2) { | ||
95 | header('Content-type: text/xml; charset=UTF-8'); | ||
96 | // this line prevents Chrome 20 from prompting download | ||
97 | // used by Google: https://news.google.com/news/feeds?ned=us&topic=b&output=rss | ||
98 | header('X-content-type-options: nosniff'); | ||
99 | } elseif ($this->version == JSON) { | ||
100 | header('Content-type: application/json; charset=UTF-8'); | ||
101 | } elseif ($this->version == JSONP) { | ||
102 | header('Content-type: application/javascript; charset=UTF-8'); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | if ($this->version == JSON || $this->version == JSONP) { | ||
107 | $this->json = new stdClass(); | ||
108 | } | ||
109 | |||
110 | |||
111 | $this->printHead(); | ||
112 | $this->printChannels(); | ||
113 | $this->printItems(); | ||
114 | $this->printTale(); | ||
115 | if ($this->version == JSON || $this->version == JSONP) { | ||
116 | echo json_encode($this->json); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | public function &getItems() | ||
121 | { | ||
122 | return $this->items; | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * Create a new FeedItem. | ||
127 | * | ||
128 | * @access public | ||
129 | * @return object instance of FeedItem class | ||
130 | */ | ||
131 | public function createNewItem() | ||
132 | { | ||
133 | $Item = new FeedItem($this->version); | ||
134 | return $Item; | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * Add a FeedItem to the main class | ||
139 | * | ||
140 | * @access public | ||
141 | * @param object instance of FeedItem class | ||
142 | * @return void | ||
143 | */ | ||
144 | public function addItem($feedItem) | ||
145 | { | ||
146 | $this->items[] = $feedItem; | ||
147 | } | ||
148 | |||
149 | // Wrapper functions ------------------------------------------------------------------- | ||
150 | |||
151 | /** | ||
152 | * Set the 'title' channel element | ||
153 | * | ||
154 | * @access public | ||
155 | * @param srting value of 'title' channel tag | ||
156 | * @return void | ||
157 | */ | ||
158 | public function setTitle($title) | ||
159 | { | ||
160 | $this->setChannelElement('title', $title); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Add a hub to the channel element | ||
165 | * | ||
166 | * @access public | ||
167 | * @param string URL | ||
168 | * @return void | ||
169 | */ | ||
170 | public function addHub($hub) | ||
171 | { | ||
172 | $this->hubs[] = $hub; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * Set XSL URL | ||
177 | * | ||
178 | * @access public | ||
179 | * @param string URL | ||
180 | * @return void | ||
181 | */ | ||
182 | public function setXsl($xsl) | ||
183 | { | ||
184 | $this->xsl = $xsl; | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Set self URL | ||
189 | * | ||
190 | * @access public | ||
191 | * @param string URL | ||
192 | * @return void | ||
193 | */ | ||
194 | public function setSelf($self) | ||
195 | { | ||
196 | $this->self = $self; | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * Set the 'description' channel element | ||
201 | * | ||
202 | * @access public | ||
203 | * @param srting value of 'description' channel tag | ||
204 | * @return void | ||
205 | */ | ||
206 | public function setDescription($description) | ||
207 | { | ||
208 | $tag = ($this->version == ATOM)? 'subtitle' : 'description'; | ||
209 | $this->setChannelElement($tag, $description); | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * Set the 'link' channel element | ||
214 | * | ||
215 | * @access public | ||
216 | * @param srting value of 'link' channel tag | ||
217 | * @return void | ||
218 | */ | ||
219 | public function setLink($link) | ||
220 | { | ||
221 | $this->setChannelElement('link', $link); | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * Set the 'image' channel element | ||
226 | * | ||
227 | * @access public | ||
228 | * @param srting title of image | ||
229 | * @param srting link url of the imahe | ||
230 | * @param srting path url of the image | ||
231 | * @return void | ||
232 | */ | ||
233 | public function setImage($title, $link, $url) | ||
234 | { | ||
235 | $this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url)); | ||
236 | } | ||
237 | |||
238 | // End # public functions ---------------------------------------------- | ||
239 | |||
240 | // Start # private functions ---------------------------------------------- | ||
241 | |||
242 | /** | ||
243 | * Prints the xml and rss namespace | ||
244 | * | ||
245 | * @access private | ||
246 | * @return void | ||
247 | */ | ||
248 | private function printHead() | ||
249 | { | ||
250 | if ($this->version == RSS2) | ||
251 | { | ||
252 | $out = '<?xml version="1.0" encoding="utf-8"?>'."\n"; | ||
253 | if ($this->xsl) $out .= '<?xml-stylesheet type="text/xsl" href="'.htmlspecialchars($this->xsl).'"?>' . PHP_EOL; | ||
254 | $out .= '<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">' . PHP_EOL; | ||
255 | echo $out; | ||
256 | } | ||
257 | elseif ($this->version == JSON || $this->version == JSONP) | ||
258 | { | ||
259 | $this->json->rss = array('@attributes' => array('version' => '2.0')); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | /** | ||
264 | * Closes the open tags at the end of file | ||
265 | * | ||
266 | * @access private | ||
267 | * @return void | ||
268 | */ | ||
269 | private function printTale() | ||
270 | { | ||
271 | if ($this->version == RSS2) | ||
272 | { | ||
273 | echo '</channel>',PHP_EOL,'</rss>'; | ||
274 | } | ||
275 | // do nothing for JSON | ||
276 | } | ||
277 | |||
278 | /** | ||
279 | * Creates a single node as xml format | ||
280 | * | ||
281 | * @access private | ||
282 | * @param string name of the tag | ||
283 | * @param mixed tag value as string or array of nested tags in 'tagName' => 'tagValue' format | ||
284 | * @param array Attributes(if any) in 'attrName' => 'attrValue' format | ||
285 | * @return string formatted xml tag | ||
286 | */ | ||
287 | private function makeNode($tagName, $tagContent, $attributes = null) | ||
288 | { | ||
289 | if ($this->version == RSS2) | ||
290 | { | ||
291 | $nodeText = ''; | ||
292 | $attrText = ''; | ||
293 | if (is_array($attributes)) | ||
294 | { | ||
295 | foreach ($attributes as $key => $value) | ||
296 | { | ||
297 | $attrText .= " $key=\"$value\" "; | ||
298 | } | ||
299 | } | ||
300 | $nodeText .= "<{$tagName}{$attrText}>"; | ||
301 | if (is_array($tagContent)) | ||
302 | { | ||
303 | foreach ($tagContent as $key => $value) | ||
304 | { | ||
305 | $nodeText .= $this->makeNode($key, $value); | ||
306 | } | ||
307 | } | ||
308 | else | ||
309 | { | ||
310 | //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent); | ||
311 | $nodeText .= htmlspecialchars($tagContent); | ||
312 | } | ||
313 | //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>"; | ||
314 | $nodeText .= "</$tagName>"; | ||
315 | return $nodeText . PHP_EOL; | ||
316 | } | ||
317 | elseif ($this->version == JSON || $this->version == JSONP) | ||
318 | { | ||
319 | $tagName = (string)$tagName; | ||
320 | $tagName = strtr($tagName, ':', '_'); | ||
321 | $node = null; | ||
322 | if (!$tagContent && is_array($attributes) && count($attributes)) | ||
323 | { | ||
324 | $node = array('@attributes' => $this->json_keys($attributes)); | ||
325 | } else { | ||
326 | if (is_array($tagContent)) { | ||
327 | $node = $this->json_keys($tagContent); | ||
328 | } else { | ||
329 | $node = $tagContent; | ||
330 | } | ||
331 | } | ||
332 | return $node; | ||
333 | } | ||
334 | return ''; // should not get here | ||
335 | } | ||
336 | |||
337 | private function json_keys(array $array) { | ||
338 | $new = array(); | ||
339 | foreach ($array as $key => $val) { | ||
340 | if (is_string($key)) $key = strtr($key, ':', '_'); | ||
341 | if (is_array($val)) { | ||
342 | $new[$key] = $this->json_keys($val); | ||
343 | } else { | ||
344 | $new[$key] = $val; | ||
345 | } | ||
346 | } | ||
347 | return $new; | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * @desc Print channels | ||
352 | * @access private | ||
353 | * @return void | ||
354 | */ | ||
355 | private function printChannels() | ||
356 | { | ||
357 | //Start channel tag | ||
358 | if ($this->version == RSS2) { | ||
359 | echo '<channel>' . PHP_EOL; | ||
360 | // add hubs | ||
361 | foreach ($this->hubs as $hub) { | ||
362 | //echo $this->makeNode('link', '', array('rel'=>'hub', 'href'=>$hub, 'xmlns'=>'http://www.w3.org/2005/Atom')); | ||
363 | echo '<link rel="hub" href="'.htmlspecialchars($hub).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL; | ||
364 | } | ||
365 | // add self | ||
366 | if (isset($this->self)) { | ||
367 | //echo $this->makeNode('link', '', array('rel'=>'self', 'href'=>$this->self, 'xmlns'=>'http://www.w3.org/2005/Atom')); | ||
368 | echo '<link rel="self" href="'.htmlspecialchars($this->self).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL; | ||
369 | } | ||
370 | //Print Items of channel | ||
371 | foreach ($this->channels as $key => $value) | ||
372 | { | ||
373 | echo $this->makeNode($key, $value); | ||
374 | } | ||
375 | } elseif ($this->version == JSON || $this->version == JSONP) { | ||
376 | $this->json->rss['channel'] = (object)$this->json_keys($this->channels); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | /** | ||
381 | * Prints formatted feed items | ||
382 | * | ||
383 | * @access private | ||
384 | * @return void | ||
385 | */ | ||
386 | private function printItems() | ||
387 | { | ||
388 | foreach ($this->items as $item) { | ||
389 | $itemElements = $item->getElements(); | ||
390 | |||
391 | echo $this->startItem(); | ||
392 | |||
393 | if ($this->version == JSON || $this->version == JSONP) { | ||
394 | $json_item = array(); | ||
395 | } | ||
396 | |||
397 | foreach ($itemElements as $thisElement) { | ||
398 | foreach ($thisElement as $instance) { | ||
399 | if ($this->version == RSS2) { | ||
400 | echo $this->makeNode($instance['name'], $instance['content'], $instance['attributes']); | ||
401 | } elseif ($this->version == JSON || $this->version == JSONP) { | ||
402 | $_json_node = $this->makeNode($instance['name'], $instance['content'], $instance['attributes']); | ||
403 | if (count($thisElement) > 1) { | ||
404 | $json_item[strtr($instance['name'], ':', '_')][] = $_json_node; | ||
405 | } else { | ||
406 | $json_item[strtr($instance['name'], ':', '_')] = $_json_node; | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | echo $this->endItem(); | ||
412 | if ($this->version == JSON || $this->version == JSONP) { | ||
413 | if (count($this->items) > 1) { | ||
414 | $this->json->rss['channel']->item[] = $json_item; | ||
415 | } else { | ||
416 | $this->json->rss['channel']->item = $json_item; | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * Make the starting tag of channels | ||
424 | * | ||
425 | * @access private | ||
426 | * @return void | ||
427 | */ | ||
428 | private function startItem() | ||
429 | { | ||
430 | if ($this->version == RSS2) | ||
431 | { | ||
432 | echo '<item>' . PHP_EOL; | ||
433 | } | ||
434 | // nothing for JSON | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * Closes feed item tag | ||
439 | * | ||
440 | * @access private | ||
441 | * @return void | ||
442 | */ | ||
443 | private function endItem() | ||
444 | { | ||
445 | if ($this->version == RSS2) | ||
446 | { | ||
447 | echo '</item>' . PHP_EOL; | ||
448 | } | ||
449 | // nothing for JSON | ||
450 | } | ||
451 | |||
452 | // End # private functions ---------------------------------------------- | ||
453 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/html5/Data.php b/inc/3rdparty/libraries/html5/Data.php deleted file mode 100644 index 497345f4..00000000 --- a/inc/3rdparty/libraries/html5/Data.php +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | // warning: this file is encoded in UTF-8! | ||
4 | |||
5 | class HTML5_Data | ||
6 | { | ||
7 | |||
8 | // at some point this should be moved to a .ser file. Another | ||
9 | // possible optimization is to give UTF-8 bytes, not Unicode | ||
10 | // codepoints | ||
11 | // XXX: Not quite sure why it's named this; this is | ||
12 | // actually the numeric entity dereference table. | ||
13 | protected static $realCodepointTable = array( | ||
14 | 0x00 => 0xFFFD, // REPLACEMENT CHARACTER | ||
15 | 0x0D => 0x000A, // LINE FEED (LF) | ||
16 | 0x80 => 0x20AC, // EURO SIGN ('€') | ||
17 | 0x81 => 0x0081, // <control> | ||
18 | 0x82 => 0x201A, // SINGLE LOW-9 QUOTATION MARK ('‚') | ||
19 | 0x83 => 0x0192, // LATIN SMALL LETTER F WITH HOOK ('ƒ') | ||
20 | 0x84 => 0x201E, // DOUBLE LOW-9 QUOTATION MARK ('„') | ||
21 | 0x85 => 0x2026, // HORIZONTAL ELLIPSIS ('…') | ||
22 | 0x86 => 0x2020, // DAGGER ('†') | ||
23 | 0x87 => 0x2021, // DOUBLE DAGGER ('‡') | ||
24 | 0x88 => 0x02C6, // MODIFIER LETTER CIRCUMFLEX ACCENT ('ˆ') | ||
25 | 0x89 => 0x2030, // PER MILLE SIGN ('‰') | ||
26 | 0x8A => 0x0160, // LATIN CAPITAL LETTER S WITH CARON ('Š') | ||
27 | 0x8B => 0x2039, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK ('‹') | ||
28 | 0x8C => 0x0152, // LATIN CAPITAL LIGATURE OE ('Œ') | ||
29 | 0x8D => 0x008D, // <control> | ||
30 | 0x8E => 0x017D, // LATIN CAPITAL LETTER Z WITH CARON ('Ž') | ||
31 | 0x8F => 0x008F, // <control> | ||
32 | 0x90 => 0x0090, // <control> | ||
33 | 0x91 => 0x2018, // LEFT SINGLE QUOTATION MARK ('‘') | ||
34 | 0x92 => 0x2019, // RIGHT SINGLE QUOTATION MARK ('’') | ||
35 | 0x93 => 0x201C, // LEFT DOUBLE QUOTATION MARK ('“') | ||
36 | 0x94 => 0x201D, // RIGHT DOUBLE QUOTATION MARK ('”') | ||
37 | 0x95 => 0x2022, // BULLET ('•') | ||
38 | 0x96 => 0x2013, // EN DASH ('–') | ||
39 | 0x97 => 0x2014, // EM DASH ('—') | ||
40 | 0x98 => 0x02DC, // SMALL TILDE ('˜') | ||
41 | 0x99 => 0x2122, // TRADE MARK SIGN ('™') | ||
42 | 0x9A => 0x0161, // LATIN SMALL LETTER S WITH CARON ('š') | ||
43 | 0x9B => 0x203A, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK ('›') | ||
44 | 0x9C => 0x0153, // LATIN SMALL LIGATURE OE ('œ') | ||
45 | 0x9D => 0x009D, // <control> | ||
46 | 0x9E => 0x017E, // LATIN SMALL LETTER Z WITH CARON ('ž') | ||
47 | 0x9F => 0x0178, // LATIN CAPITAL LETTER Y WITH DIAERESIS ('Ÿ') | ||
48 | ); | ||
49 | |||
50 | protected static $namedCharacterReferences; | ||
51 | |||
52 | protected static $namedCharacterReferenceMaxLength; | ||
53 | |||
54 | /** | ||
55 | * Returns the "real" Unicode codepoint of a malformed character | ||
56 | * reference. | ||
57 | */ | ||
58 | public static function getRealCodepoint($ref) { | ||
59 | if (!isset(self::$realCodepointTable[$ref])) return false; | ||
60 | else return self::$realCodepointTable[$ref]; | ||
61 | } | ||
62 | |||
63 | public static function getNamedCharacterReferences() { | ||
64 | if (!self::$namedCharacterReferences) { | ||
65 | self::$namedCharacterReferences = unserialize( | ||
66 | file_get_contents(dirname(__FILE__) . '/named-character-references.ser')); | ||
67 | } | ||
68 | return self::$namedCharacterReferences; | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * Converts a Unicode codepoint to sequence of UTF-8 bytes. | ||
73 | * @note Shamelessly stolen from HTML Purifier, which is also | ||
74 | * shamelessly stolen from Feyd (which is in public domain). | ||
75 | */ | ||
76 | public static function utf8chr($code) { | ||
77 | /* We don't care: we live dangerously | ||
78 | * if($code > 0x10FFFF or $code < 0x0 or | ||
79 | ($code >= 0xD800 and $code <= 0xDFFF) ) { | ||
80 | // bits are set outside the "valid" range as defined | ||
81 | // by UNICODE 4.1.0 | ||
82 | return "\xEF\xBF\xBD"; | ||
83 | }*/ | ||
84 | |||
85 | $x = $y = $z = $w = 0; | ||
86 | if ($code < 0x80) { | ||
87 | // regular ASCII character | ||
88 | $x = $code; | ||
89 | } else { | ||
90 | // set up bits for UTF-8 | ||
91 | $x = ($code & 0x3F) | 0x80; | ||
92 | if ($code < 0x800) { | ||
93 | $y = (($code & 0x7FF) >> 6) | 0xC0; | ||
94 | } else { | ||
95 | $y = (($code & 0xFC0) >> 6) | 0x80; | ||
96 | if($code < 0x10000) { | ||
97 | $z = (($code >> 12) & 0x0F) | 0xE0; | ||
98 | } else { | ||
99 | $z = (($code >> 12) & 0x3F) | 0x80; | ||
100 | $w = (($code >> 18) & 0x07) | 0xF0; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | // set up the actual character | ||
105 | $ret = ''; | ||
106 | if($w) $ret .= chr($w); | ||
107 | if($z) $ret .= chr($z); | ||
108 | if($y) $ret .= chr($y); | ||
109 | $ret .= chr($x); | ||
110 | |||
111 | return $ret; | ||
112 | } | ||
113 | |||
114 | } | ||
diff --git a/inc/3rdparty/libraries/html5/InputStream.php b/inc/3rdparty/libraries/html5/InputStream.php deleted file mode 100644 index f98b4272..00000000 --- a/inc/3rdparty/libraries/html5/InputStream.php +++ /dev/null | |||
@@ -1,284 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | |||
5 | Copyright 2009 Geoffrey Sneddon <http://gsnedders.com/> | ||
6 | |||
7 | Permission is hereby granted, free of charge, to any person obtaining a | ||
8 | copy of this software and associated documentation files (the | ||
9 | "Software"), to deal in the Software without restriction, including | ||
10 | without limitation the rights to use, copy, modify, merge, publish, | ||
11 | distribute, sublicense, and/or sell copies of the Software, and to | ||
12 | permit persons to whom the Software is furnished to do so, subject to | ||
13 | the following conditions: | ||
14 | |||
15 | The above copyright notice and this permission notice shall be included | ||
16 | in all copies or substantial portions of the Software. | ||
17 | |||
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
19 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
25 | |||
26 | */ | ||
27 | |||
28 | // Some conventions: | ||
29 | // /* */ indicates verbatim text from the HTML 5 specification | ||
30 | // // indicates regular comments | ||
31 | |||
32 | class HTML5_InputStream { | ||
33 | /** | ||
34 | * The string data we're parsing. | ||
35 | */ | ||
36 | private $data; | ||
37 | |||
38 | /** | ||
39 | * The current integer byte position we are in $data | ||
40 | */ | ||
41 | private $char; | ||
42 | |||
43 | /** | ||
44 | * Length of $data; when $char === $data, we are at the end-of-file. | ||
45 | */ | ||
46 | private $EOF; | ||
47 | |||
48 | /** | ||
49 | * Parse errors. | ||
50 | */ | ||
51 | public $errors = array(); | ||
52 | |||
53 | /** | ||
54 | * @param $data Data to parse | ||
55 | */ | ||
56 | public function __construct($data) { | ||
57 | |||
58 | /* Given an encoding, the bytes in the input stream must be | ||
59 | converted to Unicode characters for the tokeniser, as | ||
60 | described by the rules for that encoding, except that the | ||
61 | leading U+FEFF BYTE ORDER MARK character, if any, must not | ||
62 | be stripped by the encoding layer (it is stripped by the rule below). | ||
63 | |||
64 | Bytes or sequences of bytes in the original byte stream that | ||
65 | could not be converted to Unicode characters must be converted | ||
66 | to U+FFFD REPLACEMENT CHARACTER code points. */ | ||
67 | |||
68 | // XXX currently assuming input data is UTF-8; once we | ||
69 | // build encoding detection this will no longer be the case | ||
70 | // | ||
71 | // We previously had an mbstring implementation here, but that | ||
72 | // implementation is heavily non-conforming, so it's been | ||
73 | // omitted. | ||
74 | if (extension_loaded('iconv')) { | ||
75 | // non-conforming | ||
76 | $data = @iconv('UTF-8', 'UTF-8//IGNORE', $data); | ||
77 | } else { | ||
78 | // we can make a conforming native implementation | ||
79 | throw new Exception('Not implemented, please install mbstring or iconv'); | ||
80 | } | ||
81 | |||
82 | /* One leading U+FEFF BYTE ORDER MARK character must be | ||
83 | ignored if any are present. */ | ||
84 | if (substr($data, 0, 3) === "\xEF\xBB\xBF") { | ||
85 | $data = substr($data, 3); | ||
86 | } | ||
87 | |||
88 | /* All U+0000 NULL characters in the input must be replaced | ||
89 | by U+FFFD REPLACEMENT CHARACTERs. Any occurrences of such | ||
90 | characters is a parse error. */ | ||
91 | for ($i = 0, $count = substr_count($data, "\0"); $i < $count; $i++) { | ||
92 | $this->errors[] = array( | ||
93 | 'type' => HTML5_Tokenizer::PARSEERROR, | ||
94 | 'data' => 'null-character' | ||
95 | ); | ||
96 | } | ||
97 | /* U+000D CARRIAGE RETURN (CR) characters and U+000A LINE FEED | ||
98 | (LF) characters are treated specially. Any CR characters | ||
99 | that are followed by LF characters must be removed, and any | ||
100 | CR characters not followed by LF characters must be converted | ||
101 | to LF characters. Thus, newlines in HTML DOMs are represented | ||
102 | by LF characters, and there are never any CR characters in the | ||
103 | input to the tokenization stage. */ | ||
104 | $data = str_replace( | ||
105 | array( | ||
106 | "\0", | ||
107 | "\r\n", | ||
108 | "\r" | ||
109 | ), | ||
110 | array( | ||
111 | "\xEF\xBF\xBD", | ||
112 | "\n", | ||
113 | "\n" | ||
114 | ), | ||
115 | $data | ||
116 | ); | ||
117 | |||
118 | /* Any occurrences of any characters in the ranges U+0001 to | ||
119 | U+0008, U+000B, U+000E to U+001F, U+007F to U+009F, | ||
120 | U+D800 to U+DFFF , U+FDD0 to U+FDEF, and | ||
121 | characters U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, | ||
122 | U+3FFFE, U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, | ||
123 | U+6FFFF, U+7FFFE, U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, | ||
124 | U+AFFFE, U+AFFFF, U+BFFFE, U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, | ||
125 | U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, U+FFFFF, U+10FFFE, and | ||
126 | U+10FFFF are parse errors. (These are all control characters | ||
127 | or permanently undefined Unicode characters.) */ | ||
128 | // Check PCRE is loaded. | ||
129 | if (extension_loaded('pcre')) { | ||
130 | $count = preg_match_all( | ||
131 | '/(?: | ||
132 | [\x01-\x08\x0B\x0E-\x1F\x7F] # U+0001 to U+0008, U+000B, U+000E to U+001F and U+007F | ||
133 | | | ||
134 | \xC2[\x80-\x9F] # U+0080 to U+009F | ||
135 | | | ||
136 | \xED(?:\xA0[\x80-\xFF]|[\xA1-\xBE][\x00-\xFF]|\xBF[\x00-\xBF]) # U+D800 to U+DFFFF | ||
137 | | | ||
138 | \xEF\xB7[\x90-\xAF] # U+FDD0 to U+FDEF | ||
139 | | | ||
140 | \xEF\xBF[\xBE\xBF] # U+FFFE and U+FFFF | ||
141 | | | ||
142 | [\xF0-\xF4][\x8F-\xBF]\xBF[\xBE\xBF] # U+nFFFE and U+nFFFF (1 <= n <= 10_{16}) | ||
143 | )/x', | ||
144 | $data, | ||
145 | $matches | ||
146 | ); | ||
147 | for ($i = 0; $i < $count; $i++) { | ||
148 | $this->errors[] = array( | ||
149 | 'type' => HTML5_Tokenizer::PARSEERROR, | ||
150 | 'data' => 'invalid-codepoint' | ||
151 | ); | ||
152 | } | ||
153 | } else { | ||
154 | // XXX: Need non-PCRE impl, probably using substr_count | ||
155 | } | ||
156 | |||
157 | $this->data = $data; | ||
158 | $this->char = 0; | ||
159 | $this->EOF = strlen($data); | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * Returns the current line that the tokenizer is at. | ||
164 | */ | ||
165 | public function getCurrentLine() { | ||
166 | // Check the string isn't empty | ||
167 | if($this->EOF) { | ||
168 | // Add one to $this->char because we want the number for the next | ||
169 | // byte to be processed. | ||
170 | return substr_count($this->data, "\n", 0, min($this->char, $this->EOF)) + 1; | ||
171 | } else { | ||
172 | // If the string is empty, we are on the first line (sorta). | ||
173 | return 1; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * Returns the current column of the current line that the tokenizer is at. | ||
179 | */ | ||
180 | public function getColumnOffset() { | ||
181 | // strrpos is weird, and the offset needs to be negative for what we | ||
182 | // want (i.e., the last \n before $this->char). This needs to not have | ||
183 | // one (to make it point to the next character, the one we want the | ||
184 | // position of) added to it because strrpos's behaviour includes the | ||
185 | // final offset byte. | ||
186 | $lastLine = strrpos($this->data, "\n", $this->char - 1 - strlen($this->data)); | ||
187 | |||
188 | // However, for here we want the length up until the next byte to be | ||
189 | // processed, so add one to the current byte ($this->char). | ||
190 | if($lastLine !== false) { | ||
191 | $findLengthOf = substr($this->data, $lastLine + 1, $this->char - 1 - $lastLine); | ||
192 | } else { | ||
193 | $findLengthOf = substr($this->data, 0, $this->char); | ||
194 | } | ||
195 | |||
196 | // Get the length for the string we need. | ||
197 | if(extension_loaded('iconv')) { | ||
198 | return iconv_strlen($findLengthOf, 'utf-8'); | ||
199 | } elseif(extension_loaded('mbstring')) { | ||
200 | return mb_strlen($findLengthOf, 'utf-8'); | ||
201 | } elseif(extension_loaded('xml')) { | ||
202 | return strlen(utf8_decode($findLengthOf)); | ||
203 | } else { | ||
204 | $count = count_chars($findLengthOf); | ||
205 | // 0x80 = 0x7F - 0 + 1 (one added to get inclusive range) | ||
206 | // 0x33 = 0xF4 - 0x2C + 1 (one added to get inclusive range) | ||
207 | return array_sum(array_slice($count, 0, 0x80)) + | ||
208 | array_sum(array_slice($count, 0xC2, 0x33)); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * Retrieve the currently consume character. | ||
214 | * @note This performs bounds checking | ||
215 | */ | ||
216 | public function char() { | ||
217 | return ($this->char++ < $this->EOF) | ||
218 | ? $this->data[$this->char - 1] | ||
219 | : false; | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * Get all characters until EOF. | ||
224 | * @note This performs bounds checking | ||
225 | */ | ||
226 | public function remainingChars() { | ||
227 | if($this->char < $this->EOF) { | ||
228 | $data = substr($this->data, $this->char); | ||
229 | $this->char = $this->EOF; | ||
230 | return $data; | ||
231 | } else { | ||
232 | return false; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * Matches as far as possible until we reach a certain set of bytes | ||
238 | * and returns the matched substring. | ||
239 | * @param $bytes Bytes to match. | ||
240 | */ | ||
241 | public function charsUntil($bytes, $max = null) { | ||
242 | if ($this->char < $this->EOF) { | ||
243 | if ($max === 0 || $max) { | ||
244 | $len = strcspn($this->data, $bytes, $this->char, $max); | ||
245 | } else { | ||
246 | $len = strcspn($this->data, $bytes, $this->char); | ||
247 | } | ||
248 | $string = (string) substr($this->data, $this->char, $len); | ||
249 | $this->char += $len; | ||
250 | return $string; | ||
251 | } else { | ||
252 | return false; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * Matches as far as possible with a certain set of bytes | ||
258 | * and returns the matched substring. | ||
259 | * @param $bytes Bytes to match. | ||
260 | */ | ||
261 | public function charsWhile($bytes, $max = null) { | ||
262 | if ($this->char < $this->EOF) { | ||
263 | if ($max === 0 || $max) { | ||
264 | $len = strspn($this->data, $bytes, $this->char, $max); | ||
265 | } else { | ||
266 | $len = strspn($this->data, $bytes, $this->char); | ||
267 | } | ||
268 | $string = (string) substr($this->data, $this->char, $len); | ||
269 | $this->char += $len; | ||
270 | return $string; | ||
271 | } else { | ||
272 | return false; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * Unconsume one character. | ||
278 | */ | ||
279 | public function unget() { | ||
280 | if ($this->char <= $this->EOF) { | ||
281 | $this->char--; | ||
282 | } | ||
283 | } | ||
284 | } | ||
diff --git a/inc/3rdparty/libraries/html5/Parser.php b/inc/3rdparty/libraries/html5/Parser.php deleted file mode 100644 index 5f9ca560..00000000 --- a/inc/3rdparty/libraries/html5/Parser.php +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | require_once dirname(__FILE__) . '/Data.php'; | ||
4 | require_once dirname(__FILE__) . '/InputStream.php'; | ||
5 | require_once dirname(__FILE__) . '/TreeBuilder.php'; | ||
6 | require_once dirname(__FILE__) . '/Tokenizer.php'; | ||
7 | |||
8 | /** | ||
9 | * Outwards facing interface for HTML5. | ||
10 | */ | ||
11 | class HTML5_Parser | ||
12 | { | ||
13 | /** | ||
14 | * Parses a full HTML document. | ||
15 | * @param $text HTML text to parse | ||
16 | * @param $builder Custom builder implementation | ||
17 | * @return Parsed HTML as DOMDocument | ||
18 | */ | ||
19 | static public function parse($text, $builder = null) { | ||
20 | $tokenizer = new HTML5_Tokenizer($text, $builder); | ||
21 | $tokenizer->parse(); | ||
22 | return $tokenizer->save(); | ||
23 | } | ||
24 | /** | ||
25 | * Parses an HTML fragment. | ||
26 | * @param $text HTML text to parse | ||
27 | * @param $context String name of context element to pretend parsing is in. | ||
28 | * @param $builder Custom builder implementation | ||
29 | * @return Parsed HTML as DOMDocument | ||
30 | */ | ||
31 | static public function parseFragment($text, $context = null, $builder = null) { | ||
32 | $tokenizer = new HTML5_Tokenizer($text, $builder); | ||
33 | $tokenizer->parseFragment($context); | ||
34 | return $tokenizer->save(); | ||
35 | } | ||
36 | } | ||
diff --git a/inc/3rdparty/libraries/html5/Tokenizer.php b/inc/3rdparty/libraries/html5/Tokenizer.php deleted file mode 100644 index 0af07164..00000000 --- a/inc/3rdparty/libraries/html5/Tokenizer.php +++ /dev/null | |||
@@ -1,2422 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | |||
5 | Copyright 2007 Jeroen van der Meer <http://jero.net/> | ||
6 | Copyright 2008 Edward Z. Yang <http://htmlpurifier.org/> | ||
7 | Copyright 2009 Geoffrey Sneddon <http://gsnedders.com/> | ||
8 | |||
9 | Permission is hereby granted, free of charge, to any person obtaining a | ||
10 | copy of this software and associated documentation files (the | ||
11 | "Software"), to deal in the Software without restriction, including | ||
12 | without limitation the rights to use, copy, modify, merge, publish, | ||
13 | distribute, sublicense, and/or sell copies of the Software, and to | ||
14 | permit persons to whom the Software is furnished to do so, subject to | ||
15 | the following conditions: | ||
16 | |||
17 | The above copyright notice and this permission notice shall be included | ||
18 | in all copies or substantial portions of the Software. | ||
19 | |||
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
21 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
27 | |||
28 | */ | ||
29 | |||
30 | // Some conventions: | ||
31 | // /* */ indicates verbatim text from the HTML 5 specification | ||
32 | // // indicates regular comments | ||
33 | |||
34 | // all flags are in hyphenated form | ||
35 | |||
36 | class HTML5_Tokenizer { | ||
37 | /** | ||
38 | * Points to an InputStream object. | ||
39 | */ | ||
40 | protected $stream; | ||
41 | |||
42 | /** | ||
43 | * Tree builder that the tokenizer emits token to. | ||
44 | */ | ||
45 | private $tree; | ||
46 | |||
47 | /** | ||
48 | * Current content model we are parsing as. | ||
49 | */ | ||
50 | protected $content_model; | ||
51 | |||
52 | /** | ||
53 | * Current token that is being built, but not yet emitted. Also | ||
54 | * is the last token emitted, if applicable. | ||
55 | */ | ||
56 | protected $token; | ||
57 | |||
58 | // These are constants describing the content model | ||
59 | const PCDATA = 0; | ||
60 | const RCDATA = 1; | ||
61 | const CDATA = 2; | ||
62 | const PLAINTEXT = 3; | ||
63 | |||
64 | // These are constants describing tokens | ||
65 | // XXX should probably be moved somewhere else, probably the | ||
66 | // HTML5 class. | ||
67 | const DOCTYPE = 0; | ||
68 | const STARTTAG = 1; | ||
69 | const ENDTAG = 2; | ||
70 | const COMMENT = 3; | ||
71 | const CHARACTER = 4; | ||
72 | const SPACECHARACTER = 5; | ||
73 | const EOF = 6; | ||
74 | const PARSEERROR = 7; | ||
75 | |||
76 | // These are constants representing bunches of characters. | ||
77 | const ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; | ||
78 | const UPPER_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; | ||
79 | const LOWER_ALPHA = 'abcdefghijklmnopqrstuvwxyz'; | ||
80 | const DIGIT = '0123456789'; | ||
81 | const HEX = '0123456789ABCDEFabcdef'; | ||
82 | const WHITESPACE = "\t\n\x0c "; | ||
83 | |||
84 | /** | ||
85 | * @param $data Data to parse | ||
86 | */ | ||
87 | public function __construct($data, $builder = null) { | ||
88 | $this->stream = new HTML5_InputStream($data); | ||
89 | if (!$builder) $this->tree = new HTML5_TreeBuilder; | ||
90 | else $this->tree = $builder; | ||
91 | $this->content_model = self::PCDATA; | ||
92 | } | ||
93 | |||
94 | public function parseFragment($context = null) { | ||
95 | $this->tree->setupContext($context); | ||
96 | if ($this->tree->content_model) { | ||
97 | $this->content_model = $this->tree->content_model; | ||
98 | $this->tree->content_model = null; | ||
99 | } | ||
100 | $this->parse(); | ||
101 | } | ||
102 | |||
103 | // XXX maybe convert this into an iterator? regardless, this function | ||
104 | // and the save function should go into a Parser facade of some sort | ||
105 | /** | ||
106 | * Performs the actual parsing of the document. | ||
107 | */ | ||
108 | public function parse() { | ||
109 | // Current state | ||
110 | $state = 'data'; | ||
111 | // This is used to avoid having to have look-behind in the data state. | ||
112 | $lastFourChars = ''; | ||
113 | /** | ||
114 | * Escape flag as specified by the HTML5 specification: "used to | ||
115 | * control the behavior of the tokeniser. It is either true or | ||
116 | * false, and initially must be set to the false state." | ||
117 | */ | ||
118 | $escape = false; | ||
119 | //echo "\n\n"; | ||
120 | while($state !== null) { | ||
121 | |||
122 | /*echo $state . ' '; | ||
123 | switch ($this->content_model) { | ||
124 | case self::PCDATA: echo 'PCDATA'; break; | ||
125 | case self::RCDATA: echo 'RCDATA'; break; | ||
126 | case self::CDATA: echo 'CDATA'; break; | ||
127 | case self::PLAINTEXT: echo 'PLAINTEXT'; break; | ||
128 | } | ||
129 | if ($escape) echo " escape"; | ||
130 | echo "\n";*/ | ||
131 | |||
132 | switch($state) { | ||
133 | case 'data': | ||
134 | |||
135 | /* Consume the next input character */ | ||
136 | $char = $this->stream->char(); | ||
137 | $lastFourChars .= $char; | ||
138 | if (strlen($lastFourChars) > 4) $lastFourChars = substr($lastFourChars, -4); | ||
139 | |||
140 | // see below for meaning | ||
141 | $hyp_cond = | ||
142 | !$escape && | ||
143 | ( | ||
144 | $this->content_model === self::RCDATA || | ||
145 | $this->content_model === self::CDATA | ||
146 | ); | ||
147 | $amp_cond = | ||
148 | !$escape && | ||
149 | ( | ||
150 | $this->content_model === self::PCDATA || | ||
151 | $this->content_model === self::RCDATA | ||
152 | ); | ||
153 | $lt_cond = | ||
154 | $this->content_model === self::PCDATA || | ||
155 | ( | ||
156 | ( | ||
157 | $this->content_model === self::RCDATA || | ||
158 | $this->content_model === self::CDATA | ||
159 | ) && | ||
160 | !$escape | ||
161 | ); | ||
162 | $gt_cond = | ||
163 | $escape && | ||
164 | ( | ||
165 | $this->content_model === self::RCDATA || | ||
166 | $this->content_model === self::CDATA | ||
167 | ); | ||
168 | |||
169 | if($char === '&' && $amp_cond) { | ||
170 | /* U+0026 AMPERSAND (&) | ||
171 | When the content model flag is set to one of the PCDATA or RCDATA | ||
172 | states and the escape flag is false: switch to the | ||
173 | character reference data state. Otherwise: treat it as per | ||
174 | the "anything else" entry below. */ | ||
175 | $state = 'character reference data'; | ||
176 | |||
177 | } elseif( | ||
178 | $char === '-' && | ||
179 | $hyp_cond && | ||
180 | $lastFourChars === '<!--' | ||
181 | ) { | ||
182 | /* | ||
183 | U+002D HYPHEN-MINUS (-) | ||
184 | If the content model flag is set to either the RCDATA state or | ||
185 | the CDATA state, and the escape flag is false, and there are at | ||
186 | least three characters before this one in the input stream, and the | ||
187 | last four characters in the input stream, including this one, are | ||
188 | U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, | ||
189 | and U+002D HYPHEN-MINUS ("<!--"), then set the escape flag to true. */ | ||
190 | $escape = true; | ||
191 | |||
192 | /* In any case, emit the input character as a character token. Stay | ||
193 | in the data state. */ | ||
194 | $this->emitToken(array( | ||
195 | 'type' => self::CHARACTER, | ||
196 | 'data' => '-' | ||
197 | )); | ||
198 | // We do the "any case" part as part of "anything else". | ||
199 | |||
200 | /* U+003C LESS-THAN SIGN (<) */ | ||
201 | } elseif($char === '<' && $lt_cond) { | ||
202 | /* When the content model flag is set to the PCDATA state: switch | ||
203 | to the tag open state. | ||
204 | |||
205 | When the content model flag is set to either the RCDATA state or | ||
206 | the CDATA state and the escape flag is false: switch to the tag | ||
207 | open state. | ||
208 | |||
209 | Otherwise: treat it as per the "anything else" entry below. */ | ||
210 | $state = 'tag open'; | ||
211 | |||
212 | /* U+003E GREATER-THAN SIGN (>) */ | ||
213 | } elseif( | ||
214 | $char === '>' && | ||
215 | $gt_cond && | ||
216 | substr($lastFourChars, 1) === '-->' | ||
217 | ) { | ||
218 | /* If the content model flag is set to either the RCDATA state or | ||
219 | the CDATA state, and the escape flag is true, and the last three | ||
220 | characters in the input stream including this one are U+002D | ||
221 | HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN ("-->"), | ||
222 | set the escape flag to false. */ | ||
223 | $escape = false; | ||
224 | |||
225 | /* In any case, emit the input character as a character token. | ||
226 | Stay in the data state. */ | ||
227 | $this->emitToken(array( | ||
228 | 'type' => self::CHARACTER, | ||
229 | 'data' => '>' | ||
230 | )); | ||
231 | // We do the "any case" part as part of "anything else". | ||
232 | |||
233 | } elseif($char === false) { | ||
234 | /* EOF | ||
235 | Emit an end-of-file token. */ | ||
236 | $state = null; | ||
237 | $this->tree->emitToken(array( | ||
238 | 'type' => self::EOF | ||
239 | )); | ||
240 | |||
241 | } elseif($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
242 | // Directly after emitting a token you switch back to the "data | ||
243 | // state". At that point spaceCharacters are important so they are | ||
244 | // emitted separately. | ||
245 | $chars = $this->stream->charsWhile(self::WHITESPACE); | ||
246 | $this->emitToken(array( | ||
247 | 'type' => self::SPACECHARACTER, | ||
248 | 'data' => $char . $chars | ||
249 | )); | ||
250 | $lastFourChars .= $chars; | ||
251 | if (strlen($lastFourChars) > 4) $lastFourChars = substr($lastFourChars, -4); | ||
252 | |||
253 | } else { | ||
254 | /* Anything else | ||
255 | THIS IS AN OPTIMIZATION: Get as many character that | ||
256 | otherwise would also be treated as a character token and emit it | ||
257 | as a single character token. Stay in the data state. */ | ||
258 | |||
259 | $mask = ''; | ||
260 | if ($hyp_cond) $mask .= '-'; | ||
261 | if ($amp_cond) $mask .= '&'; | ||
262 | if ($lt_cond) $mask .= '<'; | ||
263 | if ($gt_cond) $mask .= '>'; | ||
264 | |||
265 | if ($mask === '') { | ||
266 | $chars = $this->stream->remainingChars(); | ||
267 | } else { | ||
268 | $chars = $this->stream->charsUntil($mask); | ||
269 | } | ||
270 | |||
271 | $this->emitToken(array( | ||
272 | 'type' => self::CHARACTER, | ||
273 | 'data' => $char . $chars | ||
274 | )); | ||
275 | |||
276 | $lastFourChars .= $chars; | ||
277 | if (strlen($lastFourChars) > 4) $lastFourChars = substr($lastFourChars, -4); | ||
278 | |||
279 | $state = 'data'; | ||
280 | } | ||
281 | break; | ||
282 | |||
283 | case 'character reference data': | ||
284 | /* (This cannot happen if the content model flag | ||
285 | is set to the CDATA state.) */ | ||
286 | |||
287 | /* Attempt to consume a character reference, with no | ||
288 | additional allowed character. */ | ||
289 | $entity = $this->consumeCharacterReference(); | ||
290 | |||
291 | /* If nothing is returned, emit a U+0026 AMPERSAND | ||
292 | character token. Otherwise, emit the character token that | ||
293 | was returned. */ | ||
294 | // This is all done when consuming the character reference. | ||
295 | $this->emitToken(array( | ||
296 | 'type' => self::CHARACTER, | ||
297 | 'data' => $entity | ||
298 | )); | ||
299 | |||
300 | /* Finally, switch to the data state. */ | ||
301 | $state = 'data'; | ||
302 | break; | ||
303 | |||
304 | case 'tag open': | ||
305 | $char = $this->stream->char(); | ||
306 | |||
307 | switch($this->content_model) { | ||
308 | case self::RCDATA: | ||
309 | case self::CDATA: | ||
310 | /* Consume the next input character. If it is a | ||
311 | U+002F SOLIDUS (/) character, switch to the close | ||
312 | tag open state. Otherwise, emit a U+003C LESS-THAN | ||
313 | SIGN character token and reconsume the current input | ||
314 | character in the data state. */ | ||
315 | // We consumed above. | ||
316 | |||
317 | if($char === '/') { | ||
318 | $state = 'close tag open'; | ||
319 | |||
320 | } else { | ||
321 | $this->emitToken(array( | ||
322 | 'type' => self::CHARACTER, | ||
323 | 'data' => '<' | ||
324 | )); | ||
325 | |||
326 | $this->stream->unget(); | ||
327 | |||
328 | $state = 'data'; | ||
329 | } | ||
330 | break; | ||
331 | |||
332 | case self::PCDATA: | ||
333 | /* If the content model flag is set to the PCDATA state | ||
334 | Consume the next input character: */ | ||
335 | // We consumed above. | ||
336 | |||
337 | if($char === '!') { | ||
338 | /* U+0021 EXCLAMATION MARK (!) | ||
339 | Switch to the markup declaration open state. */ | ||
340 | $state = 'markup declaration open'; | ||
341 | |||
342 | } elseif($char === '/') { | ||
343 | /* U+002F SOLIDUS (/) | ||
344 | Switch to the close tag open state. */ | ||
345 | $state = 'close tag open'; | ||
346 | |||
347 | } elseif('A' <= $char && $char <= 'Z') { | ||
348 | /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z | ||
349 | Create a new start tag token, set its tag name to the lowercase | ||
350 | version of the input character (add 0x0020 to the character's code | ||
351 | point), then switch to the tag name state. (Don't emit the token | ||
352 | yet; further details will be filled in before it is emitted.) */ | ||
353 | $this->token = array( | ||
354 | 'name' => strtolower($char), | ||
355 | 'type' => self::STARTTAG, | ||
356 | 'attr' => array() | ||
357 | ); | ||
358 | |||
359 | $state = 'tag name'; | ||
360 | |||
361 | } elseif('a' <= $char && $char <= 'z') { | ||
362 | /* U+0061 LATIN SMALL LETTER A through to U+007A LATIN SMALL LETTER Z | ||
363 | Create a new start tag token, set its tag name to the input | ||
364 | character, then switch to the tag name state. (Don't emit | ||
365 | the token yet; further details will be filled in before it | ||
366 | is emitted.) */ | ||
367 | $this->token = array( | ||
368 | 'name' => $char, | ||
369 | 'type' => self::STARTTAG, | ||
370 | 'attr' => array() | ||
371 | ); | ||
372 | |||
373 | $state = 'tag name'; | ||
374 | |||
375 | } elseif($char === '>') { | ||
376 | /* U+003E GREATER-THAN SIGN (>) | ||
377 | Parse error. Emit a U+003C LESS-THAN SIGN character token and a | ||
378 | U+003E GREATER-THAN SIGN character token. Switch to the data state. */ | ||
379 | $this->emitToken(array( | ||
380 | 'type' => self::PARSEERROR, | ||
381 | 'data' => 'expected-tag-name-but-got-right-bracket' | ||
382 | )); | ||
383 | $this->emitToken(array( | ||
384 | 'type' => self::CHARACTER, | ||
385 | 'data' => '<>' | ||
386 | )); | ||
387 | |||
388 | $state = 'data'; | ||
389 | |||
390 | } elseif($char === '?') { | ||
391 | /* U+003F QUESTION MARK (?) | ||
392 | Parse error. Switch to the bogus comment state. */ | ||
393 | $this->emitToken(array( | ||
394 | 'type' => self::PARSEERROR, | ||
395 | 'data' => 'expected-tag-name-but-got-question-mark' | ||
396 | )); | ||
397 | $this->token = array( | ||
398 | 'data' => '?', | ||
399 | 'type' => self::COMMENT | ||
400 | ); | ||
401 | $state = 'bogus comment'; | ||
402 | |||
403 | } else { | ||
404 | /* Anything else | ||
405 | Parse error. Emit a U+003C LESS-THAN SIGN character token and | ||
406 | reconsume the current input character in the data state. */ | ||
407 | $this->emitToken(array( | ||
408 | 'type' => self::PARSEERROR, | ||
409 | 'data' => 'expected-tag-name' | ||
410 | )); | ||
411 | $this->emitToken(array( | ||
412 | 'type' => self::CHARACTER, | ||
413 | 'data' => '<' | ||
414 | )); | ||
415 | |||
416 | $state = 'data'; | ||
417 | $this->stream->unget(); | ||
418 | } | ||
419 | break; | ||
420 | } | ||
421 | break; | ||
422 | |||
423 | case 'close tag open': | ||
424 | if ( | ||
425 | $this->content_model === self::RCDATA || | ||
426 | $this->content_model === self::CDATA | ||
427 | ) { | ||
428 | /* If the content model flag is set to the RCDATA or CDATA | ||
429 | states... */ | ||
430 | $name = strtolower($this->stream->charsWhile(self::ALPHA)); | ||
431 | $following = $this->stream->char(); | ||
432 | $this->stream->unget(); | ||
433 | if ( | ||
434 | !$this->token || | ||
435 | $this->token['name'] !== $name || | ||
436 | $this->token['name'] === $name && !in_array($following, array("\x09", "\x0A", "\x0C", "\x20", "\x3E", "\x2F", false)) | ||
437 | ) { | ||
438 | /* if no start tag token has ever been emitted by this instance | ||
439 | of the tokenizer (fragment case), or, if the next few | ||
440 | characters do not match the tag name of the last start tag | ||
441 | token emitted (compared in an ASCII case-insensitive manner), | ||
442 | or if they do but they are not immediately followed by one of | ||
443 | the following characters: | ||
444 | |||
445 | * U+0009 CHARACTER TABULATION | ||
446 | * U+000A LINE FEED (LF) | ||
447 | * U+000C FORM FEED (FF) | ||
448 | * U+0020 SPACE | ||
449 | * U+003E GREATER-THAN SIGN (>) | ||
450 | * U+002F SOLIDUS (/) | ||
451 | * EOF | ||
452 | |||
453 | ...then emit a U+003C LESS-THAN SIGN character token, a | ||
454 | U+002F SOLIDUS character token, and switch to the data | ||
455 | state to process the next input character. */ | ||
456 | // XXX: Probably ought to replace in_array with $following === x ||... | ||
457 | |||
458 | // We also need to emit $name now we've consumed that, as we | ||
459 | // know it'll just be emitted as a character token. | ||
460 | $this->emitToken(array( | ||
461 | 'type' => self::CHARACTER, | ||
462 | 'data' => '</' . $name | ||
463 | )); | ||
464 | |||
465 | $state = 'data'; | ||
466 | } else { | ||
467 | // This matches what would happen if we actually did the | ||
468 | // otherwise below (but we can't because we've consumed too | ||
469 | // much). | ||
470 | |||
471 | // Start the end tag token with the name we already have. | ||
472 | $this->token = array( | ||
473 | 'name' => $name, | ||
474 | 'type' => self::ENDTAG | ||
475 | ); | ||
476 | |||
477 | // Change to tag name state. | ||
478 | $state = 'tag name'; | ||
479 | } | ||
480 | } elseif ($this->content_model === self::PCDATA) { | ||
481 | /* Otherwise, if the content model flag is set to the PCDATA | ||
482 | state [...]: */ | ||
483 | $char = $this->stream->char(); | ||
484 | |||
485 | if ('A' <= $char && $char <= 'Z') { | ||
486 | /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z | ||
487 | Create a new end tag token, set its tag name to the lowercase version | ||
488 | of the input character (add 0x0020 to the character's code point), then | ||
489 | switch to the tag name state. (Don't emit the token yet; further details | ||
490 | will be filled in before it is emitted.) */ | ||
491 | $this->token = array( | ||
492 | 'name' => strtolower($char), | ||
493 | 'type' => self::ENDTAG | ||
494 | ); | ||
495 | |||
496 | $state = 'tag name'; | ||
497 | |||
498 | } elseif ('a' <= $char && $char <= 'z') { | ||
499 | /* U+0061 LATIN SMALL LETTER A through to U+007A LATIN SMALL LETTER Z | ||
500 | Create a new end tag token, set its tag name to the | ||
501 | input character, then switch to the tag name state. | ||
502 | (Don't emit the token yet; further details will be | ||
503 | filled in before it is emitted.) */ | ||
504 | $this->token = array( | ||
505 | 'name' => $char, | ||
506 | 'type' => self::ENDTAG | ||
507 | ); | ||
508 | |||
509 | $state = 'tag name'; | ||
510 | |||
511 | } elseif($char === '>') { | ||
512 | /* U+003E GREATER-THAN SIGN (>) | ||
513 | Parse error. Switch to the data state. */ | ||
514 | $this->emitToken(array( | ||
515 | 'type' => self::PARSEERROR, | ||
516 | 'data' => 'expected-closing-tag-but-got-right-bracket' | ||
517 | )); | ||
518 | $state = 'data'; | ||
519 | |||
520 | } elseif($char === false) { | ||
521 | /* EOF | ||
522 | Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F | ||
523 | SOLIDUS character token. Reconsume the EOF character in the data state. */ | ||
524 | $this->emitToken(array( | ||
525 | 'type' => self::PARSEERROR, | ||
526 | 'data' => 'expected-closing-tag-but-got-eof' | ||
527 | )); | ||
528 | $this->emitToken(array( | ||
529 | 'type' => self::CHARACTER, | ||
530 | 'data' => '</' | ||
531 | )); | ||
532 | |||
533 | $this->stream->unget(); | ||
534 | $state = 'data'; | ||
535 | |||
536 | } else { | ||
537 | /* Parse error. Switch to the bogus comment state. */ | ||
538 | $this->emitToken(array( | ||
539 | 'type' => self::PARSEERROR, | ||
540 | 'data' => 'expected-closing-tag-but-got-char' | ||
541 | )); | ||
542 | $this->token = array( | ||
543 | 'data' => $char, | ||
544 | 'type' => self::COMMENT | ||
545 | ); | ||
546 | $state = 'bogus comment'; | ||
547 | } | ||
548 | } | ||
549 | break; | ||
550 | |||
551 | case 'tag name': | ||
552 | /* Consume the next input character: */ | ||
553 | $char = $this->stream->char(); | ||
554 | |||
555 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
556 | /* U+0009 CHARACTER TABULATION | ||
557 | U+000A LINE FEED (LF) | ||
558 | U+000C FORM FEED (FF) | ||
559 | U+0020 SPACE | ||
560 | Switch to the before attribute name state. */ | ||
561 | $state = 'before attribute name'; | ||
562 | |||
563 | } elseif($char === '/') { | ||
564 | /* U+002F SOLIDUS (/) | ||
565 | Switch to the self-closing start tag state. */ | ||
566 | $state = 'self-closing start tag'; | ||
567 | |||
568 | } elseif($char === '>') { | ||
569 | /* U+003E GREATER-THAN SIGN (>) | ||
570 | Emit the current tag token. Switch to the data state. */ | ||
571 | $this->emitToken($this->token); | ||
572 | $state = 'data'; | ||
573 | |||
574 | } elseif('A' <= $char && $char <= 'Z') { | ||
575 | /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z | ||
576 | Append the lowercase version of the current input | ||
577 | character (add 0x0020 to the character's code point) to | ||
578 | the current tag token's tag name. Stay in the tag name state. */ | ||
579 | $chars = $this->stream->charsWhile(self::UPPER_ALPHA); | ||
580 | |||
581 | $this->token['name'] .= strtolower($char . $chars); | ||
582 | $state = 'tag name'; | ||
583 | |||
584 | } elseif($char === false) { | ||
585 | /* EOF | ||
586 | Parse error. Reconsume the EOF character in the data state. */ | ||
587 | $this->emitToken(array( | ||
588 | 'type' => self::PARSEERROR, | ||
589 | 'data' => 'eof-in-tag-name' | ||
590 | )); | ||
591 | |||
592 | $this->stream->unget(); | ||
593 | $state = 'data'; | ||
594 | |||
595 | } else { | ||
596 | /* Anything else | ||
597 | Append the current input character to the current tag token's tag name. | ||
598 | Stay in the tag name state. */ | ||
599 | $chars = $this->stream->charsUntil("\t\n\x0C />" . self::UPPER_ALPHA); | ||
600 | |||
601 | $this->token['name'] .= $char . $chars; | ||
602 | $state = 'tag name'; | ||
603 | } | ||
604 | break; | ||
605 | |||
606 | case 'before attribute name': | ||
607 | /* Consume the next input character: */ | ||
608 | $char = $this->stream->char(); | ||
609 | |||
610 | // this conditional is optimized, check bottom | ||
611 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
612 | /* U+0009 CHARACTER TABULATION | ||
613 | U+000A LINE FEED (LF) | ||
614 | U+000C FORM FEED (FF) | ||
615 | U+0020 SPACE | ||
616 | Stay in the before attribute name state. */ | ||
617 | $state = 'before attribute name'; | ||
618 | |||
619 | } elseif($char === '/') { | ||
620 | /* U+002F SOLIDUS (/) | ||
621 | Switch to the self-closing start tag state. */ | ||
622 | $state = 'self-closing start tag'; | ||
623 | |||
624 | } elseif($char === '>') { | ||
625 | /* U+003E GREATER-THAN SIGN (>) | ||
626 | Emit the current tag token. Switch to the data state. */ | ||
627 | $this->emitToken($this->token); | ||
628 | $state = 'data'; | ||
629 | |||
630 | } elseif('A' <= $char && $char <= 'Z') { | ||
631 | /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z | ||
632 | Start a new attribute in the current tag token. Set that | ||
633 | attribute's name to the lowercase version of the current | ||
634 | input character (add 0x0020 to the character's code | ||
635 | point), and its value to the empty string. Switch to the | ||
636 | attribute name state.*/ | ||
637 | $this->token['attr'][] = array( | ||
638 | 'name' => strtolower($char), | ||
639 | 'value' => '' | ||
640 | ); | ||
641 | |||
642 | $state = 'attribute name'; | ||
643 | |||
644 | } elseif($char === false) { | ||
645 | /* EOF | ||
646 | Parse error. Reconsume the EOF character in the data state. */ | ||
647 | $this->emitToken(array( | ||
648 | 'type' => self::PARSEERROR, | ||
649 | 'data' => 'expected-attribute-name-but-got-eof' | ||
650 | )); | ||
651 | |||
652 | $this->stream->unget(); | ||
653 | $state = 'data'; | ||
654 | |||
655 | } else { | ||
656 | /* U+0022 QUOTATION MARK (") | ||
657 | U+0027 APOSTROPHE (') | ||
658 | U+003C LESS-THAN SIGN (<) | ||
659 | U+003D EQUALS SIGN (=) | ||
660 | Parse error. Treat it as per the "anything else" entry | ||
661 | below. */ | ||
662 | if($char === '"' || $char === "'" || $char === '<' || $char === '=') { | ||
663 | $this->emitToken(array( | ||
664 | 'type' => self::PARSEERROR, | ||
665 | 'data' => 'invalid-character-in-attribute-name' | ||
666 | )); | ||
667 | } | ||
668 | |||
669 | /* Anything else | ||
670 | Start a new attribute in the current tag token. Set that attribute's | ||
671 | name to the current input character, and its value to the empty string. | ||
672 | Switch to the attribute name state. */ | ||
673 | $this->token['attr'][] = array( | ||
674 | 'name' => $char, | ||
675 | 'value' => '' | ||
676 | ); | ||
677 | |||
678 | $state = 'attribute name'; | ||
679 | } | ||
680 | break; | ||
681 | |||
682 | case 'attribute name': | ||
683 | // Consume the next input character: | ||
684 | $char = $this->stream->char(); | ||
685 | |||
686 | // this conditional is optimized, check bottom | ||
687 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
688 | /* U+0009 CHARACTER TABULATION | ||
689 | U+000A LINE FEED (LF) | ||
690 | U+000C FORM FEED (FF) | ||
691 | U+0020 SPACE | ||
692 | Switch to the after attribute name state. */ | ||
693 | $state = 'after attribute name'; | ||
694 | |||
695 | } elseif($char === '/') { | ||
696 | /* U+002F SOLIDUS (/) | ||
697 | Switch to the self-closing start tag state. */ | ||
698 | $state = 'self-closing start tag'; | ||
699 | |||
700 | } elseif($char === '=') { | ||
701 | /* U+003D EQUALS SIGN (=) | ||
702 | Switch to the before attribute value state. */ | ||
703 | $state = 'before attribute value'; | ||
704 | |||
705 | } elseif($char === '>') { | ||
706 | /* U+003E GREATER-THAN SIGN (>) | ||
707 | Emit the current tag token. Switch to the data state. */ | ||
708 | $this->emitToken($this->token); | ||
709 | $state = 'data'; | ||
710 | |||
711 | } elseif('A' <= $char && $char <= 'Z') { | ||
712 | /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z | ||
713 | Append the lowercase version of the current input | ||
714 | character (add 0x0020 to the character's code point) to | ||
715 | the current attribute's name. Stay in the attribute name | ||
716 | state. */ | ||
717 | $chars = $this->stream->charsWhile(self::UPPER_ALPHA); | ||
718 | |||
719 | $last = count($this->token['attr']) - 1; | ||
720 | $this->token['attr'][$last]['name'] .= strtolower($char . $chars); | ||
721 | |||
722 | $state = 'attribute name'; | ||
723 | |||
724 | } elseif($char === false) { | ||
725 | /* EOF | ||
726 | Parse error. Reconsume the EOF character in the data state. */ | ||
727 | $this->emitToken(array( | ||
728 | 'type' => self::PARSEERROR, | ||
729 | 'data' => 'eof-in-attribute-name' | ||
730 | )); | ||
731 | |||
732 | $this->stream->unget(); | ||
733 | $state = 'data'; | ||
734 | |||
735 | } else { | ||
736 | /* U+0022 QUOTATION MARK (") | ||
737 | U+0027 APOSTROPHE (') | ||
738 | U+003C LESS-THAN SIGN (<) | ||
739 | Parse error. Treat it as per the "anything else" | ||
740 | entry below. */ | ||
741 | if($char === '"' || $char === "'" || $char === '<') { | ||
742 | $this->emitToken(array( | ||
743 | 'type' => self::PARSEERROR, | ||
744 | 'data' => 'invalid-character-in-attribute-name' | ||
745 | )); | ||
746 | } | ||
747 | |||
748 | /* Anything else | ||
749 | Append the current input character to the current attribute's name. | ||
750 | Stay in the attribute name state. */ | ||
751 | $chars = $this->stream->charsUntil("\t\n\x0C /=>\"'" . self::UPPER_ALPHA); | ||
752 | |||
753 | $last = count($this->token['attr']) - 1; | ||
754 | $this->token['attr'][$last]['name'] .= $char . $chars; | ||
755 | |||
756 | $state = 'attribute name'; | ||
757 | } | ||
758 | |||
759 | /* When the user agent leaves the attribute name state | ||
760 | (and before emitting the tag token, if appropriate), the | ||
761 | complete attribute's name must be compared to the other | ||
762 | attributes on the same token; if there is already an | ||
763 | attribute on the token with the exact same name, then this | ||
764 | is a parse error and the new attribute must be dropped, along | ||
765 | with the value that gets associated with it (if any). */ | ||
766 | // this might be implemented in the emitToken method | ||
767 | break; | ||
768 | |||
769 | case 'after attribute name': | ||
770 | // Consume the next input character: | ||
771 | $char = $this->stream->char(); | ||
772 | |||
773 | // this is an optimized conditional, check the bottom | ||
774 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
775 | /* U+0009 CHARACTER TABULATION | ||
776 | U+000A LINE FEED (LF) | ||
777 | U+000C FORM FEED (FF) | ||
778 | U+0020 SPACE | ||
779 | Stay in the after attribute name state. */ | ||
780 | $state = 'after attribute name'; | ||
781 | |||
782 | } elseif($char === '/') { | ||
783 | /* U+002F SOLIDUS (/) | ||
784 | Switch to the self-closing start tag state. */ | ||
785 | $state = 'self-closing start tag'; | ||
786 | |||
787 | } elseif($char === '=') { | ||
788 | /* U+003D EQUALS SIGN (=) | ||
789 | Switch to the before attribute value state. */ | ||
790 | $state = 'before attribute value'; | ||
791 | |||
792 | } elseif($char === '>') { | ||
793 | /* U+003E GREATER-THAN SIGN (>) | ||
794 | Emit the current tag token. Switch to the data state. */ | ||
795 | $this->emitToken($this->token); | ||
796 | $state = 'data'; | ||
797 | |||
798 | } elseif('A' <= $char && $char <= 'Z') { | ||
799 | /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z | ||
800 | Start a new attribute in the current tag token. Set that | ||
801 | attribute's name to the lowercase version of the current | ||
802 | input character (add 0x0020 to the character's code | ||
803 | point), and its value to the empty string. Switch to the | ||
804 | attribute name state. */ | ||
805 | $this->token['attr'][] = array( | ||
806 | 'name' => strtolower($char), | ||
807 | 'value' => '' | ||
808 | ); | ||
809 | |||
810 | $state = 'attribute name'; | ||
811 | |||
812 | } elseif($char === false) { | ||
813 | /* EOF | ||
814 | Parse error. Reconsume the EOF character in the data state. */ | ||
815 | $this->emitToken(array( | ||
816 | 'type' => self::PARSEERROR, | ||
817 | 'data' => 'expected-end-of-tag-but-got-eof' | ||
818 | )); | ||
819 | |||
820 | $this->stream->unget(); | ||
821 | $state = 'data'; | ||
822 | |||
823 | } else { | ||
824 | /* U+0022 QUOTATION MARK (") | ||
825 | U+0027 APOSTROPHE (') | ||
826 | U+003C LESS-THAN SIGN(<) | ||
827 | Parse error. Treat it as per the "anything else" | ||
828 | entry below. */ | ||
829 | if($char === '"' || $char === "'" || $char === "<") { | ||
830 | $this->emitToken(array( | ||
831 | 'type' => self::PARSEERROR, | ||
832 | 'data' => 'invalid-character-after-attribute-name' | ||
833 | )); | ||
834 | } | ||
835 | |||
836 | /* Anything else | ||
837 | Start a new attribute in the current tag token. Set that attribute's | ||
838 | name to the current input character, and its value to the empty string. | ||
839 | Switch to the attribute name state. */ | ||
840 | $this->token['attr'][] = array( | ||
841 | 'name' => $char, | ||
842 | 'value' => '' | ||
843 | ); | ||
844 | |||
845 | $state = 'attribute name'; | ||
846 | } | ||
847 | break; | ||
848 | |||
849 | case 'before attribute value': | ||
850 | // Consume the next input character: | ||
851 | $char = $this->stream->char(); | ||
852 | |||
853 | // this is an optimized conditional | ||
854 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
855 | /* U+0009 CHARACTER TABULATION | ||
856 | U+000A LINE FEED (LF) | ||
857 | U+000C FORM FEED (FF) | ||
858 | U+0020 SPACE | ||
859 | Stay in the before attribute value state. */ | ||
860 | $state = 'before attribute value'; | ||
861 | |||
862 | } elseif($char === '"') { | ||
863 | /* U+0022 QUOTATION MARK (") | ||
864 | Switch to the attribute value (double-quoted) state. */ | ||
865 | $state = 'attribute value (double-quoted)'; | ||
866 | |||
867 | } elseif($char === '&') { | ||
868 | /* U+0026 AMPERSAND (&) | ||
869 | Switch to the attribute value (unquoted) state and reconsume | ||
870 | this input character. */ | ||
871 | $this->stream->unget(); | ||
872 | $state = 'attribute value (unquoted)'; | ||
873 | |||
874 | } elseif($char === '\'') { | ||
875 | /* U+0027 APOSTROPHE (') | ||
876 | Switch to the attribute value (single-quoted) state. */ | ||
877 | $state = 'attribute value (single-quoted)'; | ||
878 | |||
879 | } elseif($char === '>') { | ||
880 | /* U+003E GREATER-THAN SIGN (>) | ||
881 | Parse error. Emit the current tag token. Switch to the data state. */ | ||
882 | $this->emitToken(array( | ||
883 | 'type' => self::PARSEERROR, | ||
884 | 'data' => 'expected-attribute-value-but-got-right-bracket' | ||
885 | )); | ||
886 | $this->emitToken($this->token); | ||
887 | $state = 'data'; | ||
888 | |||
889 | } elseif($char === false) { | ||
890 | /* EOF | ||
891 | Parse error. Reconsume the EOF character in the data state. */ | ||
892 | $this->emitToken(array( | ||
893 | 'type' => self::PARSEERROR, | ||
894 | 'data' => 'expected-attribute-value-but-got-eof' | ||
895 | )); | ||
896 | $this->stream->unget(); | ||
897 | $state = 'data'; | ||
898 | |||
899 | } else { | ||
900 | /* U+003D EQUALS SIGN (=) | ||
901 | * U+003C LESS-THAN SIGN (<) | ||
902 | Parse error. Treat it as per the "anything else" entry below. */ | ||
903 | if($char === '=' || $char === '<') { | ||
904 | $this->emitToken(array( | ||
905 | 'type' => self::PARSEERROR, | ||
906 | 'data' => 'equals-in-unquoted-attribute-value' | ||
907 | )); | ||
908 | } | ||
909 | |||
910 | /* Anything else | ||
911 | Append the current input character to the current attribute's value. | ||
912 | Switch to the attribute value (unquoted) state. */ | ||
913 | $last = count($this->token['attr']) - 1; | ||
914 | $this->token['attr'][$last]['value'] .= $char; | ||
915 | |||
916 | $state = 'attribute value (unquoted)'; | ||
917 | } | ||
918 | break; | ||
919 | |||
920 | case 'attribute value (double-quoted)': | ||
921 | // Consume the next input character: | ||
922 | $char = $this->stream->char(); | ||
923 | |||
924 | if($char === '"') { | ||
925 | /* U+0022 QUOTATION MARK (") | ||
926 | Switch to the after attribute value (quoted) state. */ | ||
927 | $state = 'after attribute value (quoted)'; | ||
928 | |||
929 | } elseif($char === '&') { | ||
930 | /* U+0026 AMPERSAND (&) | ||
931 | Switch to the character reference in attribute value | ||
932 | state, with the additional allowed character | ||
933 | being U+0022 QUOTATION MARK ("). */ | ||
934 | $this->characterReferenceInAttributeValue('"'); | ||
935 | |||
936 | } elseif($char === false) { | ||
937 | /* EOF | ||
938 | Parse error. Reconsume the EOF character in the data state. */ | ||
939 | $this->emitToken(array( | ||
940 | 'type' => self::PARSEERROR, | ||
941 | 'data' => 'eof-in-attribute-value-double-quote' | ||
942 | )); | ||
943 | |||
944 | $this->stream->unget(); | ||
945 | $state = 'data'; | ||
946 | |||
947 | } else { | ||
948 | /* Anything else | ||
949 | Append the current input character to the current attribute's value. | ||
950 | Stay in the attribute value (double-quoted) state. */ | ||
951 | $chars = $this->stream->charsUntil('"&'); | ||
952 | |||
953 | $last = count($this->token['attr']) - 1; | ||
954 | $this->token['attr'][$last]['value'] .= $char . $chars; | ||
955 | |||
956 | $state = 'attribute value (double-quoted)'; | ||
957 | } | ||
958 | break; | ||
959 | |||
960 | case 'attribute value (single-quoted)': | ||
961 | // Consume the next input character: | ||
962 | $char = $this->stream->char(); | ||
963 | |||
964 | if($char === "'") { | ||
965 | /* U+0022 QUOTATION MARK (') | ||
966 | Switch to the after attribute value state. */ | ||
967 | $state = 'after attribute value (quoted)'; | ||
968 | |||
969 | } elseif($char === '&') { | ||
970 | /* U+0026 AMPERSAND (&) | ||
971 | Switch to the entity in attribute value state. */ | ||
972 | $this->characterReferenceInAttributeValue("'"); | ||
973 | |||
974 | } elseif($char === false) { | ||
975 | /* EOF | ||
976 | Parse error. Reconsume the EOF character in the data state. */ | ||
977 | $this->emitToken(array( | ||
978 | 'type' => self::PARSEERROR, | ||
979 | 'data' => 'eof-in-attribute-value-single-quote' | ||
980 | )); | ||
981 | |||
982 | $this->stream->unget(); | ||
983 | $state = 'data'; | ||
984 | |||
985 | } else { | ||
986 | /* Anything else | ||
987 | Append the current input character to the current attribute's value. | ||
988 | Stay in the attribute value (single-quoted) state. */ | ||
989 | $chars = $this->stream->charsUntil("'&"); | ||
990 | |||
991 | $last = count($this->token['attr']) - 1; | ||
992 | $this->token['attr'][$last]['value'] .= $char . $chars; | ||
993 | |||
994 | $state = 'attribute value (single-quoted)'; | ||
995 | } | ||
996 | break; | ||
997 | |||
998 | case 'attribute value (unquoted)': | ||
999 | // Consume the next input character: | ||
1000 | $char = $this->stream->char(); | ||
1001 | |||
1002 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1003 | /* U+0009 CHARACTER TABULATION | ||
1004 | U+000A LINE FEED (LF) | ||
1005 | U+000C FORM FEED (FF) | ||
1006 | U+0020 SPACE | ||
1007 | Switch to the before attribute name state. */ | ||
1008 | $state = 'before attribute name'; | ||
1009 | |||
1010 | } elseif($char === '&') { | ||
1011 | /* U+0026 AMPERSAND (&) | ||
1012 | Switch to the entity in attribute value state, with the | ||
1013 | additional allowed character being U+003E | ||
1014 | GREATER-THAN SIGN (>). */ | ||
1015 | $this->characterReferenceInAttributeValue('>'); | ||
1016 | |||
1017 | } elseif($char === '>') { | ||
1018 | /* U+003E GREATER-THAN SIGN (>) | ||
1019 | Emit the current tag token. Switch to the data state. */ | ||
1020 | $this->emitToken($this->token); | ||
1021 | $state = 'data'; | ||
1022 | |||
1023 | } elseif ($char === false) { | ||
1024 | /* EOF | ||
1025 | Parse error. Reconsume the EOF character in the data state. */ | ||
1026 | $this->emitToken(array( | ||
1027 | 'type' => self::PARSEERROR, | ||
1028 | 'data' => 'eof-in-attribute-value-no-quotes' | ||
1029 | )); | ||
1030 | $this->stream->unget(); | ||
1031 | $state = 'data'; | ||
1032 | |||
1033 | } else { | ||
1034 | /* U+0022 QUOTATION MARK (") | ||
1035 | U+0027 APOSTROPHE (') | ||
1036 | U+003C LESS-THAN SIGN (<) | ||
1037 | U+003D EQUALS SIGN (=) | ||
1038 | Parse error. Treat it as per the "anything else" | ||
1039 | entry below. */ | ||
1040 | if($char === '"' || $char === "'" || $char === '=' || $char == '<') { | ||
1041 | $this->emitToken(array( | ||
1042 | 'type' => self::PARSEERROR, | ||
1043 | 'data' => 'unexpected-character-in-unquoted-attribute-value' | ||
1044 | )); | ||
1045 | } | ||
1046 | |||
1047 | /* Anything else | ||
1048 | Append the current input character to the current attribute's value. | ||
1049 | Stay in the attribute value (unquoted) state. */ | ||
1050 | $chars = $this->stream->charsUntil("\t\n\x0c &>\"'="); | ||
1051 | |||
1052 | $last = count($this->token['attr']) - 1; | ||
1053 | $this->token['attr'][$last]['value'] .= $char . $chars; | ||
1054 | |||
1055 | $state = 'attribute value (unquoted)'; | ||
1056 | } | ||
1057 | break; | ||
1058 | |||
1059 | case 'after attribute value (quoted)': | ||
1060 | /* Consume the next input character: */ | ||
1061 | $char = $this->stream->char(); | ||
1062 | |||
1063 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1064 | /* U+0009 CHARACTER TABULATION | ||
1065 | U+000A LINE FEED (LF) | ||
1066 | U+000C FORM FEED (FF) | ||
1067 | U+0020 SPACE | ||
1068 | Switch to the before attribute name state. */ | ||
1069 | $state = 'before attribute name'; | ||
1070 | |||
1071 | } elseif ($char === '/') { | ||
1072 | /* U+002F SOLIDUS (/) | ||
1073 | Switch to the self-closing start tag state. */ | ||
1074 | $state = 'self-closing start tag'; | ||
1075 | |||
1076 | } elseif ($char === '>') { | ||
1077 | /* U+003E GREATER-THAN SIGN (>) | ||
1078 | Emit the current tag token. Switch to the data state. */ | ||
1079 | $this->emitToken($this->token); | ||
1080 | $state = 'data'; | ||
1081 | |||
1082 | } elseif ($char === false) { | ||
1083 | /* EOF | ||
1084 | Parse error. Reconsume the EOF character in the data state. */ | ||
1085 | $this->emitToken(array( | ||
1086 | 'type' => self::PARSEERROR, | ||
1087 | 'data' => 'unexpected-EOF-after-attribute-value' | ||
1088 | )); | ||
1089 | $this->stream->unget(); | ||
1090 | $state = 'data'; | ||
1091 | |||
1092 | } else { | ||
1093 | /* Anything else | ||
1094 | Parse error. Reconsume the character in the before attribute | ||
1095 | name state. */ | ||
1096 | $this->emitToken(array( | ||
1097 | 'type' => self::PARSEERROR, | ||
1098 | 'data' => 'unexpected-character-after-attribute-value' | ||
1099 | )); | ||
1100 | $this->stream->unget(); | ||
1101 | $state = 'before attribute name'; | ||
1102 | } | ||
1103 | break; | ||
1104 | |||
1105 | case 'self-closing start tag': | ||
1106 | /* Consume the next input character: */ | ||
1107 | $char = $this->stream->char(); | ||
1108 | |||
1109 | if ($char === '>') { | ||
1110 | /* U+003E GREATER-THAN SIGN (>) | ||
1111 | Set the self-closing flag of the current tag token. | ||
1112 | Emit the current tag token. Switch to the data state. */ | ||
1113 | // not sure if this is the name we want | ||
1114 | $this->token['self-closing'] = true; | ||
1115 | $this->emitToken($this->token); | ||
1116 | $state = 'data'; | ||
1117 | |||
1118 | } elseif ($char === false) { | ||
1119 | /* EOF | ||
1120 | Parse error. Reconsume the EOF character in the data state. */ | ||
1121 | $this->emitToken(array( | ||
1122 | 'type' => self::PARSEERROR, | ||
1123 | 'data' => 'unexpected-eof-after-self-closing' | ||
1124 | )); | ||
1125 | $this->stream->unget(); | ||
1126 | $state = 'data'; | ||
1127 | |||
1128 | } else { | ||
1129 | /* Anything else | ||
1130 | Parse error. Reconsume the character in the before attribute name state. */ | ||
1131 | $this->emitToken(array( | ||
1132 | 'type' => self::PARSEERROR, | ||
1133 | 'data' => 'unexpected-character-after-self-closing' | ||
1134 | )); | ||
1135 | $this->stream->unget(); | ||
1136 | $state = 'before attribute name'; | ||
1137 | } | ||
1138 | break; | ||
1139 | |||
1140 | case 'bogus comment': | ||
1141 | /* (This can only happen if the content model flag is set to the PCDATA state.) */ | ||
1142 | /* Consume every character up to the first U+003E GREATER-THAN SIGN | ||
1143 | character (>) or the end of the file (EOF), whichever comes first. Emit | ||
1144 | a comment token whose data is the concatenation of all the characters | ||
1145 | starting from and including the character that caused the state machine | ||
1146 | to switch into the bogus comment state, up to and including the last | ||
1147 | consumed character before the U+003E character, if any, or up to the | ||
1148 | end of the file otherwise. (If the comment was started by the end of | ||
1149 | the file (EOF), the token is empty.) */ | ||
1150 | $this->token['data'] .= (string) $this->stream->charsUntil('>'); | ||
1151 | $this->stream->char(); | ||
1152 | |||
1153 | $this->emitToken($this->token); | ||
1154 | |||
1155 | /* Switch to the data state. */ | ||
1156 | $state = 'data'; | ||
1157 | break; | ||
1158 | |||
1159 | case 'markup declaration open': | ||
1160 | // Consume for below | ||
1161 | $hyphens = $this->stream->charsWhile('-', 2); | ||
1162 | if ($hyphens === '-') { | ||
1163 | $this->stream->unget(); | ||
1164 | } | ||
1165 | if ($hyphens !== '--') { | ||
1166 | $alpha = $this->stream->charsWhile(self::ALPHA, 7); | ||
1167 | } | ||
1168 | |||
1169 | /* If the next two characters are both U+002D HYPHEN-MINUS (-) | ||
1170 | characters, consume those two characters, create a comment token whose | ||
1171 | data is the empty string, and switch to the comment state. */ | ||
1172 | if($hyphens === '--') { | ||
1173 | $state = 'comment start'; | ||
1174 | $this->token = array( | ||
1175 | 'data' => '', | ||
1176 | 'type' => self::COMMENT | ||
1177 | ); | ||
1178 | |||
1179 | /* Otherwise if the next seven characters are a case-insensitive match | ||
1180 | for the word "DOCTYPE", then consume those characters and switch to the | ||
1181 | DOCTYPE state. */ | ||
1182 | } elseif(strtoupper($alpha) === 'DOCTYPE') { | ||
1183 | $state = 'DOCTYPE'; | ||
1184 | |||
1185 | // XXX not implemented | ||
1186 | /* Otherwise, if the insertion mode is "in foreign content" | ||
1187 | and the current node is not an element in the HTML namespace | ||
1188 | and the next seven characters are an ASCII case-sensitive | ||
1189 | match for the string "[CDATA[" (the five uppercase letters | ||
1190 | "CDATA" with a U+005B LEFT SQUARE BRACKET character before | ||
1191 | and after), then consume those characters and switch to the | ||
1192 | CDATA section state (which is unrelated to the content model | ||
1193 | flag's CDATA state). */ | ||
1194 | |||
1195 | /* Otherwise, is is a parse error. Switch to the bogus comment state. | ||
1196 | The next character that is consumed, if any, is the first character | ||
1197 | that will be in the comment. */ | ||
1198 | } else { | ||
1199 | $this->emitToken(array( | ||
1200 | 'type' => self::PARSEERROR, | ||
1201 | 'data' => 'expected-dashes-or-doctype' | ||
1202 | )); | ||
1203 | $this->token = array( | ||
1204 | 'data' => (string) $alpha, | ||
1205 | 'type' => self::COMMENT | ||
1206 | ); | ||
1207 | $state = 'bogus comment'; | ||
1208 | } | ||
1209 | break; | ||
1210 | |||
1211 | case 'comment start': | ||
1212 | /* Consume the next input character: */ | ||
1213 | $char = $this->stream->char(); | ||
1214 | |||
1215 | if ($char === '-') { | ||
1216 | /* U+002D HYPHEN-MINUS (-) | ||
1217 | Switch to the comment start dash state. */ | ||
1218 | $state = 'comment start dash'; | ||
1219 | } elseif ($char === '>') { | ||
1220 | /* U+003E GREATER-THAN SIGN (>) | ||
1221 | Parse error. Emit the comment token. Switch to the | ||
1222 | data state. */ | ||
1223 | $this->emitToken(array( | ||
1224 | 'type' => self::PARSEERROR, | ||
1225 | 'data' => 'incorrect-comment' | ||
1226 | )); | ||
1227 | $this->emitToken($this->token); | ||
1228 | $state = 'data'; | ||
1229 | } elseif ($char === false) { | ||
1230 | /* EOF | ||
1231 | Parse error. Emit the comment token. Reconsume the | ||
1232 | EOF character in the data state. */ | ||
1233 | $this->emitToken(array( | ||
1234 | 'type' => self::PARSEERROR, | ||
1235 | 'data' => 'eof-in-comment' | ||
1236 | )); | ||
1237 | $this->emitToken($this->token); | ||
1238 | $this->stream->unget(); | ||
1239 | $state = 'data'; | ||
1240 | } else { | ||
1241 | /* Anything else | ||
1242 | Append the input character to the comment token's | ||
1243 | data. Switch to the comment state. */ | ||
1244 | $this->token['data'] .= $char; | ||
1245 | $state = 'comment'; | ||
1246 | } | ||
1247 | break; | ||
1248 | |||
1249 | case 'comment start dash': | ||
1250 | /* Consume the next input character: */ | ||
1251 | $char = $this->stream->char(); | ||
1252 | if ($char === '-') { | ||
1253 | /* U+002D HYPHEN-MINUS (-) | ||
1254 | Switch to the comment end state */ | ||
1255 | $state = 'comment end'; | ||
1256 | } elseif ($char === '>') { | ||
1257 | /* U+003E GREATER-THAN SIGN (>) | ||
1258 | Parse error. Emit the comment token. Switch to the | ||
1259 | data state. */ | ||
1260 | $this->emitToken(array( | ||
1261 | 'type' => self::PARSEERROR, | ||
1262 | 'data' => 'incorrect-comment' | ||
1263 | )); | ||
1264 | $this->emitToken($this->token); | ||
1265 | $state = 'data'; | ||
1266 | } elseif ($char === false) { | ||
1267 | /* Parse error. Emit the comment token. Reconsume the | ||
1268 | EOF character in the data state. */ | ||
1269 | $this->emitToken(array( | ||
1270 | 'type' => self::PARSEERROR, | ||
1271 | 'data' => 'eof-in-comment' | ||
1272 | )); | ||
1273 | $this->emitToken($this->token); | ||
1274 | $this->stream->unget(); | ||
1275 | $state = 'data'; | ||
1276 | } else { | ||
1277 | $this->token['data'] .= '-' . $char; | ||
1278 | $state = 'comment'; | ||
1279 | } | ||
1280 | break; | ||
1281 | |||
1282 | case 'comment': | ||
1283 | /* Consume the next input character: */ | ||
1284 | $char = $this->stream->char(); | ||
1285 | |||
1286 | if($char === '-') { | ||
1287 | /* U+002D HYPHEN-MINUS (-) | ||
1288 | Switch to the comment end dash state */ | ||
1289 | $state = 'comment end dash'; | ||
1290 | |||
1291 | } elseif($char === false) { | ||
1292 | /* EOF | ||
1293 | Parse error. Emit the comment token. Reconsume the EOF character | ||
1294 | in the data state. */ | ||
1295 | $this->emitToken(array( | ||
1296 | 'type' => self::PARSEERROR, | ||
1297 | 'data' => 'eof-in-comment' | ||
1298 | )); | ||
1299 | $this->emitToken($this->token); | ||
1300 | $this->stream->unget(); | ||
1301 | $state = 'data'; | ||
1302 | |||
1303 | } else { | ||
1304 | /* Anything else | ||
1305 | Append the input character to the comment token's data. Stay in | ||
1306 | the comment state. */ | ||
1307 | $chars = $this->stream->charsUntil('-'); | ||
1308 | |||
1309 | $this->token['data'] .= $char . $chars; | ||
1310 | } | ||
1311 | break; | ||
1312 | |||
1313 | case 'comment end dash': | ||
1314 | /* Consume the next input character: */ | ||
1315 | $char = $this->stream->char(); | ||
1316 | |||
1317 | if($char === '-') { | ||
1318 | /* U+002D HYPHEN-MINUS (-) | ||
1319 | Switch to the comment end state */ | ||
1320 | $state = 'comment end'; | ||
1321 | |||
1322 | } elseif($char === false) { | ||
1323 | /* EOF | ||
1324 | Parse error. Emit the comment token. Reconsume the EOF character | ||
1325 | in the data state. */ | ||
1326 | $this->emitToken(array( | ||
1327 | 'type' => self::PARSEERROR, | ||
1328 | 'data' => 'eof-in-comment-end-dash' | ||
1329 | )); | ||
1330 | $this->emitToken($this->token); | ||
1331 | $this->stream->unget(); | ||
1332 | $state = 'data'; | ||
1333 | |||
1334 | } else { | ||
1335 | /* Anything else | ||
1336 | Append a U+002D HYPHEN-MINUS (-) character and the input | ||
1337 | character to the comment token's data. Switch to the comment state. */ | ||
1338 | $this->token['data'] .= '-'.$char; | ||
1339 | $state = 'comment'; | ||
1340 | } | ||
1341 | break; | ||
1342 | |||
1343 | case 'comment end': | ||
1344 | /* Consume the next input character: */ | ||
1345 | $char = $this->stream->char(); | ||
1346 | |||
1347 | if($char === '>') { | ||
1348 | /* U+003E GREATER-THAN SIGN (>) | ||
1349 | Emit the comment token. Switch to the data state. */ | ||
1350 | $this->emitToken($this->token); | ||
1351 | $state = 'data'; | ||
1352 | |||
1353 | } elseif($char === '-') { | ||
1354 | /* U+002D HYPHEN-MINUS (-) | ||
1355 | Parse error. Append a U+002D HYPHEN-MINUS (-) character | ||
1356 | to the comment token's data. Stay in the comment end | ||
1357 | state. */ | ||
1358 | $this->emitToken(array( | ||
1359 | 'type' => self::PARSEERROR, | ||
1360 | 'data' => 'unexpected-dash-after-double-dash-in-comment' | ||
1361 | )); | ||
1362 | $this->token['data'] .= '-'; | ||
1363 | |||
1364 | } elseif($char === "\t" || $char === "\n" || $char === "\x0a" || $char === ' ') { | ||
1365 | $this->emitToken(array( | ||
1366 | 'type' => self::PARSEERROR, | ||
1367 | 'data' => 'unexpected-space-after-double-dash-in-comment' | ||
1368 | )); | ||
1369 | $this->token['data'] .= '--' . $char; | ||
1370 | $state = 'comment end space'; | ||
1371 | |||
1372 | } elseif($char === '!') { | ||
1373 | $this->emitToken(array( | ||
1374 | 'type' => self::PARSEERROR, | ||
1375 | 'data' => 'unexpected-bang-after-double-dash-in-comment' | ||
1376 | )); | ||
1377 | $state = 'comment end bang'; | ||
1378 | |||
1379 | } elseif($char === false) { | ||
1380 | /* EOF | ||
1381 | Parse error. Emit the comment token. Reconsume the | ||
1382 | EOF character in the data state. */ | ||
1383 | $this->emitToken(array( | ||
1384 | 'type' => self::PARSEERROR, | ||
1385 | 'data' => 'eof-in-comment-double-dash' | ||
1386 | )); | ||
1387 | $this->emitToken($this->token); | ||
1388 | $this->stream->unget(); | ||
1389 | $state = 'data'; | ||
1390 | |||
1391 | } else { | ||
1392 | /* Anything else | ||
1393 | Parse error. Append two U+002D HYPHEN-MINUS (-) | ||
1394 | characters and the input character to the comment token's | ||
1395 | data. Switch to the comment state. */ | ||
1396 | $this->emitToken(array( | ||
1397 | 'type' => self::PARSEERROR, | ||
1398 | 'data' => 'unexpected-char-in-comment' | ||
1399 | )); | ||
1400 | $this->token['data'] .= '--'.$char; | ||
1401 | $state = 'comment'; | ||
1402 | } | ||
1403 | break; | ||
1404 | |||
1405 | case 'comment end bang': | ||
1406 | $char = $this->stream->char(); | ||
1407 | if ($char === '>') { | ||
1408 | $this->emitToken($this->token); | ||
1409 | $state = 'data'; | ||
1410 | } elseif ($char === "-") { | ||
1411 | $this->token['data'] .= '--!'; | ||
1412 | $state = 'comment end dash'; | ||
1413 | } elseif ($char === false) { | ||
1414 | $this->emitToken(array( | ||
1415 | 'type' => self::PARSEERROR, | ||
1416 | 'data' => 'eof-in-comment-end-bang' | ||
1417 | )); | ||
1418 | $this->emitToken($this->token); | ||
1419 | $this->stream->unget(); | ||
1420 | $state = 'data'; | ||
1421 | } else { | ||
1422 | $this->token['data'] .= '--!' . $char; | ||
1423 | $state = 'comment'; | ||
1424 | } | ||
1425 | break; | ||
1426 | |||
1427 | case 'comment end space': | ||
1428 | $char = $this->stream->char(); | ||
1429 | if ($char === '>') { | ||
1430 | $this->emitToken($this->token); | ||
1431 | $state = 'data'; | ||
1432 | } elseif ($char === '-') { | ||
1433 | $state = 'comment end dash'; | ||
1434 | } elseif ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1435 | $this->token['data'] .= $char; | ||
1436 | } elseif ($char === false) { | ||
1437 | $this->emitToken(array( | ||
1438 | 'type' => self::PARSEERROR, | ||
1439 | 'data' => 'unexpected-eof-in-comment-end-space', | ||
1440 | )); | ||
1441 | $this->emitToken($this->token); | ||
1442 | $this->stream->unget(); | ||
1443 | $state = 'data'; | ||
1444 | } else { | ||
1445 | $this->token['data'] .= $char; | ||
1446 | $state = 'comment'; | ||
1447 | } | ||
1448 | break; | ||
1449 | |||
1450 | case 'DOCTYPE': | ||
1451 | /* Consume the next input character: */ | ||
1452 | $char = $this->stream->char(); | ||
1453 | |||
1454 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1455 | /* U+0009 CHARACTER TABULATION | ||
1456 | U+000A LINE FEED (LF) | ||
1457 | U+000C FORM FEED (FF) | ||
1458 | U+0020 SPACE | ||
1459 | Switch to the before DOCTYPE name state. */ | ||
1460 | $state = 'before DOCTYPE name'; | ||
1461 | |||
1462 | } elseif($char === false) { | ||
1463 | /* EOF | ||
1464 | Parse error. Create a new DOCTYPE token. Set its | ||
1465 | force-quirks flag to on. Emit the token. Reconsume the | ||
1466 | EOF character in the data state. */ | ||
1467 | $this->emitToken(array( | ||
1468 | 'type' => self::PARSEERROR, | ||
1469 | 'data' => 'need-space-after-doctype-but-got-eof' | ||
1470 | )); | ||
1471 | $this->emitToken(array( | ||
1472 | 'name' => '', | ||
1473 | 'type' => self::DOCTYPE, | ||
1474 | 'force-quirks' => true, | ||
1475 | 'error' => true | ||
1476 | )); | ||
1477 | $this->stream->unget(); | ||
1478 | $state = 'data'; | ||
1479 | |||
1480 | } else { | ||
1481 | /* Anything else | ||
1482 | Parse error. Reconsume the current character in the | ||
1483 | before DOCTYPE name state. */ | ||
1484 | $this->emitToken(array( | ||
1485 | 'type' => self::PARSEERROR, | ||
1486 | 'data' => 'need-space-after-doctype' | ||
1487 | )); | ||
1488 | $this->stream->unget(); | ||
1489 | $state = 'before DOCTYPE name'; | ||
1490 | } | ||
1491 | break; | ||
1492 | |||
1493 | case 'before DOCTYPE name': | ||
1494 | /* Consume the next input character: */ | ||
1495 | $char = $this->stream->char(); | ||
1496 | |||
1497 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1498 | /* U+0009 CHARACTER TABULATION | ||
1499 | U+000A LINE FEED (LF) | ||
1500 | U+000C FORM FEED (FF) | ||
1501 | U+0020 SPACE | ||
1502 | Stay in the before DOCTYPE name state. */ | ||
1503 | |||
1504 | } elseif($char === '>') { | ||
1505 | /* U+003E GREATER-THAN SIGN (>) | ||
1506 | Parse error. Create a new DOCTYPE token. Set its | ||
1507 | force-quirks flag to on. Emit the token. Switch to the | ||
1508 | data state. */ | ||
1509 | $this->emitToken(array( | ||
1510 | 'type' => self::PARSEERROR, | ||
1511 | 'data' => 'expected-doctype-name-but-got-right-bracket' | ||
1512 | )); | ||
1513 | $this->emitToken(array( | ||
1514 | 'name' => '', | ||
1515 | 'type' => self::DOCTYPE, | ||
1516 | 'force-quirks' => true, | ||
1517 | 'error' => true | ||
1518 | )); | ||
1519 | |||
1520 | $state = 'data'; | ||
1521 | |||
1522 | } elseif('A' <= $char && $char <= 'Z') { | ||
1523 | /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z | ||
1524 | Create a new DOCTYPE token. Set the token's name to the | ||
1525 | lowercase version of the input character (add 0x0020 to | ||
1526 | the character's code point). Switch to the DOCTYPE name | ||
1527 | state. */ | ||
1528 | $this->token = array( | ||
1529 | 'name' => strtolower($char), | ||
1530 | 'type' => self::DOCTYPE, | ||
1531 | 'error' => true | ||
1532 | ); | ||
1533 | |||
1534 | $state = 'DOCTYPE name'; | ||
1535 | |||
1536 | } elseif($char === false) { | ||
1537 | /* EOF | ||
1538 | Parse error. Create a new DOCTYPE token. Set its | ||
1539 | force-quirks flag to on. Emit the token. Reconsume the | ||
1540 | EOF character in the data state. */ | ||
1541 | $this->emitToken(array( | ||
1542 | 'type' => self::PARSEERROR, | ||
1543 | 'data' => 'expected-doctype-name-but-got-eof' | ||
1544 | )); | ||
1545 | $this->emitToken(array( | ||
1546 | 'name' => '', | ||
1547 | 'type' => self::DOCTYPE, | ||
1548 | 'force-quirks' => true, | ||
1549 | 'error' => true | ||
1550 | )); | ||
1551 | |||
1552 | $this->stream->unget(); | ||
1553 | $state = 'data'; | ||
1554 | |||
1555 | } else { | ||
1556 | /* Anything else | ||
1557 | Create a new DOCTYPE token. Set the token's name to the | ||
1558 | current input character. Switch to the DOCTYPE name state. */ | ||
1559 | $this->token = array( | ||
1560 | 'name' => $char, | ||
1561 | 'type' => self::DOCTYPE, | ||
1562 | 'error' => true | ||
1563 | ); | ||
1564 | |||
1565 | $state = 'DOCTYPE name'; | ||
1566 | } | ||
1567 | break; | ||
1568 | |||
1569 | case 'DOCTYPE name': | ||
1570 | /* Consume the next input character: */ | ||
1571 | $char = $this->stream->char(); | ||
1572 | |||
1573 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1574 | /* U+0009 CHARACTER TABULATION | ||
1575 | U+000A LINE FEED (LF) | ||
1576 | U+000C FORM FEED (FF) | ||
1577 | U+0020 SPACE | ||
1578 | Switch to the after DOCTYPE name state. */ | ||
1579 | $state = 'after DOCTYPE name'; | ||
1580 | |||
1581 | } elseif($char === '>') { | ||
1582 | /* U+003E GREATER-THAN SIGN (>) | ||
1583 | Emit the current DOCTYPE token. Switch to the data state. */ | ||
1584 | $this->emitToken($this->token); | ||
1585 | $state = 'data'; | ||
1586 | |||
1587 | } elseif('A' <= $char && $char <= 'Z') { | ||
1588 | /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z | ||
1589 | Append the lowercase version of the input character | ||
1590 | (add 0x0020 to the character's code point) to the current | ||
1591 | DOCTYPE token's name. Stay in the DOCTYPE name state. */ | ||
1592 | $this->token['name'] .= strtolower($char); | ||
1593 | |||
1594 | } elseif($char === false) { | ||
1595 | /* EOF | ||
1596 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1597 | to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1598 | character in the data state. */ | ||
1599 | $this->emitToken(array( | ||
1600 | 'type' => self::PARSEERROR, | ||
1601 | 'data' => 'eof-in-doctype-name' | ||
1602 | )); | ||
1603 | $this->token['force-quirks'] = true; | ||
1604 | $this->emitToken($this->token); | ||
1605 | $this->stream->unget(); | ||
1606 | $state = 'data'; | ||
1607 | |||
1608 | } else { | ||
1609 | /* Anything else | ||
1610 | Append the current input character to the current | ||
1611 | DOCTYPE token's name. Stay in the DOCTYPE name state. */ | ||
1612 | $this->token['name'] .= $char; | ||
1613 | } | ||
1614 | |||
1615 | // XXX this is probably some sort of quirks mode designation, | ||
1616 | // check tree-builder to be sure. In general 'error' needs | ||
1617 | // to be specc'ified, this probably means removing it at the end | ||
1618 | $this->token['error'] = ($this->token['name'] === 'HTML') | ||
1619 | ? false | ||
1620 | : true; | ||
1621 | break; | ||
1622 | |||
1623 | case 'after DOCTYPE name': | ||
1624 | /* Consume the next input character: */ | ||
1625 | $char = $this->stream->char(); | ||
1626 | |||
1627 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1628 | /* U+0009 CHARACTER TABULATION | ||
1629 | U+000A LINE FEED (LF) | ||
1630 | U+000C FORM FEED (FF) | ||
1631 | U+0020 SPACE | ||
1632 | Stay in the after DOCTYPE name state. */ | ||
1633 | |||
1634 | } elseif($char === '>') { | ||
1635 | /* U+003E GREATER-THAN SIGN (>) | ||
1636 | Emit the current DOCTYPE token. Switch to the data state. */ | ||
1637 | $this->emitToken($this->token); | ||
1638 | $state = 'data'; | ||
1639 | |||
1640 | } elseif($char === false) { | ||
1641 | /* EOF | ||
1642 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1643 | to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1644 | character in the data state. */ | ||
1645 | $this->emitToken(array( | ||
1646 | 'type' => self::PARSEERROR, | ||
1647 | 'data' => 'eof-in-doctype' | ||
1648 | )); | ||
1649 | $this->token['force-quirks'] = true; | ||
1650 | $this->emitToken($this->token); | ||
1651 | $this->stream->unget(); | ||
1652 | $state = 'data'; | ||
1653 | |||
1654 | } else { | ||
1655 | /* Anything else */ | ||
1656 | |||
1657 | $nextSix = strtoupper($char . $this->stream->charsWhile(self::ALPHA, 5)); | ||
1658 | if ($nextSix === 'PUBLIC') { | ||
1659 | /* If the next six characters are an ASCII | ||
1660 | case-insensitive match for the word "PUBLIC", then | ||
1661 | consume those characters and switch to the before | ||
1662 | DOCTYPE public identifier state. */ | ||
1663 | $state = 'before DOCTYPE public identifier'; | ||
1664 | |||
1665 | } elseif ($nextSix === 'SYSTEM') { | ||
1666 | /* Otherwise, if the next six characters are an ASCII | ||
1667 | case-insensitive match for the word "SYSTEM", then | ||
1668 | consume those characters and switch to the before | ||
1669 | DOCTYPE system identifier state. */ | ||
1670 | $state = 'before DOCTYPE system identifier'; | ||
1671 | |||
1672 | } else { | ||
1673 | /* Otherwise, this is the parse error. Set the DOCTYPE | ||
1674 | token's force-quirks flag to on. Switch to the bogus | ||
1675 | DOCTYPE state. */ | ||
1676 | $this->emitToken(array( | ||
1677 | 'type' => self::PARSEERROR, | ||
1678 | 'data' => 'expected-space-or-right-bracket-in-doctype' | ||
1679 | )); | ||
1680 | $this->token['force-quirks'] = true; | ||
1681 | $this->token['error'] = true; | ||
1682 | $state = 'bogus DOCTYPE'; | ||
1683 | } | ||
1684 | } | ||
1685 | break; | ||
1686 | |||
1687 | case 'before DOCTYPE public identifier': | ||
1688 | /* Consume the next input character: */ | ||
1689 | $char = $this->stream->char(); | ||
1690 | |||
1691 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1692 | /* U+0009 CHARACTER TABULATION | ||
1693 | U+000A LINE FEED (LF) | ||
1694 | U+000C FORM FEED (FF) | ||
1695 | U+0020 SPACE | ||
1696 | Stay in the before DOCTYPE public identifier state. */ | ||
1697 | } elseif ($char === '"') { | ||
1698 | /* U+0022 QUOTATION MARK (") | ||
1699 | Set the DOCTYPE token's public identifier to the empty | ||
1700 | string (not missing), then switch to the DOCTYPE public | ||
1701 | identifier (double-quoted) state. */ | ||
1702 | $this->token['public'] = ''; | ||
1703 | $state = 'DOCTYPE public identifier (double-quoted)'; | ||
1704 | } elseif ($char === "'") { | ||
1705 | /* U+0027 APOSTROPHE (') | ||
1706 | Set the DOCTYPE token's public identifier to the empty | ||
1707 | string (not missing), then switch to the DOCTYPE public | ||
1708 | identifier (single-quoted) state. */ | ||
1709 | $this->token['public'] = ''; | ||
1710 | $state = 'DOCTYPE public identifier (single-quoted)'; | ||
1711 | } elseif ($char === '>') { | ||
1712 | /* Parse error. Set the DOCTYPE token's force-quirks flag | ||
1713 | to on. Emit that DOCTYPE token. Switch to the data state. */ | ||
1714 | $this->emitToken(array( | ||
1715 | 'type' => self::PARSEERROR, | ||
1716 | 'data' => 'unexpected-end-of-doctype' | ||
1717 | )); | ||
1718 | $this->token['force-quirks'] = true; | ||
1719 | $this->emitToken($this->token); | ||
1720 | $state = 'data'; | ||
1721 | } elseif ($char === false) { | ||
1722 | /* Parse error. Set the DOCTYPE token's force-quirks | ||
1723 | flag to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1724 | character in the data state. */ | ||
1725 | $this->emitToken(array( | ||
1726 | 'type' => self::PARSEERROR, | ||
1727 | 'data' => 'eof-in-doctype' | ||
1728 | )); | ||
1729 | $this->token['force-quirks'] = true; | ||
1730 | $this->emitToken($this->token); | ||
1731 | $this->stream->unget(); | ||
1732 | $state = 'data'; | ||
1733 | } else { | ||
1734 | /* Parse error. Set the DOCTYPE token's force-quirks flag | ||
1735 | to on. Switch to the bogus DOCTYPE state. */ | ||
1736 | $this->emitToken(array( | ||
1737 | 'type' => self::PARSEERROR, | ||
1738 | 'data' => 'unexpected-char-in-doctype' | ||
1739 | )); | ||
1740 | $this->token['force-quirks'] = true; | ||
1741 | $state = 'bogus DOCTYPE'; | ||
1742 | } | ||
1743 | break; | ||
1744 | |||
1745 | case 'DOCTYPE public identifier (double-quoted)': | ||
1746 | /* Consume the next input character: */ | ||
1747 | $char = $this->stream->char(); | ||
1748 | |||
1749 | if ($char === '"') { | ||
1750 | /* U+0022 QUOTATION MARK (") | ||
1751 | Switch to the after DOCTYPE public identifier state. */ | ||
1752 | $state = 'after DOCTYPE public identifier'; | ||
1753 | } elseif ($char === '>') { | ||
1754 | /* U+003E GREATER-THAN SIGN (>) | ||
1755 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1756 | to on. Emit that DOCTYPE token. Switch to the data state. */ | ||
1757 | $this->emitToken(array( | ||
1758 | 'type' => self::PARSEERROR, | ||
1759 | 'data' => 'unexpected-end-of-doctype' | ||
1760 | )); | ||
1761 | $this->token['force-quirks'] = true; | ||
1762 | $this->emitToken($this->token); | ||
1763 | $state = 'data'; | ||
1764 | } elseif ($char === false) { | ||
1765 | /* EOF | ||
1766 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1767 | to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1768 | character in the data state. */ | ||
1769 | $this->emitToken(array( | ||
1770 | 'type' => self::PARSEERROR, | ||
1771 | 'data' => 'eof-in-doctype' | ||
1772 | )); | ||
1773 | $this->token['force-quirks'] = true; | ||
1774 | $this->emitToken($this->token); | ||
1775 | $this->stream->unget(); | ||
1776 | $state = 'data'; | ||
1777 | } else { | ||
1778 | /* Anything else | ||
1779 | Append the current input character to the current | ||
1780 | DOCTYPE token's public identifier. Stay in the DOCTYPE | ||
1781 | public identifier (double-quoted) state. */ | ||
1782 | $this->token['public'] .= $char; | ||
1783 | } | ||
1784 | break; | ||
1785 | |||
1786 | case 'DOCTYPE public identifier (single-quoted)': | ||
1787 | /* Consume the next input character: */ | ||
1788 | $char = $this->stream->char(); | ||
1789 | |||
1790 | if ($char === "'") { | ||
1791 | /* U+0027 APOSTROPHE (') | ||
1792 | Switch to the after DOCTYPE public identifier state. */ | ||
1793 | $state = 'after DOCTYPE public identifier'; | ||
1794 | } elseif ($char === '>') { | ||
1795 | /* U+003E GREATER-THAN SIGN (>) | ||
1796 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1797 | to on. Emit that DOCTYPE token. Switch to the data state. */ | ||
1798 | $this->emitToken(array( | ||
1799 | 'type' => self::PARSEERROR, | ||
1800 | 'data' => 'unexpected-end-of-doctype' | ||
1801 | )); | ||
1802 | $this->token['force-quirks'] = true; | ||
1803 | $this->emitToken($this->token); | ||
1804 | $state = 'data'; | ||
1805 | } elseif ($char === false) { | ||
1806 | /* EOF | ||
1807 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1808 | to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1809 | character in the data state. */ | ||
1810 | $this->emitToken(array( | ||
1811 | 'type' => self::PARSEERROR, | ||
1812 | 'data' => 'eof-in-doctype' | ||
1813 | )); | ||
1814 | $this->token['force-quirks'] = true; | ||
1815 | $this->emitToken($this->token); | ||
1816 | $this->stream->unget(); | ||
1817 | $state = 'data'; | ||
1818 | } else { | ||
1819 | /* Anything else | ||
1820 | Append the current input character to the current | ||
1821 | DOCTYPE token's public identifier. Stay in the DOCTYPE | ||
1822 | public identifier (double-quoted) state. */ | ||
1823 | $this->token['public'] .= $char; | ||
1824 | } | ||
1825 | break; | ||
1826 | |||
1827 | case 'after DOCTYPE public identifier': | ||
1828 | /* Consume the next input character: */ | ||
1829 | $char = $this->stream->char(); | ||
1830 | |||
1831 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1832 | /* U+0009 CHARACTER TABULATION | ||
1833 | U+000A LINE FEED (LF) | ||
1834 | U+000C FORM FEED (FF) | ||
1835 | U+0020 SPACE | ||
1836 | Stay in the after DOCTYPE public identifier state. */ | ||
1837 | } elseif ($char === '"') { | ||
1838 | /* U+0022 QUOTATION MARK (") | ||
1839 | Set the DOCTYPE token's system identifier to the | ||
1840 | empty string (not missing), then switch to the DOCTYPE | ||
1841 | system identifier (double-quoted) state. */ | ||
1842 | $this->token['system'] = ''; | ||
1843 | $state = 'DOCTYPE system identifier (double-quoted)'; | ||
1844 | } elseif ($char === "'") { | ||
1845 | /* U+0027 APOSTROPHE (') | ||
1846 | Set the DOCTYPE token's system identifier to the | ||
1847 | empty string (not missing), then switch to the DOCTYPE | ||
1848 | system identifier (single-quoted) state. */ | ||
1849 | $this->token['system'] = ''; | ||
1850 | $state = 'DOCTYPE system identifier (single-quoted)'; | ||
1851 | } elseif ($char === '>') { | ||
1852 | /* U+003E GREATER-THAN SIGN (>) | ||
1853 | Emit the current DOCTYPE token. Switch to the data state. */ | ||
1854 | $this->emitToken($this->token); | ||
1855 | $state = 'data'; | ||
1856 | } elseif ($char === false) { | ||
1857 | /* Parse error. Set the DOCTYPE token's force-quirks | ||
1858 | flag to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1859 | character in the data state. */ | ||
1860 | $this->emitToken(array( | ||
1861 | 'type' => self::PARSEERROR, | ||
1862 | 'data' => 'eof-in-doctype' | ||
1863 | )); | ||
1864 | $this->token['force-quirks'] = true; | ||
1865 | $this->emitToken($this->token); | ||
1866 | $this->stream->unget(); | ||
1867 | $state = 'data'; | ||
1868 | } else { | ||
1869 | /* Anything else | ||
1870 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1871 | to on. Switch to the bogus DOCTYPE state. */ | ||
1872 | $this->emitToken(array( | ||
1873 | 'type' => self::PARSEERROR, | ||
1874 | 'data' => 'unexpected-char-in-doctype' | ||
1875 | )); | ||
1876 | $this->token['force-quirks'] = true; | ||
1877 | $state = 'bogus DOCTYPE'; | ||
1878 | } | ||
1879 | break; | ||
1880 | |||
1881 | case 'before DOCTYPE system identifier': | ||
1882 | /* Consume the next input character: */ | ||
1883 | $char = $this->stream->char(); | ||
1884 | |||
1885 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
1886 | /* U+0009 CHARACTER TABULATION | ||
1887 | U+000A LINE FEED (LF) | ||
1888 | U+000C FORM FEED (FF) | ||
1889 | U+0020 SPACE | ||
1890 | Stay in the before DOCTYPE system identifier state. */ | ||
1891 | } elseif ($char === '"') { | ||
1892 | /* U+0022 QUOTATION MARK (") | ||
1893 | Set the DOCTYPE token's system identifier to the empty | ||
1894 | string (not missing), then switch to the DOCTYPE system | ||
1895 | identifier (double-quoted) state. */ | ||
1896 | $this->token['system'] = ''; | ||
1897 | $state = 'DOCTYPE system identifier (double-quoted)'; | ||
1898 | } elseif ($char === "'") { | ||
1899 | /* U+0027 APOSTROPHE (') | ||
1900 | Set the DOCTYPE token's system identifier to the empty | ||
1901 | string (not missing), then switch to the DOCTYPE system | ||
1902 | identifier (single-quoted) state. */ | ||
1903 | $this->token['system'] = ''; | ||
1904 | $state = 'DOCTYPE system identifier (single-quoted)'; | ||
1905 | } elseif ($char === '>') { | ||
1906 | /* Parse error. Set the DOCTYPE token's force-quirks flag | ||
1907 | to on. Emit that DOCTYPE token. Switch to the data state. */ | ||
1908 | $this->emitToken(array( | ||
1909 | 'type' => self::PARSEERROR, | ||
1910 | 'data' => 'unexpected-char-in-doctype' | ||
1911 | )); | ||
1912 | $this->token['force-quirks'] = true; | ||
1913 | $this->emitToken($this->token); | ||
1914 | $state = 'data'; | ||
1915 | } elseif ($char === false) { | ||
1916 | /* Parse error. Set the DOCTYPE token's force-quirks | ||
1917 | flag to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1918 | character in the data state. */ | ||
1919 | $this->emitToken(array( | ||
1920 | 'type' => self::PARSEERROR, | ||
1921 | 'data' => 'eof-in-doctype' | ||
1922 | )); | ||
1923 | $this->token['force-quirks'] = true; | ||
1924 | $this->emitToken($this->token); | ||
1925 | $this->stream->unget(); | ||
1926 | $state = 'data'; | ||
1927 | } else { | ||
1928 | /* Parse error. Set the DOCTYPE token's force-quirks flag | ||
1929 | to on. Switch to the bogus DOCTYPE state. */ | ||
1930 | $this->emitToken(array( | ||
1931 | 'type' => self::PARSEERROR, | ||
1932 | 'data' => 'unexpected-char-in-doctype' | ||
1933 | )); | ||
1934 | $this->token['force-quirks'] = true; | ||
1935 | $state = 'bogus DOCTYPE'; | ||
1936 | } | ||
1937 | break; | ||
1938 | |||
1939 | case 'DOCTYPE system identifier (double-quoted)': | ||
1940 | /* Consume the next input character: */ | ||
1941 | $char = $this->stream->char(); | ||
1942 | |||
1943 | if ($char === '"') { | ||
1944 | /* U+0022 QUOTATION MARK (") | ||
1945 | Switch to the after DOCTYPE system identifier state. */ | ||
1946 | $state = 'after DOCTYPE system identifier'; | ||
1947 | } elseif ($char === '>') { | ||
1948 | /* U+003E GREATER-THAN SIGN (>) | ||
1949 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1950 | to on. Emit that DOCTYPE token. Switch to the data state. */ | ||
1951 | $this->emitToken(array( | ||
1952 | 'type' => self::PARSEERROR, | ||
1953 | 'data' => 'unexpected-end-of-doctype' | ||
1954 | )); | ||
1955 | $this->token['force-quirks'] = true; | ||
1956 | $this->emitToken($this->token); | ||
1957 | $state = 'data'; | ||
1958 | } elseif ($char === false) { | ||
1959 | /* EOF | ||
1960 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1961 | to on. Emit that DOCTYPE token. Reconsume the EOF | ||
1962 | character in the data state. */ | ||
1963 | $this->emitToken(array( | ||
1964 | 'type' => self::PARSEERROR, | ||
1965 | 'data' => 'eof-in-doctype' | ||
1966 | )); | ||
1967 | $this->token['force-quirks'] = true; | ||
1968 | $this->emitToken($this->token); | ||
1969 | $this->stream->unget(); | ||
1970 | $state = 'data'; | ||
1971 | } else { | ||
1972 | /* Anything else | ||
1973 | Append the current input character to the current | ||
1974 | DOCTYPE token's system identifier. Stay in the DOCTYPE | ||
1975 | system identifier (double-quoted) state. */ | ||
1976 | $this->token['system'] .= $char; | ||
1977 | } | ||
1978 | break; | ||
1979 | |||
1980 | case 'DOCTYPE system identifier (single-quoted)': | ||
1981 | /* Consume the next input character: */ | ||
1982 | $char = $this->stream->char(); | ||
1983 | |||
1984 | if ($char === "'") { | ||
1985 | /* U+0027 APOSTROPHE (') | ||
1986 | Switch to the after DOCTYPE system identifier state. */ | ||
1987 | $state = 'after DOCTYPE system identifier'; | ||
1988 | } elseif ($char === '>') { | ||
1989 | /* U+003E GREATER-THAN SIGN (>) | ||
1990 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
1991 | to on. Emit that DOCTYPE token. Switch to the data state. */ | ||
1992 | $this->emitToken(array( | ||
1993 | 'type' => self::PARSEERROR, | ||
1994 | 'data' => 'unexpected-end-of-doctype' | ||
1995 | )); | ||
1996 | $this->token['force-quirks'] = true; | ||
1997 | $this->emitToken($this->token); | ||
1998 | $state = 'data'; | ||
1999 | } elseif ($char === false) { | ||
2000 | /* EOF | ||
2001 | Parse error. Set the DOCTYPE token's force-quirks flag | ||
2002 | to on. Emit that DOCTYPE token. Reconsume the EOF | ||
2003 | character in the data state. */ | ||
2004 | $this->emitToken(array( | ||
2005 | 'type' => self::PARSEERROR, | ||
2006 | 'data' => 'eof-in-doctype' | ||
2007 | )); | ||
2008 | $this->token['force-quirks'] = true; | ||
2009 | $this->emitToken($this->token); | ||
2010 | $this->stream->unget(); | ||
2011 | $state = 'data'; | ||
2012 | } else { | ||
2013 | /* Anything else | ||
2014 | Append the current input character to the current | ||
2015 | DOCTYPE token's system identifier. Stay in the DOCTYPE | ||
2016 | system identifier (double-quoted) state. */ | ||
2017 | $this->token['system'] .= $char; | ||
2018 | } | ||
2019 | break; | ||
2020 | |||
2021 | case 'after DOCTYPE system identifier': | ||
2022 | /* Consume the next input character: */ | ||
2023 | $char = $this->stream->char(); | ||
2024 | |||
2025 | if($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { | ||
2026 | /* U+0009 CHARACTER TABULATION | ||
2027 | U+000A LINE FEED (LF) | ||
2028 | U+000C FORM FEED (FF) | ||
2029 | U+0020 SPACE | ||
2030 | Stay in the after DOCTYPE system identifier state. */ | ||
2031 | } elseif ($char === '>') { | ||
2032 | /* U+003E GREATER-THAN SIGN (>) | ||
2033 | Emit the current DOCTYPE token. Switch to the data state. */ | ||
2034 | $this->emitToken($this->token); | ||
2035 | $state = 'data'; | ||
2036 | } elseif ($char === false) { | ||
2037 | /* Parse error. Set the DOCTYPE token's force-quirks | ||
2038 | flag to on. Emit that DOCTYPE token. Reconsume the EOF | ||
2039 | character in the data state. */ | ||
2040 | $this->emitToken(array( | ||
2041 | 'type' => self::PARSEERROR, | ||
2042 | 'data' => 'eof-in-doctype' | ||
2043 | )); | ||
2044 | $this->token['force-quirks'] = true; | ||
2045 | $this->emitToken($this->token); | ||
2046 | $this->stream->unget(); | ||
2047 | $state = 'data'; | ||
2048 | } else { | ||
2049 | /* Anything else | ||
2050 | Parse error. Switch to the bogus DOCTYPE state. | ||
2051 | (This does not set the DOCTYPE token's force-quirks | ||
2052 | flag to on.) */ | ||
2053 | $this->emitToken(array( | ||
2054 | 'type' => self::PARSEERROR, | ||
2055 | 'data' => 'unexpected-char-in-doctype' | ||
2056 | )); | ||
2057 | $state = 'bogus DOCTYPE'; | ||
2058 | } | ||
2059 | break; | ||
2060 | |||
2061 | case 'bogus DOCTYPE': | ||
2062 | /* Consume the next input character: */ | ||
2063 | $char = $this->stream->char(); | ||
2064 | |||
2065 | if ($char === '>') { | ||
2066 | /* U+003E GREATER-THAN SIGN (>) | ||
2067 | Emit the DOCTYPE token. Switch to the data state. */ | ||
2068 | $this->emitToken($this->token); | ||
2069 | $state = 'data'; | ||
2070 | |||
2071 | } elseif($char === false) { | ||
2072 | /* EOF | ||
2073 | Emit the DOCTYPE token. Reconsume the EOF character in | ||
2074 | the data state. */ | ||
2075 | $this->emitToken($this->token); | ||
2076 | $this->stream->unget(); | ||
2077 | $state = 'data'; | ||
2078 | |||
2079 | } else { | ||
2080 | /* Anything else | ||
2081 | Stay in the bogus DOCTYPE state. */ | ||
2082 | } | ||
2083 | break; | ||
2084 | |||
2085 | // case 'cdataSection': | ||
2086 | |||
2087 | } | ||
2088 | } | ||
2089 | } | ||
2090 | |||
2091 | /** | ||
2092 | * Returns a serialized representation of the tree. | ||
2093 | */ | ||
2094 | public function save() { | ||
2095 | return $this->tree->save(); | ||
2096 | } | ||
2097 | |||
2098 | /** | ||
2099 | * Returns the input stream. | ||
2100 | */ | ||
2101 | public function stream() { | ||
2102 | return $this->stream; | ||
2103 | } | ||
2104 | |||
2105 | private function consumeCharacterReference($allowed = false, $inattr = false) { | ||
2106 | // This goes quite far against spec, and is far closer to the Python | ||
2107 | // impl., mainly because we don't do the large unconsuming the spec | ||
2108 | // requires. | ||
2109 | |||
2110 | // All consumed characters. | ||
2111 | $chars = $this->stream->char(); | ||
2112 | |||
2113 | /* This section defines how to consume a character | ||
2114 | reference. This definition is used when parsing character | ||
2115 | references in text and in attributes. | ||
2116 | |||
2117 | The behavior depends on the identity of the next character | ||
2118 | (the one immediately after the U+0026 AMPERSAND character): */ | ||
2119 | |||
2120 | if ( | ||
2121 | $chars[0] === "\x09" || | ||
2122 | $chars[0] === "\x0A" || | ||
2123 | $chars[0] === "\x0C" || | ||
2124 | $chars[0] === "\x20" || | ||
2125 | $chars[0] === '<' || | ||
2126 | $chars[0] === '&' || | ||
2127 | $chars === false || | ||
2128 | $chars[0] === $allowed | ||
2129 | ) { | ||
2130 | /* U+0009 CHARACTER TABULATION | ||
2131 | U+000A LINE FEED (LF) | ||
2132 | U+000C FORM FEED (FF) | ||
2133 | U+0020 SPACE | ||
2134 | U+003C LESS-THAN SIGN | ||
2135 | U+0026 AMPERSAND | ||
2136 | EOF | ||
2137 | The additional allowed character, if there is one | ||
2138 | Not a character reference. No characters are consumed, | ||
2139 | and nothing is returned. (This is not an error, either.) */ | ||
2140 | // We already consumed, so unconsume. | ||
2141 | $this->stream->unget(); | ||
2142 | return '&'; | ||
2143 | } elseif ($chars[0] === '#') { | ||
2144 | /* Consume the U+0023 NUMBER SIGN. */ | ||
2145 | // Um, yeah, we already did that. | ||
2146 | /* The behavior further depends on the character after | ||
2147 | the U+0023 NUMBER SIGN: */ | ||
2148 | $chars .= $this->stream->char(); | ||
2149 | if (isset($chars[1]) && ($chars[1] === 'x' || $chars[1] === 'X')) { | ||
2150 | /* U+0078 LATIN SMALL LETTER X | ||
2151 | U+0058 LATIN CAPITAL LETTER X */ | ||
2152 | /* Consume the X. */ | ||
2153 | // Um, yeah, we already did that. | ||
2154 | /* Follow the steps below, but using the range of | ||
2155 | characters U+0030 DIGIT ZERO through to U+0039 DIGIT | ||
2156 | NINE, U+0061 LATIN SMALL LETTER A through to U+0066 | ||
2157 | LATIN SMALL LETTER F, and U+0041 LATIN CAPITAL LETTER | ||
2158 | A, through to U+0046 LATIN CAPITAL LETTER F (in other | ||
2159 | words, 0123456789, ABCDEF, abcdef). */ | ||
2160 | $char_class = self::HEX; | ||
2161 | /* When it comes to interpreting the | ||
2162 | number, interpret it as a hexadecimal number. */ | ||
2163 | $hex = true; | ||
2164 | } else { | ||
2165 | /* Anything else */ | ||
2166 | // Unconsume because we shouldn't have consumed this. | ||
2167 | $chars = $chars[0]; | ||
2168 | $this->stream->unget(); | ||
2169 | /* Follow the steps below, but using the range of | ||
2170 | characters U+0030 DIGIT ZERO through to U+0039 DIGIT | ||
2171 | NINE (i.e. just 0123456789). */ | ||
2172 | $char_class = self::DIGIT; | ||
2173 | /* When it comes to interpreting the number, | ||
2174 | interpret it as a decimal number. */ | ||
2175 | $hex = false; | ||
2176 | } | ||
2177 | |||
2178 | /* Consume as many characters as match the range of characters given above. */ | ||
2179 | $consumed = $this->stream->charsWhile($char_class); | ||
2180 | if ($consumed === '' || $consumed === false) { | ||
2181 | /* If no characters match the range, then don't consume | ||
2182 | any characters (and unconsume the U+0023 NUMBER SIGN | ||
2183 | character and, if appropriate, the X character). This | ||
2184 | is a parse error; nothing is returned. */ | ||
2185 | $this->emitToken(array( | ||
2186 | 'type' => self::PARSEERROR, | ||
2187 | 'data' => 'expected-numeric-entity' | ||
2188 | )); | ||
2189 | return '&' . $chars; | ||
2190 | } else { | ||
2191 | /* Otherwise, if the next character is a U+003B SEMICOLON, | ||
2192 | consume that too. If it isn't, there is a parse error. */ | ||
2193 | if ($this->stream->char() !== ';') { | ||
2194 | $this->stream->unget(); | ||
2195 | $this->emitToken(array( | ||
2196 | 'type' => self::PARSEERROR, | ||
2197 | 'data' => 'numeric-entity-without-semicolon' | ||
2198 | )); | ||
2199 | } | ||
2200 | |||
2201 | /* If one or more characters match the range, then take | ||
2202 | them all and interpret the string of characters as a number | ||
2203 | (either hexadecimal or decimal as appropriate). */ | ||
2204 | $codepoint = $hex ? hexdec($consumed) : (int) $consumed; | ||
2205 | |||
2206 | /* If that number is one of the numbers in the first column | ||
2207 | of the following table, then this is a parse error. Find the | ||
2208 | row with that number in the first column, and return a | ||
2209 | character token for the Unicode character given in the | ||
2210 | second column of that row. */ | ||
2211 | $new_codepoint = HTML5_Data::getRealCodepoint($codepoint); | ||
2212 | if ($new_codepoint) { | ||
2213 | $this->emitToken(array( | ||
2214 | 'type' => self::PARSEERROR, | ||
2215 | 'data' => 'illegal-windows-1252-entity' | ||
2216 | )); | ||
2217 | return HTML5_Data::utf8chr($new_codepoint); | ||
2218 | } else { | ||
2219 | /* Otherwise, if the number is greater than 0x10FFFF, then | ||
2220 | * this is a parse error. Return a U+FFFD REPLACEMENT | ||
2221 | * CHARACTER. */ | ||
2222 | if ($codepoint > 0x10FFFF) { | ||
2223 | $this->emitToken(array( | ||
2224 | 'type' => self::PARSEERROR, | ||
2225 | 'data' => 'overlong-character-entity' // XXX probably not correct | ||
2226 | )); | ||
2227 | return "\xEF\xBF\xBD"; | ||
2228 | } | ||
2229 | /* Otherwise, return a character token for the Unicode | ||
2230 | * character whose code point is that number. If the | ||
2231 | * number is in the range 0x0001 to 0x0008, 0x000E to | ||
2232 | * 0x001F, 0x007F to 0x009F, 0xD800 to 0xDFFF, 0xFDD0 to | ||
2233 | * 0xFDEF, or is one of 0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, | ||
2234 | * 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF, 0x4FFFE, | ||
2235 | * 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, | ||
2236 | * 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, | ||
2237 | * 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, | ||
2238 | * 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, | ||
2239 | * or 0x10FFFF, then this is a parse error. */ | ||
2240 | // && has higher precedence than || | ||
2241 | if ( | ||
2242 | $codepoint >= 0x0000 && $codepoint <= 0x0008 || | ||
2243 | $codepoint === 0x000B || | ||
2244 | $codepoint >= 0x000E && $codepoint <= 0x001F || | ||
2245 | $codepoint >= 0x007F && $codepoint <= 0x009F || | ||
2246 | $codepoint >= 0xD800 && $codepoint <= 0xDFFF || | ||
2247 | $codepoint >= 0xFDD0 && $codepoint <= 0xFDEF || | ||
2248 | ($codepoint & 0xFFFE) === 0xFFFE || | ||
2249 | $codepoint == 0x10FFFF || $codepoint == 0x10FFFE | ||
2250 | ) { | ||
2251 | $this->emitToken(array( | ||
2252 | 'type' => self::PARSEERROR, | ||
2253 | 'data' => 'illegal-codepoint-for-numeric-entity' | ||
2254 | )); | ||
2255 | } | ||
2256 | return HTML5_Data::utf8chr($codepoint); | ||
2257 | } | ||
2258 | } | ||
2259 | |||
2260 | } else { | ||
2261 | /* Anything else */ | ||
2262 | |||
2263 | /* Consume the maximum number of characters possible, | ||
2264 | with the consumed characters matching one of the | ||
2265 | identifiers in the first column of the named character | ||
2266 | references table (in a case-sensitive manner). */ | ||
2267 | // What we actually do here is consume as much as we can while it | ||
2268 | // matches the start of one of the identifiers in the first column. | ||
2269 | |||
2270 | $refs = HTML5_Data::getNamedCharacterReferences(); | ||
2271 | |||
2272 | // Get the longest string which is the start of an identifier | ||
2273 | // ($chars) as well as the longest identifier which matches ($id) | ||
2274 | // and its codepoint ($codepoint). | ||
2275 | $codepoint = false; | ||
2276 | $char = $chars; | ||
2277 | while ($char !== false && isset($refs[$char])) { | ||
2278 | $refs = $refs[$char]; | ||
2279 | if (isset($refs['codepoint'])) { | ||
2280 | $id = $chars; | ||
2281 | $codepoint = $refs['codepoint']; | ||
2282 | } | ||
2283 | $chars .= $char = $this->stream->char(); | ||
2284 | } | ||
2285 | |||
2286 | // Unconsume the one character we just took which caused the while | ||
2287 | // statement to fail. This could be anything and could cause state | ||
2288 | // changes (as if it matches the while loop it must be | ||
2289 | // alphanumeric so we can just concat it to whatever we get later). | ||
2290 | $this->stream->unget(); | ||
2291 | if ($char !== false) { | ||
2292 | $chars = substr($chars, 0, -1); | ||
2293 | } | ||
2294 | |||
2295 | /* If no match can be made, then this is a parse error. | ||
2296 | No characters are consumed, and nothing is returned. */ | ||
2297 | if (!$codepoint) { | ||
2298 | $this->emitToken(array( | ||
2299 | 'type' => self::PARSEERROR, | ||
2300 | 'data' => 'expected-named-entity' | ||
2301 | )); | ||
2302 | return '&' . $chars; | ||
2303 | } | ||
2304 | |||
2305 | /* If the last character matched is not a U+003B SEMICOLON | ||
2306 | (;), there is a parse error. */ | ||
2307 | $semicolon = true; | ||
2308 | if (substr($id, -1) !== ';') { | ||
2309 | $this->emitToken(array( | ||
2310 | 'type' => self::PARSEERROR, | ||
2311 | 'data' => 'named-entity-without-semicolon' | ||
2312 | )); | ||
2313 | $semicolon = false; | ||
2314 | } | ||
2315 | |||
2316 | /* If the character reference is being consumed as part of | ||
2317 | an attribute, and the last character matched is not a | ||
2318 | U+003B SEMICOLON (;), and the next character is in the | ||
2319 | range U+0030 DIGIT ZERO to U+0039 DIGIT NINE, U+0041 | ||
2320 | LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z, | ||
2321 | or U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z, | ||
2322 | then, for historical reasons, all the characters that were | ||
2323 | matched after the U+0026 AMPERSAND (&) must be unconsumed, | ||
2324 | and nothing is returned. */ | ||
2325 | if ($inattr && !$semicolon) { | ||
2326 | // The next character is either the next character in $chars or in the stream. | ||
2327 | if (strlen($chars) > strlen($id)) { | ||
2328 | $next = substr($chars, strlen($id), 1); | ||
2329 | } else { | ||
2330 | $next = $this->stream->char(); | ||
2331 | $this->stream->unget(); | ||
2332 | } | ||
2333 | if ( | ||
2334 | '0' <= $next && $next <= '9' || | ||
2335 | 'A' <= $next && $next <= 'Z' || | ||
2336 | 'a' <= $next && $next <= 'z' | ||
2337 | ) { | ||
2338 | return '&' . $chars; | ||
2339 | } | ||
2340 | } | ||
2341 | |||
2342 | /* Otherwise, return a character token for the character | ||
2343 | corresponding to the character reference name (as given | ||
2344 | by the second column of the named character references table). */ | ||
2345 | return HTML5_Data::utf8chr($codepoint) . substr($chars, strlen($id)); | ||
2346 | } | ||
2347 | } | ||
2348 | |||
2349 | private function characterReferenceInAttributeValue($allowed = false) { | ||
2350 | /* Attempt to consume a character reference. */ | ||
2351 | $entity = $this->consumeCharacterReference($allowed, true); | ||
2352 | |||
2353 | /* If nothing is returned, append a U+0026 AMPERSAND | ||
2354 | character to the current attribute's value. | ||
2355 | |||
2356 | Otherwise, append the returned character token to the | ||
2357 | current attribute's value. */ | ||
2358 | $char = (!$entity) | ||
2359 | ? '&' | ||
2360 | : $entity; | ||
2361 | |||
2362 | $last = count($this->token['attr']) - 1; | ||
2363 | $this->token['attr'][$last]['value'] .= $char; | ||
2364 | |||
2365 | /* Finally, switch back to the attribute value state that you | ||
2366 | were in when were switched into this state. */ | ||
2367 | } | ||
2368 | |||
2369 | /** | ||
2370 | * Emits a token, passing it on to the tree builder. | ||
2371 | */ | ||
2372 | protected function emitToken($token, $checkStream = true, $dry = false) { | ||
2373 | if ($checkStream) { | ||
2374 | // Emit errors from input stream. | ||
2375 | while ($this->stream->errors) { | ||
2376 | $this->emitToken(array_shift($this->stream->errors), false); | ||
2377 | } | ||
2378 | } | ||
2379 | if($token['type'] === self::ENDTAG && !empty($token['attr'])) { | ||
2380 | for ($i = 0; $i < count($token['attr']); $i++) { | ||
2381 | $this->emitToken(array( | ||
2382 | 'type' => self::PARSEERROR, | ||
2383 | 'data' => 'attributes-in-end-tag' | ||
2384 | )); | ||
2385 | } | ||
2386 | } | ||
2387 | if($token['type'] === self::ENDTAG && !empty($token['self-closing'])) { | ||
2388 | $this->emitToken(array( | ||
2389 | 'type' => self::PARSEERROR, | ||
2390 | 'data' => 'self-closing-flag-on-end-tag', | ||
2391 | )); | ||
2392 | } | ||
2393 | if($token['type'] === self::STARTTAG) { | ||
2394 | // This could be changed to actually pass the tree-builder a hash | ||
2395 | $hash = array(); | ||
2396 | foreach ($token['attr'] as $keypair) { | ||
2397 | if (isset($hash[$keypair['name']])) { | ||
2398 | $this->emitToken(array( | ||
2399 | 'type' => self::PARSEERROR, | ||
2400 | 'data' => 'duplicate-attribute', | ||
2401 | )); | ||
2402 | } else { | ||
2403 | $hash[$keypair['name']] = $keypair['value']; | ||
2404 | } | ||
2405 | } | ||
2406 | } | ||
2407 | |||
2408 | if(!$dry) { | ||
2409 | // the current structure of attributes is not a terribly good one | ||
2410 | $this->tree->emitToken($token); | ||
2411 | } | ||
2412 | |||
2413 | if(!$dry && is_int($this->tree->content_model)) { | ||
2414 | $this->content_model = $this->tree->content_model; | ||
2415 | $this->tree->content_model = null; | ||
2416 | |||
2417 | } elseif($token['type'] === self::ENDTAG) { | ||
2418 | $this->content_model = self::PCDATA; | ||
2419 | } | ||
2420 | } | ||
2421 | } | ||
2422 | |||
diff --git a/inc/3rdparty/libraries/html5/TreeBuilder.php b/inc/3rdparty/libraries/html5/TreeBuilder.php deleted file mode 100644 index c4a48b21..00000000 --- a/inc/3rdparty/libraries/html5/TreeBuilder.php +++ /dev/null | |||
@@ -1,3849 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | |||
5 | Copyright 2007 Jeroen van der Meer <http://jero.net/> | ||
6 | Copyright 2009 Edward Z. Yang <edwardzyang@thewritingpot.com> | ||
7 | |||
8 | Permission is hereby granted, free of charge, to any person obtaining a | ||
9 | copy of this software and associated documentation files (the | ||
10 | "Software"), to deal in the Software without restriction, including | ||
11 | without limitation the rights to use, copy, modify, merge, publish, | ||
12 | distribute, sublicense, and/or sell copies of the Software, and to | ||
13 | permit persons to whom the Software is furnished to do so, subject to | ||
14 | the following conditions: | ||
15 | |||
16 | The above copyright notice and this permission notice shall be included | ||
17 | in all copies or substantial portions of the Software. | ||
18 | |||
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
20 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
26 | |||
27 | */ | ||
28 | |||
29 | // Tags for FIX ME!!!: (in order of priority) | ||
30 | // XXX - should be fixed NAO! | ||
31 | // XERROR - with regards to parse errors | ||
32 | // XSCRIPT - with regards to scripting mode | ||
33 | // XENCODING - with regards to encoding (for reparsing tests) | ||
34 | // XDOM - DOM specific code (tagName is explicitly not marked). | ||
35 | // this is not (yet) in helper functions. | ||
36 | |||
37 | class HTML5_TreeBuilder { | ||
38 | public $stack = array(); | ||
39 | public $content_model; | ||
40 | |||
41 | private $mode; | ||
42 | private $original_mode; | ||
43 | private $secondary_mode; | ||
44 | private $dom; | ||
45 | // Whether or not normal insertion of nodes should actually foster | ||
46 | // parent (used in one case in spec) | ||
47 | private $foster_parent = false; | ||
48 | private $a_formatting = array(); | ||
49 | |||
50 | private $head_pointer = null; | ||
51 | private $form_pointer = null; | ||
52 | |||
53 | private $flag_frameset_ok = true; | ||
54 | private $flag_force_quirks = false; | ||
55 | private $ignored = false; | ||
56 | private $quirks_mode = null; | ||
57 | // this gets to 2 when we want to ignore the next lf character, and | ||
58 | // is decrement at the beginning of each processed token (this way, | ||
59 | // code can check for (bool)$ignore_lf_token, but it phases out | ||
60 | // appropriately) | ||
61 | private $ignore_lf_token = 0; | ||
62 | private $fragment = false; | ||
63 | private $root; | ||
64 | |||
65 | private $scoping = array('applet','button','caption','html','marquee','object','table','td','th', 'svg:foreignObject'); | ||
66 | private $formatting = array('a','b','big','code','em','font','i','nobr','s','small','strike','strong','tt','u'); | ||
67 | // dl and ds are speculative | ||
68 | private $special = array('address','area','article','aside','base','basefont','bgsound', | ||
69 | 'blockquote','body','br','center','col','colgroup','command','dc','dd','details','dir','div','dl','ds', | ||
70 | 'dt','embed','fieldset','figure','footer','form','frame','frameset','h1','h2','h3','h4','h5', | ||
71 | 'h6','head','header','hgroup','hr','iframe','img','input','isindex','li','link', | ||
72 | 'listing','menu','meta','nav','noembed','noframes','noscript','ol', | ||
73 | 'p','param','plaintext','pre','script','select','spacer','style', | ||
74 | 'tbody','textarea','tfoot','thead','title','tr','ul','wbr'); | ||
75 | |||
76 | private $pendingTableCharacters; | ||
77 | private $pendingTableCharactersDirty; | ||
78 | |||
79 | // Tree construction modes | ||
80 | const INITIAL = 0; | ||
81 | const BEFORE_HTML = 1; | ||
82 | const BEFORE_HEAD = 2; | ||
83 | const IN_HEAD = 3; | ||
84 | const IN_HEAD_NOSCRIPT = 4; | ||
85 | const AFTER_HEAD = 5; | ||
86 | const IN_BODY = 6; | ||
87 | const IN_CDATA_RCDATA = 7; | ||
88 | const IN_TABLE = 8; | ||
89 | const IN_TABLE_TEXT = 9; | ||
90 | const IN_CAPTION = 10; | ||
91 | const IN_COLUMN_GROUP = 11; | ||
92 | const IN_TABLE_BODY = 12; | ||
93 | const IN_ROW = 13; | ||
94 | const IN_CELL = 14; | ||
95 | const IN_SELECT = 15; | ||
96 | const IN_SELECT_IN_TABLE= 16; | ||
97 | const IN_FOREIGN_CONTENT= 17; | ||
98 | const AFTER_BODY = 18; | ||
99 | const IN_FRAMESET = 19; | ||
100 | const AFTER_FRAMESET = 20; | ||
101 | const AFTER_AFTER_BODY = 21; | ||
102 | const AFTER_AFTER_FRAMESET = 22; | ||
103 | |||
104 | /** | ||
105 | * Converts a magic number to a readable name. Use for debugging. | ||
106 | */ | ||
107 | private function strConst($number) { | ||
108 | static $lookup; | ||
109 | if (!$lookup) { | ||
110 | $lookup = array(); | ||
111 | $r = new ReflectionClass('HTML5_TreeBuilder'); | ||
112 | $consts = $r->getConstants(); | ||
113 | foreach ($consts as $const => $num) { | ||
114 | if (!is_int($num)) continue; | ||
115 | $lookup[$num] = $const; | ||
116 | } | ||
117 | } | ||
118 | return $lookup[$number]; | ||
119 | } | ||
120 | |||
121 | // The different types of elements. | ||
122 | const SPECIAL = 100; | ||
123 | const SCOPING = 101; | ||
124 | const FORMATTING = 102; | ||
125 | const PHRASING = 103; | ||
126 | |||
127 | // Quirks modes in $quirks_mode | ||
128 | const NO_QUIRKS = 200; | ||
129 | const QUIRKS_MODE = 201; | ||
130 | const LIMITED_QUIRKS_MODE = 202; | ||
131 | |||
132 | // Marker to be placed in $a_formatting | ||
133 | const MARKER = 300; | ||
134 | |||
135 | // Namespaces for foreign content | ||
136 | const NS_HTML = null; // to prevent DOM from requiring NS on everything | ||
137 | const NS_XHTML = 'http://www.w3.org/1999/xhtml'; | ||
138 | const NS_MATHML = 'http://www.w3.org/1998/Math/MathML'; | ||
139 | const NS_SVG = 'http://www.w3.org/2000/svg'; | ||
140 | const NS_XLINK = 'http://www.w3.org/1999/xlink'; | ||
141 | const NS_XML = 'http://www.w3.org/XML/1998/namespace'; | ||
142 | const NS_XMLNS = 'http://www.w3.org/2000/xmlns/'; | ||
143 | |||
144 | // Different types of scopes to test for elements | ||
145 | const SCOPE = 0; | ||
146 | const SCOPE_LISTITEM = 1; | ||
147 | const SCOPE_TABLE = 2; | ||
148 | |||
149 | public function __construct() { | ||
150 | $this->mode = self::INITIAL; | ||
151 | $this->dom = new DOMDocument; | ||
152 | |||
153 | $this->dom->encoding = 'UTF-8'; | ||
154 | $this->dom->preserveWhiteSpace = true; | ||
155 | $this->dom->substituteEntities = true; | ||
156 | $this->dom->strictErrorChecking = false; | ||
157 | } | ||
158 | |||
159 | // Process tag tokens | ||
160 | public function emitToken($token, $mode = null) { | ||
161 | // XXX: ignore parse errors... why are we emitting them, again? | ||
162 | if ($token['type'] === HTML5_Tokenizer::PARSEERROR) return; | ||
163 | if ($mode === null) $mode = $this->mode; | ||
164 | |||
165 | /* | ||
166 | $backtrace = debug_backtrace(); | ||
167 | if ($backtrace[1]['class'] !== 'HTML5_TreeBuilder') echo "--\n"; | ||
168 | echo $this->strConst($mode); | ||
169 | if ($this->original_mode) echo " (originally ".$this->strConst($this->original_mode).")"; | ||
170 | echo "\n "; | ||
171 | token_dump($token); | ||
172 | $this->printStack(); | ||
173 | $this->printActiveFormattingElements(); | ||
174 | if ($this->foster_parent) echo " -> this is a foster parent mode\n"; | ||
175 | if ($this->flag_frameset_ok) echo " -> frameset ok\n"; | ||
176 | */ | ||
177 | |||
178 | if ($this->ignore_lf_token) $this->ignore_lf_token--; | ||
179 | $this->ignored = false; | ||
180 | // indenting is a little wonky, this can be changed later on | ||
181 | switch ($mode) { | ||
182 | |||
183 | case self::INITIAL: | ||
184 | |||
185 | /* A character token that is one of U+0009 CHARACTER TABULATION, | ||
186 | * U+000A LINE FEED (LF), U+000C FORM FEED (FF), or U+0020 SPACE */ | ||
187 | if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
188 | /* Ignore the token. */ | ||
189 | $this->ignored = true; | ||
190 | } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
191 | if ( | ||
192 | $token['name'] !== 'html' || !empty($token['public']) || | ||
193 | !empty($token['system']) || $token !== 'about:legacy-compat' | ||
194 | ) { | ||
195 | /* If the DOCTYPE token's name is not a case-sensitive match | ||
196 | * for the string "html", or if the token's public identifier | ||
197 | * is not missing, or if the token's system identifier is | ||
198 | * neither missing nor a case-sensitive match for the string | ||
199 | * "about:legacy-compat", then there is a parse error (this | ||
200 | * is the DOCTYPE parse error). */ | ||
201 | // DOCTYPE parse error | ||
202 | } | ||
203 | /* Append a DocumentType node to the Document node, with the name | ||
204 | * attribute set to the name given in the DOCTYPE token, or the | ||
205 | * empty string if the name was missing; the publicId attribute | ||
206 | * set to the public identifier given in the DOCTYPE token, or | ||
207 | * the empty string if the public identifier was missing; the | ||
208 | * systemId attribute set to the system identifier given in the | ||
209 | * DOCTYPE token, or the empty string if the system identifier | ||
210 | * was missing; and the other attributes specific to | ||
211 | * DocumentType objects set to null and empty lists as | ||
212 | * appropriate. Associate the DocumentType node with the | ||
213 | * Document object so that it is returned as the value of the | ||
214 | * doctype attribute of the Document object. */ | ||
215 | if (!isset($token['public'])) $token['public'] = null; | ||
216 | if (!isset($token['system'])) $token['system'] = null; | ||
217 | // XDOM | ||
218 | // Yes this is hacky. I'm kind of annoyed that I can't appendChild | ||
219 | // a doctype to DOMDocument. Maybe I haven't chanted the right | ||
220 | // syllables. | ||
221 | $impl = new DOMImplementation(); | ||
222 | // This call can fail for particularly pathological cases (namely, | ||
223 | // the qualifiedName parameter ($token['name']) could be missing. | ||
224 | if ($token['name']) { | ||
225 | $doctype = $impl->createDocumentType($token['name'], $token['public'], $token['system']); | ||
226 | $this->dom->appendChild($doctype); | ||
227 | } else { | ||
228 | // It looks like libxml's not actually *able* to express this case. | ||
229 | // So... don't. | ||
230 | $this->dom->emptyDoctype = true; | ||
231 | } | ||
232 | $public = is_null($token['public']) ? false : strtolower($token['public']); | ||
233 | $system = is_null($token['system']) ? false : strtolower($token['system']); | ||
234 | $publicStartsWithForQuirks = array( | ||
235 | "+//silmaril//dtd html pro v0r11 19970101//", | ||
236 | "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", | ||
237 | "-//as//dtd html 3.0 aswedit + extensions//", | ||
238 | "-//ietf//dtd html 2.0 level 1//", | ||
239 | "-//ietf//dtd html 2.0 level 2//", | ||
240 | "-//ietf//dtd html 2.0 strict level 1//", | ||
241 | "-//ietf//dtd html 2.0 strict level 2//", | ||
242 | "-//ietf//dtd html 2.0 strict//", | ||
243 | "-//ietf//dtd html 2.0//", | ||
244 | "-//ietf//dtd html 2.1e//", | ||
245 | "-//ietf//dtd html 3.0//", | ||
246 | "-//ietf//dtd html 3.2 final//", | ||
247 | "-//ietf//dtd html 3.2//", | ||
248 | "-//ietf//dtd html 3//", | ||
249 | "-//ietf//dtd html level 0//", | ||
250 | "-//ietf//dtd html level 1//", | ||
251 | "-//ietf//dtd html level 2//", | ||
252 | "-//ietf//dtd html level 3//", | ||
253 | "-//ietf//dtd html strict level 0//", | ||
254 | "-//ietf//dtd html strict level 1//", | ||
255 | "-//ietf//dtd html strict level 2//", | ||
256 | "-//ietf//dtd html strict level 3//", | ||
257 | "-//ietf//dtd html strict//", | ||
258 | "-//ietf//dtd html//", | ||
259 | "-//metrius//dtd metrius presentational//", | ||
260 | "-//microsoft//dtd internet explorer 2.0 html strict//", | ||
261 | "-//microsoft//dtd internet explorer 2.0 html//", | ||
262 | "-//microsoft//dtd internet explorer 2.0 tables//", | ||
263 | "-//microsoft//dtd internet explorer 3.0 html strict//", | ||
264 | "-//microsoft//dtd internet explorer 3.0 html//", | ||
265 | "-//microsoft//dtd internet explorer 3.0 tables//", | ||
266 | "-//netscape comm. corp.//dtd html//", | ||
267 | "-//netscape comm. corp.//dtd strict html//", | ||
268 | "-//o'reilly and associates//dtd html 2.0//", | ||
269 | "-//o'reilly and associates//dtd html extended 1.0//", | ||
270 | "-//o'reilly and associates//dtd html extended relaxed 1.0//", | ||
271 | "-//spyglass//dtd html 2.0 extended//", | ||
272 | "-//sq//dtd html 2.0 hotmetal + extensions//", | ||
273 | "-//sun microsystems corp.//dtd hotjava html//", | ||
274 | "-//sun microsystems corp.//dtd hotjava strict html//", | ||
275 | "-//w3c//dtd html 3 1995-03-24//", | ||
276 | "-//w3c//dtd html 3.2 draft//", | ||
277 | "-//w3c//dtd html 3.2 final//", | ||
278 | "-//w3c//dtd html 3.2//", | ||
279 | "-//w3c//dtd html 3.2s draft//", | ||
280 | "-//w3c//dtd html 4.0 frameset//", | ||
281 | "-//w3c//dtd html 4.0 transitional//", | ||
282 | "-//w3c//dtd html experimental 19960712//", | ||
283 | "-//w3c//dtd html experimental 970421//", | ||
284 | "-//w3c//dtd w3 html//", | ||
285 | "-//w3o//dtd w3 html 3.0//", | ||
286 | "-//webtechs//dtd mozilla html 2.0//", | ||
287 | "-//webtechs//dtd mozilla html//", | ||
288 | ); | ||
289 | $publicSetToForQuirks = array( | ||
290 | "-//w3o//dtd w3 html strict 3.0//", | ||
291 | "-/w3c/dtd html 4.0 transitional/en", | ||
292 | "html", | ||
293 | ); | ||
294 | $publicStartsWithAndSystemForQuirks = array( | ||
295 | "-//w3c//dtd html 4.01 frameset//", | ||
296 | "-//w3c//dtd html 4.01 transitional//", | ||
297 | ); | ||
298 | $publicStartsWithForLimitedQuirks = array( | ||
299 | "-//w3c//dtd xhtml 1.0 frameset//", | ||
300 | "-//w3c//dtd xhtml 1.0 transitional//", | ||
301 | ); | ||
302 | $publicStartsWithAndSystemForLimitedQuirks = array( | ||
303 | "-//w3c//dtd html 4.01 frameset//", | ||
304 | "-//w3c//dtd html 4.01 transitional//", | ||
305 | ); | ||
306 | // first, do easy checks | ||
307 | if ( | ||
308 | !empty($token['force-quirks']) || | ||
309 | strtolower($token['name']) !== 'html' | ||
310 | ) { | ||
311 | $this->quirks_mode = self::QUIRKS_MODE; | ||
312 | } else { | ||
313 | do { | ||
314 | if ($system) { | ||
315 | foreach ($publicStartsWithAndSystemForQuirks as $x) { | ||
316 | if (strncmp($public, $x, strlen($x)) === 0) { | ||
317 | $this->quirks_mode = self::QUIRKS_MODE; | ||
318 | break; | ||
319 | } | ||
320 | } | ||
321 | if (!is_null($this->quirks_mode)) break; | ||
322 | foreach ($publicStartsWithAndSystemForLimitedQuirks as $x) { | ||
323 | if (strncmp($public, $x, strlen($x)) === 0) { | ||
324 | $this->quirks_mode = self::LIMITED_QUIRKS_MODE; | ||
325 | break; | ||
326 | } | ||
327 | } | ||
328 | if (!is_null($this->quirks_mode)) break; | ||
329 | } | ||
330 | foreach ($publicSetToForQuirks as $x) { | ||
331 | if ($public === $x) { | ||
332 | $this->quirks_mode = self::QUIRKS_MODE; | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | if (!is_null($this->quirks_mode)) break; | ||
337 | foreach ($publicStartsWithForLimitedQuirks as $x) { | ||
338 | if (strncmp($public, $x, strlen($x)) === 0) { | ||
339 | $this->quirks_mode = self::LIMITED_QUIRKS_MODE; | ||
340 | } | ||
341 | } | ||
342 | if (!is_null($this->quirks_mode)) break; | ||
343 | if ($system === "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") { | ||
344 | $this->quirks_mode = self::QUIRKS_MODE; | ||
345 | break; | ||
346 | } | ||
347 | foreach ($publicStartsWithForQuirks as $x) { | ||
348 | if (strncmp($public, $x, strlen($x)) === 0) { | ||
349 | $this->quirks_mode = self::QUIRKS_MODE; | ||
350 | break; | ||
351 | } | ||
352 | } | ||
353 | if (is_null($this->quirks_mode)) { | ||
354 | $this->quirks_mode = self::NO_QUIRKS; | ||
355 | } | ||
356 | } while (false); | ||
357 | } | ||
358 | $this->mode = self::BEFORE_HTML; | ||
359 | } else { | ||
360 | // parse error | ||
361 | /* Switch the insertion mode to "before html", then reprocess the | ||
362 | * current token. */ | ||
363 | $this->mode = self::BEFORE_HTML; | ||
364 | $this->quirks_mode = self::QUIRKS_MODE; | ||
365 | $this->emitToken($token); | ||
366 | } | ||
367 | break; | ||
368 | |||
369 | case self::BEFORE_HTML: | ||
370 | |||
371 | /* A DOCTYPE token */ | ||
372 | if($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
373 | // Parse error. Ignore the token. | ||
374 | $this->ignored = true; | ||
375 | |||
376 | /* A comment token */ | ||
377 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
378 | /* Append a Comment node to the Document object with the data | ||
379 | attribute set to the data given in the comment token. */ | ||
380 | // XDOM | ||
381 | $comment = $this->dom->createComment($token['data']); | ||
382 | $this->dom->appendChild($comment); | ||
383 | |||
384 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
385 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
386 | or U+0020 SPACE */ | ||
387 | } elseif($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
388 | /* Ignore the token. */ | ||
389 | $this->ignored = true; | ||
390 | |||
391 | /* A start tag whose tag name is "html" */ | ||
392 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] == 'html') { | ||
393 | /* Create an element for the token in the HTML namespace. Append it | ||
394 | * to the Document object. Put this element in the stack of open | ||
395 | * elements. */ | ||
396 | // XDOM | ||
397 | $html = $this->insertElement($token, false); | ||
398 | $this->dom->appendChild($html); | ||
399 | $this->stack[] = $html; | ||
400 | |||
401 | $this->mode = self::BEFORE_HEAD; | ||
402 | |||
403 | } else { | ||
404 | /* Create an html element. Append it to the Document object. Put | ||
405 | * this element in the stack of open elements. */ | ||
406 | // XDOM | ||
407 | $html = $this->dom->createElementNS(self::NS_HTML, 'html'); | ||
408 | $this->dom->appendChild($html); | ||
409 | $this->stack[] = $html; | ||
410 | |||
411 | /* Switch the insertion mode to "before head", then reprocess the | ||
412 | * current token. */ | ||
413 | $this->mode = self::BEFORE_HEAD; | ||
414 | $this->emitToken($token); | ||
415 | } | ||
416 | break; | ||
417 | |||
418 | case self::BEFORE_HEAD: | ||
419 | |||
420 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
421 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
422 | or U+0020 SPACE */ | ||
423 | if($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
424 | /* Ignore the token. */ | ||
425 | $this->ignored = true; | ||
426 | |||
427 | /* A comment token */ | ||
428 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
429 | /* Append a Comment node to the current node with the data attribute | ||
430 | set to the data given in the comment token. */ | ||
431 | $this->insertComment($token['data']); | ||
432 | |||
433 | /* A DOCTYPE token */ | ||
434 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
435 | /* Parse error. Ignore the token */ | ||
436 | $this->ignored = true; | ||
437 | // parse error | ||
438 | |||
439 | /* A start tag token with the tag name "html" */ | ||
440 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { | ||
441 | /* Process the token using the rules for the "in body" | ||
442 | * insertion mode. */ | ||
443 | $this->processWithRulesFor($token, self::IN_BODY); | ||
444 | |||
445 | /* A start tag token with the tag name "head" */ | ||
446 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'head') { | ||
447 | /* Insert an HTML element for the token. */ | ||
448 | $element = $this->insertElement($token); | ||
449 | |||
450 | /* Set the head element pointer to this new element node. */ | ||
451 | $this->head_pointer = $element; | ||
452 | |||
453 | /* Change the insertion mode to "in head". */ | ||
454 | $this->mode = self::IN_HEAD; | ||
455 | |||
456 | /* An end tag whose tag name is one of: "head", "body", "html", "br" */ | ||
457 | } elseif( | ||
458 | $token['type'] === HTML5_Tokenizer::ENDTAG && ( | ||
459 | $token['name'] === 'head' || $token['name'] === 'body' || | ||
460 | $token['name'] === 'html' || $token['name'] === 'br' | ||
461 | )) { | ||
462 | /* Act as if a start tag token with the tag name "head" and no | ||
463 | * attributes had been seen, then reprocess the current token. */ | ||
464 | $this->emitToken(array( | ||
465 | 'name' => 'head', | ||
466 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
467 | 'attr' => array() | ||
468 | )); | ||
469 | $this->emitToken($token); | ||
470 | |||
471 | /* Any other end tag */ | ||
472 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG) { | ||
473 | /* Parse error. Ignore the token. */ | ||
474 | $this->ignored = true; | ||
475 | |||
476 | } else { | ||
477 | /* Act as if a start tag token with the tag name "head" and no | ||
478 | * attributes had been seen, then reprocess the current token. | ||
479 | * Note: This will result in an empty head element being | ||
480 | * generated, with the current token being reprocessed in the | ||
481 | * "after head" insertion mode. */ | ||
482 | $this->emitToken(array( | ||
483 | 'name' => 'head', | ||
484 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
485 | 'attr' => array() | ||
486 | )); | ||
487 | $this->emitToken($token); | ||
488 | } | ||
489 | break; | ||
490 | |||
491 | case self::IN_HEAD: | ||
492 | |||
493 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
494 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
495 | or U+0020 SPACE. */ | ||
496 | if($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
497 | /* Insert the character into the current node. */ | ||
498 | $this->insertText($token['data']); | ||
499 | |||
500 | /* A comment token */ | ||
501 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
502 | /* Append a Comment node to the current node with the data attribute | ||
503 | set to the data given in the comment token. */ | ||
504 | $this->insertComment($token['data']); | ||
505 | |||
506 | /* A DOCTYPE token */ | ||
507 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
508 | /* Parse error. Ignore the token. */ | ||
509 | $this->ignored = true; | ||
510 | // parse error | ||
511 | |||
512 | /* A start tag whose tag name is "html" */ | ||
513 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
514 | $token['name'] === 'html') { | ||
515 | $this->processWithRulesFor($token, self::IN_BODY); | ||
516 | |||
517 | /* A start tag whose tag name is one of: "base", "command", "link" */ | ||
518 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
519 | ($token['name'] === 'base' || $token['name'] === 'command' || | ||
520 | $token['name'] === 'link')) { | ||
521 | /* Insert an HTML element for the token. Immediately pop the | ||
522 | * current node off the stack of open elements. */ | ||
523 | $this->insertElement($token); | ||
524 | array_pop($this->stack); | ||
525 | |||
526 | // YYY: Acknowledge the token's self-closing flag, if it is set. | ||
527 | |||
528 | /* A start tag whose tag name is "meta" */ | ||
529 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'meta') { | ||
530 | /* Insert an HTML element for the token. Immediately pop the | ||
531 | * current node off the stack of open elements. */ | ||
532 | $this->insertElement($token); | ||
533 | array_pop($this->stack); | ||
534 | |||
535 | // XERROR: Acknowledge the token's self-closing flag, if it is set. | ||
536 | |||
537 | // XENCODING: If the element has a charset attribute, and its value is a | ||
538 | // supported encoding, and the confidence is currently tentative, | ||
539 | // then change the encoding to the encoding given by the value of | ||
540 | // the charset attribute. | ||
541 | // | ||
542 | // Otherwise, if the element has a content attribute, and applying | ||
543 | // the algorithm for extracting an encoding from a Content-Type to | ||
544 | // its value returns a supported encoding encoding, and the | ||
545 | // confidence is currently tentative, then change the encoding to | ||
546 | // the encoding encoding. | ||
547 | |||
548 | /* A start tag with the tag name "title" */ | ||
549 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'title') { | ||
550 | $this->insertRCDATAElement($token); | ||
551 | |||
552 | /* A start tag whose tag name is "noscript", if the scripting flag is enabled, or | ||
553 | * A start tag whose tag name is one of: "noframes", "style" */ | ||
554 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
555 | ($token['name'] === 'noscript' || $token['name'] === 'noframes' || $token['name'] === 'style')) { | ||
556 | // XSCRIPT: Scripting flag not respected | ||
557 | $this->insertCDATAElement($token); | ||
558 | |||
559 | // XSCRIPT: Scripting flag disable not implemented | ||
560 | |||
561 | /* A start tag with the tag name "script" */ | ||
562 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'script') { | ||
563 | /* 1. Create an element for the token in the HTML namespace. */ | ||
564 | $node = $this->insertElement($token, false); | ||
565 | |||
566 | /* 2. Mark the element as being "parser-inserted" */ | ||
567 | // Uhhh... XSCRIPT | ||
568 | |||
569 | /* 3. If the parser was originally created for the HTML | ||
570 | * fragment parsing algorithm, then mark the script element as | ||
571 | * "already executed". (fragment case) */ | ||
572 | // ditto... XSCRIPT | ||
573 | |||
574 | /* 4. Append the new element to the current node and push it onto | ||
575 | * the stack of open elements. */ | ||
576 | end($this->stack)->appendChild($node); | ||
577 | $this->stack[] = $node; | ||
578 | // I guess we could squash these together | ||
579 | |||
580 | /* 6. Let the original insertion mode be the current insertion mode. */ | ||
581 | $this->original_mode = $this->mode; | ||
582 | /* 7. Switch the insertion mode to "in CDATA/RCDATA" */ | ||
583 | $this->mode = self::IN_CDATA_RCDATA; | ||
584 | /* 5. Switch the tokeniser's content model flag to the CDATA state. */ | ||
585 | $this->content_model = HTML5_Tokenizer::CDATA; | ||
586 | |||
587 | /* An end tag with the tag name "head" */ | ||
588 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'head') { | ||
589 | /* Pop the current node (which will be the head element) off the stack of open elements. */ | ||
590 | array_pop($this->stack); | ||
591 | |||
592 | /* Change the insertion mode to "after head". */ | ||
593 | $this->mode = self::AFTER_HEAD; | ||
594 | |||
595 | // Slight logic inversion here to minimize duplication | ||
596 | /* A start tag with the tag name "head". */ | ||
597 | /* An end tag whose tag name is not one of: "body", "html", "br" */ | ||
598 | } elseif(($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'head') || | ||
599 | ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] !== 'html' && | ||
600 | $token['name'] !== 'body' && $token['name'] !== 'br')) { | ||
601 | // Parse error. Ignore the token. | ||
602 | $this->ignored = true; | ||
603 | |||
604 | /* Anything else */ | ||
605 | } else { | ||
606 | /* Act as if an end tag token with the tag name "head" had been | ||
607 | * seen, and reprocess the current token. */ | ||
608 | $this->emitToken(array( | ||
609 | 'name' => 'head', | ||
610 | 'type' => HTML5_Tokenizer::ENDTAG | ||
611 | )); | ||
612 | |||
613 | /* Then, reprocess the current token. */ | ||
614 | $this->emitToken($token); | ||
615 | } | ||
616 | break; | ||
617 | |||
618 | case self::IN_HEAD_NOSCRIPT: | ||
619 | if ($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
620 | // parse error | ||
621 | } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { | ||
622 | $this->processWithRulesFor($token, self::IN_BODY); | ||
623 | } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'noscript') { | ||
624 | /* Pop the current node (which will be a noscript element) from the | ||
625 | * stack of open elements; the new current node will be a head | ||
626 | * element. */ | ||
627 | array_pop($this->stack); | ||
628 | $this->mode = self::IN_HEAD; | ||
629 | } elseif ( | ||
630 | ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) || | ||
631 | ($token['type'] === HTML5_Tokenizer::COMMENT) || | ||
632 | ($token['type'] === HTML5_Tokenizer::STARTTAG && ( | ||
633 | $token['name'] === 'link' || $token['name'] === 'meta' || | ||
634 | $token['name'] === 'noframes' || $token['name'] === 'style'))) { | ||
635 | $this->processWithRulesFor($token, self::IN_HEAD); | ||
636 | // inverted logic | ||
637 | } elseif ( | ||
638 | ($token['type'] === HTML5_Tokenizer::STARTTAG && ( | ||
639 | $token['name'] === 'head' || $token['name'] === 'noscript')) || | ||
640 | ($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
641 | $token['name'] !== 'br')) { | ||
642 | // parse error | ||
643 | } else { | ||
644 | // parse error | ||
645 | $this->emitToken(array( | ||
646 | 'type' => HTML5_Tokenizer::ENDTAG, | ||
647 | 'name' => 'noscript', | ||
648 | )); | ||
649 | $this->emitToken($token); | ||
650 | } | ||
651 | break; | ||
652 | |||
653 | case self::AFTER_HEAD: | ||
654 | /* Handle the token as follows: */ | ||
655 | |||
656 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
657 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
658 | or U+0020 SPACE */ | ||
659 | if($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
660 | /* Append the character to the current node. */ | ||
661 | $this->insertText($token['data']); | ||
662 | |||
663 | /* A comment token */ | ||
664 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
665 | /* Append a Comment node to the current node with the data attribute | ||
666 | set to the data given in the comment token. */ | ||
667 | $this->insertComment($token['data']); | ||
668 | |||
669 | } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
670 | // parse error | ||
671 | |||
672 | } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { | ||
673 | $this->processWithRulesFor($token, self::IN_BODY); | ||
674 | |||
675 | /* A start tag token with the tag name "body" */ | ||
676 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'body') { | ||
677 | $this->insertElement($token); | ||
678 | |||
679 | /* Set the frameset-ok flag to "not ok". */ | ||
680 | $this->flag_frameset_ok = false; | ||
681 | |||
682 | /* Change the insertion mode to "in body". */ | ||
683 | $this->mode = self::IN_BODY; | ||
684 | |||
685 | /* A start tag token with the tag name "frameset" */ | ||
686 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'frameset') { | ||
687 | /* Insert a frameset element for the token. */ | ||
688 | $this->insertElement($token); | ||
689 | |||
690 | /* Change the insertion mode to "in frameset". */ | ||
691 | $this->mode = self::IN_FRAMESET; | ||
692 | |||
693 | /* A start tag token whose tag name is one of: "base", "link", "meta", | ||
694 | "script", "style", "title" */ | ||
695 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'], | ||
696 | array('base', 'link', 'meta', 'noframes', 'script', 'style', 'title'))) { | ||
697 | // parse error | ||
698 | /* Push the node pointed to by the head element pointer onto the | ||
699 | * stack of open elements. */ | ||
700 | $this->stack[] = $this->head_pointer; | ||
701 | $this->processWithRulesFor($token, self::IN_HEAD); | ||
702 | array_splice($this->stack, array_search($this->head_pointer, $this->stack, true), 1); | ||
703 | |||
704 | // inversion of specification | ||
705 | } elseif( | ||
706 | ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'head') || | ||
707 | ($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
708 | $token['name'] !== 'body' && $token['name'] !== 'html' && | ||
709 | $token['name'] !== 'br')) { | ||
710 | // parse error | ||
711 | |||
712 | /* Anything else */ | ||
713 | } else { | ||
714 | $this->emitToken(array( | ||
715 | 'name' => 'body', | ||
716 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
717 | 'attr' => array() | ||
718 | )); | ||
719 | $this->flag_frameset_ok = true; | ||
720 | $this->emitToken($token); | ||
721 | } | ||
722 | break; | ||
723 | |||
724 | case self::IN_BODY: | ||
725 | /* Handle the token as follows: */ | ||
726 | |||
727 | switch($token['type']) { | ||
728 | /* A character token */ | ||
729 | case HTML5_Tokenizer::CHARACTER: | ||
730 | case HTML5_Tokenizer::SPACECHARACTER: | ||
731 | /* Reconstruct the active formatting elements, if any. */ | ||
732 | $this->reconstructActiveFormattingElements(); | ||
733 | |||
734 | /* Append the token's character to the current node. */ | ||
735 | $this->insertText($token['data']); | ||
736 | |||
737 | /* If the token is not one of U+0009 CHARACTER TABULATION, | ||
738 | * U+000A LINE FEED (LF), U+000C FORM FEED (FF), or U+0020 | ||
739 | * SPACE, then set the frameset-ok flag to "not ok". */ | ||
740 | // i.e., if any of the characters is not whitespace | ||
741 | if (strlen($token['data']) !== strspn($token['data'], HTML5_Tokenizer::WHITESPACE)) { | ||
742 | $this->flag_frameset_ok = false; | ||
743 | } | ||
744 | break; | ||
745 | |||
746 | /* A comment token */ | ||
747 | case HTML5_Tokenizer::COMMENT: | ||
748 | /* Append a Comment node to the current node with the data | ||
749 | attribute set to the data given in the comment token. */ | ||
750 | $this->insertComment($token['data']); | ||
751 | break; | ||
752 | |||
753 | case HTML5_Tokenizer::DOCTYPE: | ||
754 | // parse error | ||
755 | break; | ||
756 | |||
757 | case HTML5_Tokenizer::EOF: | ||
758 | // parse error | ||
759 | break; | ||
760 | |||
761 | case HTML5_Tokenizer::STARTTAG: | ||
762 | switch($token['name']) { | ||
763 | case 'html': | ||
764 | // parse error | ||
765 | /* For each attribute on the token, check to see if the | ||
766 | * attribute is already present on the top element of the | ||
767 | * stack of open elements. If it is not, add the attribute | ||
768 | * and its corresponding value to that element. */ | ||
769 | foreach($token['attr'] as $attr) { | ||
770 | if(!$this->stack[0]->hasAttribute($attr['name'])) { | ||
771 | $this->stack[0]->setAttribute($attr['name'], $attr['value']); | ||
772 | } | ||
773 | } | ||
774 | break; | ||
775 | |||
776 | case 'base': case 'command': case 'link': case 'meta': case 'noframes': | ||
777 | case 'script': case 'style': case 'title': | ||
778 | /* Process the token as if the insertion mode had been "in | ||
779 | head". */ | ||
780 | $this->processWithRulesFor($token, self::IN_HEAD); | ||
781 | break; | ||
782 | |||
783 | /* A start tag token with the tag name "body" */ | ||
784 | case 'body': | ||
785 | /* Parse error. If the second element on the stack of open | ||
786 | elements is not a body element, or, if the stack of open | ||
787 | elements has only one node on it, then ignore the token. | ||
788 | (fragment case) */ | ||
789 | if(count($this->stack) === 1 || $this->stack[1]->tagName !== 'body') { | ||
790 | $this->ignored = true; | ||
791 | // Ignore | ||
792 | |||
793 | /* Otherwise, for each attribute on the token, check to see | ||
794 | if the attribute is already present on the body element (the | ||
795 | second element) on the stack of open elements. If it is not, | ||
796 | add the attribute and its corresponding value to that | ||
797 | element. */ | ||
798 | } else { | ||
799 | foreach($token['attr'] as $attr) { | ||
800 | if(!$this->stack[1]->hasAttribute($attr['name'])) { | ||
801 | $this->stack[1]->setAttribute($attr['name'], $attr['value']); | ||
802 | } | ||
803 | } | ||
804 | } | ||
805 | break; | ||
806 | |||
807 | case 'frameset': | ||
808 | // parse error | ||
809 | /* If the second element on the stack of open elements is | ||
810 | * not a body element, or, if the stack of open elements | ||
811 | * has only one node on it, then ignore the token. | ||
812 | * (fragment case) */ | ||
813 | if(count($this->stack) === 1 || $this->stack[1]->tagName !== 'body') { | ||
814 | $this->ignored = true; | ||
815 | // Ignore | ||
816 | } elseif (!$this->flag_frameset_ok) { | ||
817 | $this->ignored = true; | ||
818 | // Ignore | ||
819 | } else { | ||
820 | /* 1. Remove the second element on the stack of open | ||
821 | * elements from its parent node, if it has one. */ | ||
822 | if($this->stack[1]->parentNode) { | ||
823 | $this->stack[1]->parentNode->removeChild($this->stack[1]); | ||
824 | } | ||
825 | |||
826 | /* 2. Pop all the nodes from the bottom of the stack of | ||
827 | * open elements, from the current node up to the root | ||
828 | * html element. */ | ||
829 | array_splice($this->stack, 1); | ||
830 | |||
831 | $this->insertElement($token); | ||
832 | $this->mode = self::IN_FRAMESET; | ||
833 | } | ||
834 | break; | ||
835 | |||
836 | // in spec, there is a diversion here | ||
837 | |||
838 | case 'address': case 'article': case 'aside': case 'blockquote': | ||
839 | case 'center': case 'datagrid': case 'details': case 'dir': | ||
840 | case 'div': case 'dl': case 'fieldset': case 'figure': case 'footer': | ||
841 | case 'header': case 'hgroup': case 'menu': case 'nav': | ||
842 | case 'ol': case 'p': case 'section': case 'ul': | ||
843 | /* If the stack of open elements has a p element in scope, | ||
844 | then act as if an end tag with the tag name p had been | ||
845 | seen. */ | ||
846 | if($this->elementInScope('p')) { | ||
847 | $this->emitToken(array( | ||
848 | 'name' => 'p', | ||
849 | 'type' => HTML5_Tokenizer::ENDTAG | ||
850 | )); | ||
851 | } | ||
852 | |||
853 | /* Insert an HTML element for the token. */ | ||
854 | $this->insertElement($token); | ||
855 | break; | ||
856 | |||
857 | /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4", | ||
858 | "h5", "h6" */ | ||
859 | case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': | ||
860 | /* If the stack of open elements has a p element in scope, | ||
861 | then act as if an end tag with the tag name p had been seen. */ | ||
862 | if($this->elementInScope('p')) { | ||
863 | $this->emitToken(array( | ||
864 | 'name' => 'p', | ||
865 | 'type' => HTML5_Tokenizer::ENDTAG | ||
866 | )); | ||
867 | } | ||
868 | |||
869 | /* If the current node is an element whose tag name is one | ||
870 | * of "h1", "h2", "h3", "h4", "h5", or "h6", then this is a | ||
871 | * parse error; pop the current node off the stack of open | ||
872 | * elements. */ | ||
873 | $peek = array_pop($this->stack); | ||
874 | if (in_array($peek->tagName, array("h1", "h2", "h3", "h4", "h5", "h6"))) { | ||
875 | // parse error | ||
876 | } else { | ||
877 | $this->stack[] = $peek; | ||
878 | } | ||
879 | |||
880 | /* Insert an HTML element for the token. */ | ||
881 | $this->insertElement($token); | ||
882 | break; | ||
883 | |||
884 | case 'pre': case 'listing': | ||
885 | /* If the stack of open elements has a p element in scope, | ||
886 | then act as if an end tag with the tag name p had been seen. */ | ||
887 | if($this->elementInScope('p')) { | ||
888 | $this->emitToken(array( | ||
889 | 'name' => 'p', | ||
890 | 'type' => HTML5_Tokenizer::ENDTAG | ||
891 | )); | ||
892 | } | ||
893 | $this->insertElement($token); | ||
894 | /* If the next token is a U+000A LINE FEED (LF) character | ||
895 | * token, then ignore that token and move on to the next | ||
896 | * one. (Newlines at the start of pre blocks are ignored as | ||
897 | * an authoring convenience.) */ | ||
898 | $this->ignore_lf_token = 2; | ||
899 | $this->flag_frameset_ok = false; | ||
900 | break; | ||
901 | |||
902 | /* A start tag whose tag name is "form" */ | ||
903 | case 'form': | ||
904 | /* If the form element pointer is not null, ignore the | ||
905 | token with a parse error. */ | ||
906 | if($this->form_pointer !== null) { | ||
907 | $this->ignored = true; | ||
908 | // Ignore. | ||
909 | |||
910 | /* Otherwise: */ | ||
911 | } else { | ||
912 | /* If the stack of open elements has a p element in | ||
913 | scope, then act as if an end tag with the tag name p | ||
914 | had been seen. */ | ||
915 | if($this->elementInScope('p')) { | ||
916 | $this->emitToken(array( | ||
917 | 'name' => 'p', | ||
918 | 'type' => HTML5_Tokenizer::ENDTAG | ||
919 | )); | ||
920 | } | ||
921 | |||
922 | /* Insert an HTML element for the token, and set the | ||
923 | form element pointer to point to the element created. */ | ||
924 | $element = $this->insertElement($token); | ||
925 | $this->form_pointer = $element; | ||
926 | } | ||
927 | break; | ||
928 | |||
929 | // condensed specification | ||
930 | case 'li': case 'dc': case 'dd': case 'ds': case 'dt': | ||
931 | /* 1. Set the frameset-ok flag to "not ok". */ | ||
932 | $this->flag_frameset_ok = false; | ||
933 | |||
934 | $stack_length = count($this->stack) - 1; | ||
935 | for($n = $stack_length; 0 <= $n; $n--) { | ||
936 | /* 2. Initialise node to be the current node (the | ||
937 | bottommost node of the stack). */ | ||
938 | $stop = false; | ||
939 | $node = $this->stack[$n]; | ||
940 | $cat = $this->getElementCategory($node); | ||
941 | |||
942 | // for case 'li': | ||
943 | /* 3. If node is an li element, then act as if an end | ||
944 | * tag with the tag name "li" had been seen, then jump | ||
945 | * to the last step. */ | ||
946 | // for case 'dc': case 'dd': case 'ds': case 'dt': | ||
947 | /* If node is a dc, dd, ds or dt element, then act as if an end | ||
948 | * tag with the same tag name as node had been seen, then | ||
949 | * jump to the last step. */ | ||
950 | if(($token['name'] === 'li' && $node->tagName === 'li') || | ||
951 | ($token['name'] !== 'li' && ($node->tagName == 'dc' || $node->tagName === 'dd' || $node->tagName == 'ds' || $node->tagName === 'dt'))) { // limited conditional | ||
952 | $this->emitToken(array( | ||
953 | 'type' => HTML5_Tokenizer::ENDTAG, | ||
954 | 'name' => $node->tagName, | ||
955 | )); | ||
956 | break; | ||
957 | } | ||
958 | |||
959 | /* 4. If node is not in the formatting category, and is | ||
960 | not in the phrasing category, and is not an address, | ||
961 | div or p element, then stop this algorithm. */ | ||
962 | if($cat !== self::FORMATTING && $cat !== self::PHRASING && | ||
963 | $node->tagName !== 'address' && $node->tagName !== 'div' && | ||
964 | $node->tagName !== 'p') { | ||
965 | break; | ||
966 | } | ||
967 | |||
968 | /* 5. Otherwise, set node to the previous entry in the | ||
969 | * stack of open elements and return to step 2. */ | ||
970 | } | ||
971 | |||
972 | /* 6. This is the last step. */ | ||
973 | |||
974 | /* If the stack of open elements has a p element in scope, | ||
975 | then act as if an end tag with the tag name p had been | ||
976 | seen. */ | ||
977 | if($this->elementInScope('p')) { | ||
978 | $this->emitToken(array( | ||
979 | 'name' => 'p', | ||
980 | 'type' => HTML5_Tokenizer::ENDTAG | ||
981 | )); | ||
982 | } | ||
983 | |||
984 | /* Finally, insert an HTML element with the same tag | ||
985 | name as the token's. */ | ||
986 | $this->insertElement($token); | ||
987 | break; | ||
988 | |||
989 | /* A start tag token whose tag name is "plaintext" */ | ||
990 | case 'plaintext': | ||
991 | /* If the stack of open elements has a p element in scope, | ||
992 | then act as if an end tag with the tag name p had been | ||
993 | seen. */ | ||
994 | if($this->elementInScope('p')) { | ||
995 | $this->emitToken(array( | ||
996 | 'name' => 'p', | ||
997 | 'type' => HTML5_Tokenizer::ENDTAG | ||
998 | )); | ||
999 | } | ||
1000 | |||
1001 | /* Insert an HTML element for the token. */ | ||
1002 | $this->insertElement($token); | ||
1003 | |||
1004 | $this->content_model = HTML5_Tokenizer::PLAINTEXT; | ||
1005 | break; | ||
1006 | |||
1007 | // more diversions | ||
1008 | |||
1009 | /* A start tag whose tag name is "a" */ | ||
1010 | case 'a': | ||
1011 | /* If the list of active formatting elements contains | ||
1012 | an element whose tag name is "a" between the end of the | ||
1013 | list and the last marker on the list (or the start of | ||
1014 | the list if there is no marker on the list), then this | ||
1015 | is a parse error; act as if an end tag with the tag name | ||
1016 | "a" had been seen, then remove that element from the list | ||
1017 | of active formatting elements and the stack of open | ||
1018 | elements if the end tag didn't already remove it (it | ||
1019 | might not have if the element is not in table scope). */ | ||
1020 | $leng = count($this->a_formatting); | ||
1021 | |||
1022 | for($n = $leng - 1; $n >= 0; $n--) { | ||
1023 | if($this->a_formatting[$n] === self::MARKER) { | ||
1024 | break; | ||
1025 | |||
1026 | } elseif($this->a_formatting[$n]->tagName === 'a') { | ||
1027 | $a = $this->a_formatting[$n]; | ||
1028 | $this->emitToken(array( | ||
1029 | 'name' => 'a', | ||
1030 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1031 | )); | ||
1032 | if (in_array($a, $this->a_formatting)) { | ||
1033 | $a_i = array_search($a, $this->a_formatting, true); | ||
1034 | if($a_i !== false) array_splice($this->a_formatting, $a_i, 1); | ||
1035 | } | ||
1036 | if (in_array($a, $this->stack)) { | ||
1037 | $a_i = array_search($a, $this->stack, true); | ||
1038 | if ($a_i !== false) array_splice($this->stack, $a_i, 1); | ||
1039 | } | ||
1040 | break; | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | /* Reconstruct the active formatting elements, if any. */ | ||
1045 | $this->reconstructActiveFormattingElements(); | ||
1046 | |||
1047 | /* Insert an HTML element for the token. */ | ||
1048 | $el = $this->insertElement($token); | ||
1049 | |||
1050 | /* Add that element to the list of active formatting | ||
1051 | elements. */ | ||
1052 | $this->a_formatting[] = $el; | ||
1053 | break; | ||
1054 | |||
1055 | case 'b': case 'big': case 'code': case 'em': case 'font': case 'i': | ||
1056 | case 's': case 'small': case 'strike': | ||
1057 | case 'strong': case 'tt': case 'u': | ||
1058 | /* Reconstruct the active formatting elements, if any. */ | ||
1059 | $this->reconstructActiveFormattingElements(); | ||
1060 | |||
1061 | /* Insert an HTML element for the token. */ | ||
1062 | $el = $this->insertElement($token); | ||
1063 | |||
1064 | /* Add that element to the list of active formatting | ||
1065 | elements. */ | ||
1066 | $this->a_formatting[] = $el; | ||
1067 | break; | ||
1068 | |||
1069 | case 'nobr': | ||
1070 | /* Reconstruct the active formatting elements, if any. */ | ||
1071 | $this->reconstructActiveFormattingElements(); | ||
1072 | |||
1073 | /* If the stack of open elements has a nobr element in | ||
1074 | * scope, then this is a parse error; act as if an end tag | ||
1075 | * with the tag name "nobr" had been seen, then once again | ||
1076 | * reconstruct the active formatting elements, if any. */ | ||
1077 | if ($this->elementInScope('nobr')) { | ||
1078 | $this->emitToken(array( | ||
1079 | 'name' => 'nobr', | ||
1080 | 'type' => HTML5_Tokenizer::ENDTAG, | ||
1081 | )); | ||
1082 | $this->reconstructActiveFormattingElements(); | ||
1083 | } | ||
1084 | |||
1085 | /* Insert an HTML element for the token. */ | ||
1086 | $el = $this->insertElement($token); | ||
1087 | |||
1088 | /* Add that element to the list of active formatting | ||
1089 | elements. */ | ||
1090 | $this->a_formatting[] = $el; | ||
1091 | break; | ||
1092 | |||
1093 | // another diversion | ||
1094 | |||
1095 | /* A start tag token whose tag name is "button" */ | ||
1096 | case 'button': | ||
1097 | /* If the stack of open elements has a button element in scope, | ||
1098 | then this is a parse error; act as if an end tag with the tag | ||
1099 | name "button" had been seen, then reprocess the token. (We don't | ||
1100 | do that. Unnecessary.) (I hope you're right! -- ezyang) */ | ||
1101 | if($this->elementInScope('button')) { | ||
1102 | $this->emitToken(array( | ||
1103 | 'name' => 'button', | ||
1104 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1105 | )); | ||
1106 | } | ||
1107 | |||
1108 | /* Reconstruct the active formatting elements, if any. */ | ||
1109 | $this->reconstructActiveFormattingElements(); | ||
1110 | |||
1111 | /* Insert an HTML element for the token. */ | ||
1112 | $this->insertElement($token); | ||
1113 | |||
1114 | /* Insert a marker at the end of the list of active | ||
1115 | formatting elements. */ | ||
1116 | $this->a_formatting[] = self::MARKER; | ||
1117 | |||
1118 | $this->flag_frameset_ok = false; | ||
1119 | break; | ||
1120 | |||
1121 | case 'applet': case 'marquee': case 'object': | ||
1122 | /* Reconstruct the active formatting elements, if any. */ | ||
1123 | $this->reconstructActiveFormattingElements(); | ||
1124 | |||
1125 | /* Insert an HTML element for the token. */ | ||
1126 | $this->insertElement($token); | ||
1127 | |||
1128 | /* Insert a marker at the end of the list of active | ||
1129 | formatting elements. */ | ||
1130 | $this->a_formatting[] = self::MARKER; | ||
1131 | |||
1132 | $this->flag_frameset_ok = false; | ||
1133 | break; | ||
1134 | |||
1135 | // spec diversion | ||
1136 | |||
1137 | /* A start tag whose tag name is "table" */ | ||
1138 | case 'table': | ||
1139 | /* If the Document is not set to quirks mode, and the | ||
1140 | * stack of open elements has a p element in scope, then | ||
1141 | * act as if an end tag with the tag name "p" had been | ||
1142 | * seen. */ | ||
1143 | if($this->quirks_mode !== self::QUIRKS_MODE && | ||
1144 | $this->elementInScope('p')) { | ||
1145 | $this->emitToken(array( | ||
1146 | 'name' => 'p', | ||
1147 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1148 | )); | ||
1149 | } | ||
1150 | |||
1151 | /* Insert an HTML element for the token. */ | ||
1152 | $this->insertElement($token); | ||
1153 | |||
1154 | $this->flag_frameset_ok = false; | ||
1155 | |||
1156 | /* Change the insertion mode to "in table". */ | ||
1157 | $this->mode = self::IN_TABLE; | ||
1158 | break; | ||
1159 | |||
1160 | /* A start tag whose tag name is one of: "area", "basefont", | ||
1161 | "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */ | ||
1162 | case 'area': case 'basefont': case 'bgsound': case 'br': | ||
1163 | case 'embed': case 'img': case 'input': case 'keygen': case 'spacer': | ||
1164 | case 'wbr': | ||
1165 | /* Reconstruct the active formatting elements, if any. */ | ||
1166 | $this->reconstructActiveFormattingElements(); | ||
1167 | |||
1168 | /* Insert an HTML element for the token. */ | ||
1169 | $this->insertElement($token); | ||
1170 | |||
1171 | /* Immediately pop the current node off the stack of open elements. */ | ||
1172 | array_pop($this->stack); | ||
1173 | |||
1174 | // YYY: Acknowledge the token's self-closing flag, if it is set. | ||
1175 | |||
1176 | $this->flag_frameset_ok = false; | ||
1177 | break; | ||
1178 | |||
1179 | case 'param': case 'source': | ||
1180 | /* Insert an HTML element for the token. */ | ||
1181 | $this->insertElement($token); | ||
1182 | |||
1183 | /* Immediately pop the current node off the stack of open elements. */ | ||
1184 | array_pop($this->stack); | ||
1185 | |||
1186 | // YYY: Acknowledge the token's self-closing flag, if it is set. | ||
1187 | break; | ||
1188 | |||
1189 | /* A start tag whose tag name is "hr" */ | ||
1190 | case 'hr': | ||
1191 | /* If the stack of open elements has a p element in scope, | ||
1192 | then act as if an end tag with the tag name p had been seen. */ | ||
1193 | if($this->elementInScope('p')) { | ||
1194 | $this->emitToken(array( | ||
1195 | 'name' => 'p', | ||
1196 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1197 | )); | ||
1198 | } | ||
1199 | |||
1200 | /* Insert an HTML element for the token. */ | ||
1201 | $this->insertElement($token); | ||
1202 | |||
1203 | /* Immediately pop the current node off the stack of open elements. */ | ||
1204 | array_pop($this->stack); | ||
1205 | |||
1206 | // YYY: Acknowledge the token's self-closing flag, if it is set. | ||
1207 | |||
1208 | $this->flag_frameset_ok = false; | ||
1209 | break; | ||
1210 | |||
1211 | /* A start tag whose tag name is "image" */ | ||
1212 | case 'image': | ||
1213 | /* Parse error. Change the token's tag name to "img" and | ||
1214 | reprocess it. (Don't ask.) */ | ||
1215 | $token['name'] = 'img'; | ||
1216 | $this->emitToken($token); | ||
1217 | break; | ||
1218 | |||
1219 | /* A start tag whose tag name is "isindex" */ | ||
1220 | case 'isindex': | ||
1221 | /* Parse error. */ | ||
1222 | |||
1223 | /* If the form element pointer is not null, | ||
1224 | then ignore the token. */ | ||
1225 | if($this->form_pointer === null) { | ||
1226 | /* Act as if a start tag token with the tag name "form" had | ||
1227 | been seen. */ | ||
1228 | /* If the token has an attribute called "action", set | ||
1229 | * the action attribute on the resulting form | ||
1230 | * element to the value of the "action" attribute of | ||
1231 | * the token. */ | ||
1232 | $attr = array(); | ||
1233 | $action = $this->getAttr($token, 'action'); | ||
1234 | if ($action !== false) { | ||
1235 | $attr[] = array('name' => 'action', 'value' => $action); | ||
1236 | } | ||
1237 | $this->emitToken(array( | ||
1238 | 'name' => 'form', | ||
1239 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
1240 | 'attr' => $attr | ||
1241 | )); | ||
1242 | |||
1243 | /* Act as if a start tag token with the tag name "hr" had | ||
1244 | been seen. */ | ||
1245 | $this->emitToken(array( | ||
1246 | 'name' => 'hr', | ||
1247 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
1248 | 'attr' => array() | ||
1249 | )); | ||
1250 | |||
1251 | /* Act as if a start tag token with the tag name "label" | ||
1252 | had been seen. */ | ||
1253 | $this->emitToken(array( | ||
1254 | 'name' => 'label', | ||
1255 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
1256 | 'attr' => array() | ||
1257 | )); | ||
1258 | |||
1259 | /* Act as if a stream of character tokens had been seen. */ | ||
1260 | $prompt = $this->getAttr($token, 'prompt'); | ||
1261 | if ($prompt === false) { | ||
1262 | $prompt = 'This is a searchable index. '. | ||
1263 | 'Insert your search keywords here: '; | ||
1264 | } | ||
1265 | $this->emitToken(array( | ||
1266 | 'data' => $prompt, | ||
1267 | 'type' => HTML5_Tokenizer::CHARACTER, | ||
1268 | )); | ||
1269 | |||
1270 | /* Act as if a start tag token with the tag name "input" | ||
1271 | had been seen, with all the attributes from the "isindex" | ||
1272 | token, except with the "name" attribute set to the value | ||
1273 | "isindex" (ignoring any explicit "name" attribute). */ | ||
1274 | $attr = array(); | ||
1275 | foreach ($token['attr'] as $keypair) { | ||
1276 | if ($keypair['name'] === 'name' || $keypair['name'] === 'action' || | ||
1277 | $keypair['name'] === 'prompt') continue; | ||
1278 | $attr[] = $keypair; | ||
1279 | } | ||
1280 | $attr[] = array('name' => 'name', 'value' => 'isindex'); | ||
1281 | |||
1282 | $this->emitToken(array( | ||
1283 | 'name' => 'input', | ||
1284 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
1285 | 'attr' => $attr | ||
1286 | )); | ||
1287 | |||
1288 | /* Act as if an end tag token with the tag name "label" | ||
1289 | had been seen. */ | ||
1290 | $this->emitToken(array( | ||
1291 | 'name' => 'label', | ||
1292 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1293 | )); | ||
1294 | |||
1295 | /* Act as if a start tag token with the tag name "hr" had | ||
1296 | been seen. */ | ||
1297 | $this->emitToken(array( | ||
1298 | 'name' => 'hr', | ||
1299 | 'type' => HTML5_Tokenizer::STARTTAG | ||
1300 | )); | ||
1301 | |||
1302 | /* Act as if an end tag token with the tag name "form" had | ||
1303 | been seen. */ | ||
1304 | $this->emitToken(array( | ||
1305 | 'name' => 'form', | ||
1306 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1307 | )); | ||
1308 | } else { | ||
1309 | $this->ignored = true; | ||
1310 | } | ||
1311 | break; | ||
1312 | |||
1313 | /* A start tag whose tag name is "textarea" */ | ||
1314 | case 'textarea': | ||
1315 | $this->insertElement($token); | ||
1316 | |||
1317 | /* If the next token is a U+000A LINE FEED (LF) | ||
1318 | * character token, then ignore that token and move on to | ||
1319 | * the next one. (Newlines at the start of textarea | ||
1320 | * elements are ignored as an authoring convenience.) | ||
1321 | * need flag, see also <pre> */ | ||
1322 | $this->ignore_lf_token = 2; | ||
1323 | |||
1324 | $this->original_mode = $this->mode; | ||
1325 | $this->flag_frameset_ok = false; | ||
1326 | $this->mode = self::IN_CDATA_RCDATA; | ||
1327 | |||
1328 | /* Switch the tokeniser's content model flag to the | ||
1329 | RCDATA state. */ | ||
1330 | $this->content_model = HTML5_Tokenizer::RCDATA; | ||
1331 | break; | ||
1332 | |||
1333 | /* A start tag token whose tag name is "xmp" */ | ||
1334 | case 'xmp': | ||
1335 | /* If the stack of open elements has a p element in | ||
1336 | scope, then act as if an end tag with the tag name | ||
1337 | "p" has been seen. */ | ||
1338 | if ($this->elementInScope('p')) { | ||
1339 | $this->emitToken(array( | ||
1340 | 'name' => 'p', | ||
1341 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1342 | )); | ||
1343 | } | ||
1344 | |||
1345 | /* Reconstruct the active formatting elements, if any. */ | ||
1346 | $this->reconstructActiveFormattingElements(); | ||
1347 | |||
1348 | $this->flag_frameset_ok = false; | ||
1349 | |||
1350 | $this->insertCDATAElement($token); | ||
1351 | break; | ||
1352 | |||
1353 | case 'iframe': | ||
1354 | $this->flag_frameset_ok = false; | ||
1355 | $this->insertCDATAElement($token); | ||
1356 | break; | ||
1357 | |||
1358 | case 'noembed': case 'noscript': | ||
1359 | // XSCRIPT: should check scripting flag | ||
1360 | $this->insertCDATAElement($token); | ||
1361 | break; | ||
1362 | |||
1363 | /* A start tag whose tag name is "select" */ | ||
1364 | case 'select': | ||
1365 | /* Reconstruct the active formatting elements, if any. */ | ||
1366 | $this->reconstructActiveFormattingElements(); | ||
1367 | |||
1368 | /* Insert an HTML element for the token. */ | ||
1369 | $this->insertElement($token); | ||
1370 | |||
1371 | $this->flag_frameset_ok = false; | ||
1372 | |||
1373 | /* If the insertion mode is one of in table", "in caption", | ||
1374 | * "in column group", "in table body", "in row", or "in | ||
1375 | * cell", then switch the insertion mode to "in select in | ||
1376 | * table". Otherwise, switch the insertion mode to "in | ||
1377 | * select". */ | ||
1378 | if ( | ||
1379 | $this->mode === self::IN_TABLE || $this->mode === self::IN_CAPTION || | ||
1380 | $this->mode === self::IN_COLUMN_GROUP || $this->mode ==+self::IN_TABLE_BODY || | ||
1381 | $this->mode === self::IN_ROW || $this->mode === self::IN_CELL | ||
1382 | ) { | ||
1383 | $this->mode = self::IN_SELECT_IN_TABLE; | ||
1384 | } else { | ||
1385 | $this->mode = self::IN_SELECT; | ||
1386 | } | ||
1387 | break; | ||
1388 | |||
1389 | case 'option': case 'optgroup': | ||
1390 | if ($this->elementInScope('option')) { | ||
1391 | $this->emitToken(array( | ||
1392 | 'name' => 'option', | ||
1393 | 'type' => HTML5_Tokenizer::ENDTAG, | ||
1394 | )); | ||
1395 | } | ||
1396 | $this->reconstructActiveFormattingElements(); | ||
1397 | $this->insertElement($token); | ||
1398 | break; | ||
1399 | |||
1400 | case 'rp': case 'rt': | ||
1401 | /* If the stack of open elements has a ruby element in scope, then generate | ||
1402 | * implied end tags. If the current node is not then a ruby element, this is | ||
1403 | * a parse error; pop all the nodes from the current node up to the node | ||
1404 | * immediately before the bottommost ruby element on the stack of open elements. | ||
1405 | */ | ||
1406 | if ($this->elementInScope('ruby')) { | ||
1407 | $this->generateImpliedEndTags(); | ||
1408 | } | ||
1409 | $peek = false; | ||
1410 | do { | ||
1411 | if ($peek) { | ||
1412 | // parse error | ||
1413 | } | ||
1414 | $peek = array_pop($this->stack); | ||
1415 | } while ($peek->tagName !== 'ruby'); | ||
1416 | $this->stack[] = $peek; // we popped one too many | ||
1417 | $this->insertElement($token); | ||
1418 | break; | ||
1419 | |||
1420 | // spec diversion | ||
1421 | |||
1422 | case 'math': | ||
1423 | $this->reconstructActiveFormattingElements(); | ||
1424 | $token = $this->adjustMathMLAttributes($token); | ||
1425 | $token = $this->adjustForeignAttributes($token); | ||
1426 | $this->insertForeignElement($token, self::NS_MATHML); | ||
1427 | if (isset($token['self-closing'])) { | ||
1428 | // XERROR: acknowledge the token's self-closing flag | ||
1429 | array_pop($this->stack); | ||
1430 | } | ||
1431 | if ($this->mode !== self::IN_FOREIGN_CONTENT) { | ||
1432 | $this->secondary_mode = $this->mode; | ||
1433 | $this->mode = self::IN_FOREIGN_CONTENT; | ||
1434 | } | ||
1435 | break; | ||
1436 | |||
1437 | case 'svg': | ||
1438 | $this->reconstructActiveFormattingElements(); | ||
1439 | $token = $this->adjustSVGAttributes($token); | ||
1440 | $token = $this->adjustForeignAttributes($token); | ||
1441 | $this->insertForeignElement($token, self::NS_SVG); | ||
1442 | if (isset($token['self-closing'])) { | ||
1443 | // XERROR: acknowledge the token's self-closing flag | ||
1444 | array_pop($this->stack); | ||
1445 | } | ||
1446 | if ($this->mode !== self::IN_FOREIGN_CONTENT) { | ||
1447 | $this->secondary_mode = $this->mode; | ||
1448 | $this->mode = self::IN_FOREIGN_CONTENT; | ||
1449 | } | ||
1450 | break; | ||
1451 | |||
1452 | case 'caption': case 'col': case 'colgroup': case 'frame': case 'head': | ||
1453 | case 'tbody': case 'td': case 'tfoot': case 'th': case 'thead': case 'tr': | ||
1454 | // parse error | ||
1455 | break; | ||
1456 | |||
1457 | /* A start tag token not covered by the previous entries */ | ||
1458 | default: | ||
1459 | /* Reconstruct the active formatting elements, if any. */ | ||
1460 | $this->reconstructActiveFormattingElements(); | ||
1461 | |||
1462 | $this->insertElement($token); | ||
1463 | /* This element will be a phrasing element. */ | ||
1464 | break; | ||
1465 | } | ||
1466 | break; | ||
1467 | |||
1468 | case HTML5_Tokenizer::ENDTAG: | ||
1469 | switch($token['name']) { | ||
1470 | /* An end tag with the tag name "body" */ | ||
1471 | case 'body': | ||
1472 | /* If the stack of open elements does not have a body | ||
1473 | * element in scope, this is a parse error; ignore the | ||
1474 | * token. */ | ||
1475 | if(!$this->elementInScope('body')) { | ||
1476 | $this->ignored = true; | ||
1477 | |||
1478 | /* Otherwise, if there is a node in the stack of open | ||
1479 | * elements that is not either a dc element, a dd element, | ||
1480 | * a ds element, a dt element, an li element, an optgroup | ||
1481 | * element, an option element, a p element, an rp element, | ||
1482 | * an rt element, a tbody element, a td element, a tfoot | ||
1483 | * element, a th element, a thead element, a tr element, | ||
1484 | * the body element, or the html element, then this is a | ||
1485 | * parse error. | ||
1486 | */ | ||
1487 | } else { | ||
1488 | // XERROR: implement this check for parse error | ||
1489 | } | ||
1490 | |||
1491 | /* Change the insertion mode to "after body". */ | ||
1492 | $this->mode = self::AFTER_BODY; | ||
1493 | break; | ||
1494 | |||
1495 | /* An end tag with the tag name "html" */ | ||
1496 | case 'html': | ||
1497 | /* Act as if an end tag with tag name "body" had been seen, | ||
1498 | then, if that token wasn't ignored, reprocess the current | ||
1499 | token. */ | ||
1500 | $this->emitToken(array( | ||
1501 | 'name' => 'body', | ||
1502 | 'type' => HTML5_Tokenizer::ENDTAG | ||
1503 | )); | ||
1504 | |||
1505 | if (!$this->ignored) $this->emitToken($token); | ||
1506 | break; | ||
1507 | |||
1508 | case 'address': case 'article': case 'aside': case 'blockquote': | ||
1509 | case 'center': case 'datagrid': case 'details': case 'dir': | ||
1510 | case 'div': case 'dl': case 'fieldset': case 'footer': | ||
1511 | case 'header': case 'hgroup': case 'listing': case 'menu': | ||
1512 | case 'nav': case 'ol': case 'pre': case 'section': case 'ul': | ||
1513 | /* If the stack of open elements has an element in scope | ||
1514 | with the same tag name as that of the token, then generate | ||
1515 | implied end tags. */ | ||
1516 | if($this->elementInScope($token['name'])) { | ||
1517 | $this->generateImpliedEndTags(); | ||
1518 | |||
1519 | /* Now, if the current node is not an element with | ||
1520 | the same tag name as that of the token, then this | ||
1521 | is a parse error. */ | ||
1522 | // XERROR: implement parse error logic | ||
1523 | |||
1524 | /* If the stack of open elements has an element in | ||
1525 | scope with the same tag name as that of the token, | ||
1526 | then pop elements from this stack until an element | ||
1527 | with that tag name has been popped from the stack. */ | ||
1528 | do { | ||
1529 | $node = array_pop($this->stack); | ||
1530 | } while ($node->tagName !== $token['name']); | ||
1531 | } else { | ||
1532 | // parse error | ||
1533 | } | ||
1534 | break; | ||
1535 | |||
1536 | /* An end tag whose tag name is "form" */ | ||
1537 | case 'form': | ||
1538 | /* Let node be the element that the form element pointer is set to. */ | ||
1539 | $node = $this->form_pointer; | ||
1540 | /* Set the form element pointer to null. */ | ||
1541 | $this->form_pointer = null; | ||
1542 | /* If node is null or the stack of open elements does not | ||
1543 | * have node in scope, then this is a parse error; ignore the token. */ | ||
1544 | if ($node === null || !in_array($node, $this->stack)) { | ||
1545 | // parse error | ||
1546 | $this->ignored = true; | ||
1547 | } else { | ||
1548 | /* 1. Generate implied end tags. */ | ||
1549 | $this->generateImpliedEndTags(); | ||
1550 | /* 2. If the current node is not node, then this is a parse error. */ | ||
1551 | if (end($this->stack) !== $node) { | ||
1552 | // parse error | ||
1553 | } | ||
1554 | /* 3. Remove node from the stack of open elements. */ | ||
1555 | array_splice($this->stack, array_search($node, $this->stack, true), 1); | ||
1556 | } | ||
1557 | |||
1558 | break; | ||
1559 | |||
1560 | /* An end tag whose tag name is "p" */ | ||
1561 | case 'p': | ||
1562 | /* If the stack of open elements has a p element in scope, | ||
1563 | then generate implied end tags, except for p elements. */ | ||
1564 | if($this->elementInScope('p')) { | ||
1565 | /* Generate implied end tags, except for elements with | ||
1566 | * the same tag name as the token. */ | ||
1567 | $this->generateImpliedEndTags(array('p')); | ||
1568 | |||
1569 | /* If the current node is not a p element, then this is | ||
1570 | a parse error. */ | ||
1571 | // XERROR: implement | ||
1572 | |||
1573 | /* Pop elements from the stack of open elements until | ||
1574 | * an element with the same tag name as the token has | ||
1575 | * been popped from the stack. */ | ||
1576 | do { | ||
1577 | $node = array_pop($this->stack); | ||
1578 | } while ($node->tagName !== 'p'); | ||
1579 | |||
1580 | } else { | ||
1581 | // parse error | ||
1582 | $this->emitToken(array( | ||
1583 | 'name' => 'p', | ||
1584 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
1585 | )); | ||
1586 | $this->emitToken($token); | ||
1587 | } | ||
1588 | break; | ||
1589 | |||
1590 | /* An end tag whose tag name is "li" */ | ||
1591 | case 'li': | ||
1592 | /* If the stack of open elements does not have an element | ||
1593 | * in list item scope with the same tag name as that of the | ||
1594 | * token, then this is a parse error; ignore the token. */ | ||
1595 | if ($this->elementInScope($token['name'], self::SCOPE_LISTITEM)) { | ||
1596 | /* Generate implied end tags, except for elements with the | ||
1597 | * same tag name as the token. */ | ||
1598 | $this->generateImpliedEndTags(array($token['name'])); | ||
1599 | /* If the current node is not an element with the same tag | ||
1600 | * name as that of the token, then this is a parse error. */ | ||
1601 | // XERROR: parse error | ||
1602 | /* Pop elements from the stack of open elements until an | ||
1603 | * element with the same tag name as the token has been | ||
1604 | * popped from the stack. */ | ||
1605 | do { | ||
1606 | $node = array_pop($this->stack); | ||
1607 | } while ($node->tagName !== $token['name']); | ||
1608 | } else { | ||
1609 | // XERROR: parse error | ||
1610 | } | ||
1611 | break; | ||
1612 | |||
1613 | /* An end tag whose tag name is "dc", "dd", "ds", "dt" */ | ||
1614 | case 'dc': case 'dd': case 'ds': case 'dt': | ||
1615 | if($this->elementInScope($token['name'])) { | ||
1616 | $this->generateImpliedEndTags(array($token['name'])); | ||
1617 | |||
1618 | /* If the current node is not an element with the same | ||
1619 | tag name as the token, then this is a parse error. */ | ||
1620 | // XERROR: implement parse error | ||
1621 | |||
1622 | /* Pop elements from the stack of open elements until | ||
1623 | * an element with the same tag name as the token has | ||
1624 | * been popped from the stack. */ | ||
1625 | do { | ||
1626 | $node = array_pop($this->stack); | ||
1627 | } while ($node->tagName !== $token['name']); | ||
1628 | |||
1629 | } else { | ||
1630 | // XERROR: parse error | ||
1631 | } | ||
1632 | break; | ||
1633 | |||
1634 | /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4", | ||
1635 | "h5", "h6" */ | ||
1636 | case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': | ||
1637 | $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); | ||
1638 | |||
1639 | /* If the stack of open elements has in scope an element whose | ||
1640 | tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then | ||
1641 | generate implied end tags. */ | ||
1642 | if($this->elementInScope($elements)) { | ||
1643 | $this->generateImpliedEndTags(); | ||
1644 | |||
1645 | /* Now, if the current node is not an element with the same | ||
1646 | tag name as that of the token, then this is a parse error. */ | ||
1647 | // XERROR: implement parse error | ||
1648 | |||
1649 | /* If the stack of open elements has in scope an element | ||
1650 | whose tag name is one of "h1", "h2", "h3", "h4", "h5", or | ||
1651 | "h6", then pop elements from the stack until an element | ||
1652 | with one of those tag names has been popped from the stack. */ | ||
1653 | do { | ||
1654 | $node = array_pop($this->stack); | ||
1655 | } while (!in_array($node->tagName, $elements)); | ||
1656 | } else { | ||
1657 | // parse error | ||
1658 | } | ||
1659 | break; | ||
1660 | |||
1661 | /* An end tag whose tag name is one of: "a", "b", "big", "em", | ||
1662 | "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ | ||
1663 | case 'a': case 'b': case 'big': case 'code': case 'em': case 'font': | ||
1664 | case 'i': case 'nobr': case 's': case 'small': case 'strike': | ||
1665 | case 'strong': case 'tt': case 'u': | ||
1666 | // XERROR: generally speaking this needs parse error logic | ||
1667 | /* 1. Let the formatting element be the last element in | ||
1668 | the list of active formatting elements that: | ||
1669 | * is between the end of the list and the last scope | ||
1670 | marker in the list, if any, or the start of the list | ||
1671 | otherwise, and | ||
1672 | * has the same tag name as the token. | ||
1673 | */ | ||
1674 | while(true) { | ||
1675 | for($a = count($this->a_formatting) - 1; $a >= 0; $a--) { | ||
1676 | if($this->a_formatting[$a] === self::MARKER) { | ||
1677 | break; | ||
1678 | |||
1679 | } elseif($this->a_formatting[$a]->tagName === $token['name']) { | ||
1680 | $formatting_element = $this->a_formatting[$a]; | ||
1681 | $in_stack = in_array($formatting_element, $this->stack, true); | ||
1682 | $fe_af_pos = $a; | ||
1683 | break; | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | /* If there is no such node, or, if that node is | ||
1688 | also in the stack of open elements but the element | ||
1689 | is not in scope, then this is a parse error. Abort | ||
1690 | these steps. The token is ignored. */ | ||
1691 | if(!isset($formatting_element) || ($in_stack && | ||
1692 | !$this->elementInScope($token['name']))) { | ||
1693 | $this->ignored = true; | ||
1694 | break; | ||
1695 | |||
1696 | /* Otherwise, if there is such a node, but that node | ||
1697 | is not in the stack of open elements, then this is a | ||
1698 | parse error; remove the element from the list, and | ||
1699 | abort these steps. */ | ||
1700 | } elseif(isset($formatting_element) && !$in_stack) { | ||
1701 | unset($this->a_formatting[$fe_af_pos]); | ||
1702 | $this->a_formatting = array_merge($this->a_formatting); | ||
1703 | break; | ||
1704 | } | ||
1705 | |||
1706 | /* Otherwise, there is a formatting element and that | ||
1707 | * element is in the stack and is in scope. If the | ||
1708 | * element is not the current node, this is a parse | ||
1709 | * error. In any case, proceed with the algorithm as | ||
1710 | * written in the following steps. */ | ||
1711 | // XERROR: implement me | ||
1712 | |||
1713 | /* 2. Let the furthest block be the topmost node in the | ||
1714 | stack of open elements that is lower in the stack | ||
1715 | than the formatting element, and is not an element in | ||
1716 | the phrasing or formatting categories. There might | ||
1717 | not be one. */ | ||
1718 | $fe_s_pos = array_search($formatting_element, $this->stack, true); | ||
1719 | $length = count($this->stack); | ||
1720 | |||
1721 | for($s = $fe_s_pos + 1; $s < $length; $s++) { | ||
1722 | $category = $this->getElementCategory($this->stack[$s]); | ||
1723 | |||
1724 | if($category !== self::PHRASING && $category !== self::FORMATTING) { | ||
1725 | $furthest_block = $this->stack[$s]; | ||
1726 | break; | ||
1727 | } | ||
1728 | } | ||
1729 | |||
1730 | /* 3. If there is no furthest block, then the UA must | ||
1731 | skip the subsequent steps and instead just pop all | ||
1732 | the nodes from the bottom of the stack of open | ||
1733 | elements, from the current node up to the formatting | ||
1734 | element, and remove the formatting element from the | ||
1735 | list of active formatting elements. */ | ||
1736 | if(!isset($furthest_block)) { | ||
1737 | for($n = $length - 1; $n >= $fe_s_pos; $n--) { | ||
1738 | array_pop($this->stack); | ||
1739 | } | ||
1740 | |||
1741 | unset($this->a_formatting[$fe_af_pos]); | ||
1742 | $this->a_formatting = array_merge($this->a_formatting); | ||
1743 | break; | ||
1744 | } | ||
1745 | |||
1746 | /* 4. Let the common ancestor be the element | ||
1747 | immediately above the formatting element in the stack | ||
1748 | of open elements. */ | ||
1749 | $common_ancestor = $this->stack[$fe_s_pos - 1]; | ||
1750 | |||
1751 | /* 5. Let a bookmark note the position of the | ||
1752 | formatting element in the list of active formatting | ||
1753 | elements relative to the elements on either side | ||
1754 | of it in the list. */ | ||
1755 | $bookmark = $fe_af_pos; | ||
1756 | |||
1757 | /* 6. Let node and last node be the furthest block. | ||
1758 | Follow these steps: */ | ||
1759 | $node = $furthest_block; | ||
1760 | $last_node = $furthest_block; | ||
1761 | |||
1762 | while(true) { | ||
1763 | for($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) { | ||
1764 | /* 6.1 Let node be the element immediately | ||
1765 | prior to node in the stack of open elements. */ | ||
1766 | $node = $this->stack[$n]; | ||
1767 | |||
1768 | /* 6.2 If node is not in the list of active | ||
1769 | formatting elements, then remove node from | ||
1770 | the stack of open elements and then go back | ||
1771 | to step 1. */ | ||
1772 | if(!in_array($node, $this->a_formatting, true)) { | ||
1773 | array_splice($this->stack, $n, 1); | ||
1774 | |||
1775 | } else { | ||
1776 | break; | ||
1777 | } | ||
1778 | } | ||
1779 | |||
1780 | /* 6.3 Otherwise, if node is the formatting | ||
1781 | element, then go to the next step in the overall | ||
1782 | algorithm. */ | ||
1783 | if($node === $formatting_element) { | ||
1784 | break; | ||
1785 | |||
1786 | /* 6.4 Otherwise, if last node is the furthest | ||
1787 | block, then move the aforementioned bookmark to | ||
1788 | be immediately after the node in the list of | ||
1789 | active formatting elements. */ | ||
1790 | } elseif($last_node === $furthest_block) { | ||
1791 | $bookmark = array_search($node, $this->a_formatting, true) + 1; | ||
1792 | } | ||
1793 | |||
1794 | /* 6.5 Create an element for the token for which | ||
1795 | * the element node was created, replace the entry | ||
1796 | * for node in the list of active formatting | ||
1797 | * elements with an entry for the new element, | ||
1798 | * replace the entry for node in the stack of open | ||
1799 | * elements with an entry for the new element, and | ||
1800 | * let node be the new element. */ | ||
1801 | // we don't know what the token is anymore | ||
1802 | // XDOM | ||
1803 | $clone = $node->cloneNode(); | ||
1804 | $a_pos = array_search($node, $this->a_formatting, true); | ||
1805 | $s_pos = array_search($node, $this->stack, true); | ||
1806 | $this->a_formatting[$a_pos] = $clone; | ||
1807 | $this->stack[$s_pos] = $clone; | ||
1808 | $node = $clone; | ||
1809 | |||
1810 | /* 6.6 Insert last node into node, first removing | ||
1811 | it from its previous parent node if any. */ | ||
1812 | // XDOM | ||
1813 | if($last_node->parentNode !== null) { | ||
1814 | $last_node->parentNode->removeChild($last_node); | ||
1815 | } | ||
1816 | |||
1817 | // XDOM | ||
1818 | $node->appendChild($last_node); | ||
1819 | |||
1820 | /* 6.7 Let last node be node. */ | ||
1821 | $last_node = $node; | ||
1822 | |||
1823 | /* 6.8 Return to step 1 of this inner set of steps. */ | ||
1824 | } | ||
1825 | |||
1826 | /* 7. If the common ancestor node is a table, tbody, | ||
1827 | * tfoot, thead, or tr element, then, foster parent | ||
1828 | * whatever last node ended up being in the previous | ||
1829 | * step, first removing it from its previous parent | ||
1830 | * node if any. */ | ||
1831 | // XDOM | ||
1832 | if ($last_node->parentNode) { // common step | ||
1833 | $last_node->parentNode->removeChild($last_node); | ||
1834 | } | ||
1835 | if (in_array($common_ancestor->tagName, array('table', 'tbody', 'tfoot', 'thead', 'tr'))) { | ||
1836 | $this->fosterParent($last_node); | ||
1837 | /* Otherwise, append whatever last node ended up being | ||
1838 | * in the previous step to the common ancestor node, | ||
1839 | * first removing it from its previous parent node if | ||
1840 | * any. */ | ||
1841 | } else { | ||
1842 | // XDOM | ||
1843 | $common_ancestor->appendChild($last_node); | ||
1844 | } | ||
1845 | |||
1846 | /* 8. Create an element for the token for which the | ||
1847 | * formatting element was created. */ | ||
1848 | // XDOM | ||
1849 | $clone = $formatting_element->cloneNode(); | ||
1850 | |||
1851 | /* 9. Take all of the child nodes of the furthest | ||
1852 | block and append them to the element created in the | ||
1853 | last step. */ | ||
1854 | // XDOM | ||
1855 | while($furthest_block->hasChildNodes()) { | ||
1856 | $child = $furthest_block->firstChild; | ||
1857 | $furthest_block->removeChild($child); | ||
1858 | $clone->appendChild($child); | ||
1859 | } | ||
1860 | |||
1861 | /* 10. Append that clone to the furthest block. */ | ||
1862 | // XDOM | ||
1863 | $furthest_block->appendChild($clone); | ||
1864 | |||
1865 | /* 11. Remove the formatting element from the list | ||
1866 | of active formatting elements, and insert the new element | ||
1867 | into the list of active formatting elements at the | ||
1868 | position of the aforementioned bookmark. */ | ||
1869 | $fe_af_pos = array_search($formatting_element, $this->a_formatting, true); | ||
1870 | array_splice($this->a_formatting, $fe_af_pos, 1); | ||
1871 | |||
1872 | $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1); | ||
1873 | $af_part2 = array_slice($this->a_formatting, $bookmark); | ||
1874 | $this->a_formatting = array_merge($af_part1, array($clone), $af_part2); | ||
1875 | |||
1876 | /* 12. Remove the formatting element from the stack | ||
1877 | of open elements, and insert the new element into the stack | ||
1878 | of open elements immediately below the position of the | ||
1879 | furthest block in that stack. */ | ||
1880 | $fe_s_pos = array_search($formatting_element, $this->stack, true); | ||
1881 | array_splice($this->stack, $fe_s_pos, 1); | ||
1882 | |||
1883 | $fb_s_pos = array_search($furthest_block, $this->stack, true); | ||
1884 | $s_part1 = array_slice($this->stack, 0, $fb_s_pos + 1); | ||
1885 | $s_part2 = array_slice($this->stack, $fb_s_pos + 1); | ||
1886 | $this->stack = array_merge($s_part1, array($clone), $s_part2); | ||
1887 | |||
1888 | /* 13. Jump back to step 1 in this series of steps. */ | ||
1889 | unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block); | ||
1890 | } | ||
1891 | break; | ||
1892 | |||
1893 | case 'applet': case 'button': case 'marquee': case 'object': | ||
1894 | /* If the stack of open elements has an element in scope whose | ||
1895 | tag name matches the tag name of the token, then generate implied | ||
1896 | tags. */ | ||
1897 | if($this->elementInScope($token['name'])) { | ||
1898 | $this->generateImpliedEndTags(); | ||
1899 | |||
1900 | /* Now, if the current node is not an element with the same | ||
1901 | tag name as the token, then this is a parse error. */ | ||
1902 | // XERROR: implement logic | ||
1903 | |||
1904 | /* Pop elements from the stack of open elements until | ||
1905 | * an element with the same tag name as the token has | ||
1906 | * been popped from the stack. */ | ||
1907 | do { | ||
1908 | $node = array_pop($this->stack); | ||
1909 | } while ($node->tagName !== $token['name']); | ||
1910 | |||
1911 | /* Clear the list of active formatting elements up to the | ||
1912 | * last marker. */ | ||
1913 | $keys = array_keys($this->a_formatting, self::MARKER, true); | ||
1914 | $marker = end($keys); | ||
1915 | |||
1916 | for($n = count($this->a_formatting) - 1; $n > $marker; $n--) { | ||
1917 | array_pop($this->a_formatting); | ||
1918 | } | ||
1919 | } else { | ||
1920 | // parse error | ||
1921 | } | ||
1922 | break; | ||
1923 | |||
1924 | case 'br': | ||
1925 | // Parse error | ||
1926 | $this->emitToken(array( | ||
1927 | 'name' => 'br', | ||
1928 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
1929 | )); | ||
1930 | break; | ||
1931 | |||
1932 | /* An end tag token not covered by the previous entries */ | ||
1933 | default: | ||
1934 | for($n = count($this->stack) - 1; $n >= 0; $n--) { | ||
1935 | /* Initialise node to be the current node (the bottommost | ||
1936 | node of the stack). */ | ||
1937 | $node = $this->stack[$n]; | ||
1938 | |||
1939 | /* If node has the same tag name as the end tag token, | ||
1940 | then: */ | ||
1941 | if($token['name'] === $node->tagName) { | ||
1942 | /* Generate implied end tags. */ | ||
1943 | $this->generateImpliedEndTags(); | ||
1944 | |||
1945 | /* If the tag name of the end tag token does not | ||
1946 | match the tag name of the current node, this is a | ||
1947 | parse error. */ | ||
1948 | // XERROR: implement this | ||
1949 | |||
1950 | /* Pop all the nodes from the current node up to | ||
1951 | node, including node, then stop these steps. */ | ||
1952 | // XSKETCHY | ||
1953 | do { | ||
1954 | $pop = array_pop($this->stack); | ||
1955 | } while ($pop !== $node); | ||
1956 | break; | ||
1957 | |||
1958 | } else { | ||
1959 | $category = $this->getElementCategory($node); | ||
1960 | |||
1961 | if($category !== self::FORMATTING && $category !== self::PHRASING) { | ||
1962 | /* Otherwise, if node is in neither the formatting | ||
1963 | category nor the phrasing category, then this is a | ||
1964 | parse error. Stop this algorithm. The end tag token | ||
1965 | is ignored. */ | ||
1966 | $this->ignored = true; | ||
1967 | break; | ||
1968 | // parse error | ||
1969 | } | ||
1970 | } | ||
1971 | /* Set node to the previous entry in the stack of open elements. Loop. */ | ||
1972 | } | ||
1973 | break; | ||
1974 | } | ||
1975 | break; | ||
1976 | } | ||
1977 | break; | ||
1978 | |||
1979 | case self::IN_CDATA_RCDATA: | ||
1980 | if ( | ||
1981 | $token['type'] === HTML5_Tokenizer::CHARACTER || | ||
1982 | $token['type'] === HTML5_Tokenizer::SPACECHARACTER | ||
1983 | ) { | ||
1984 | $this->insertText($token['data']); | ||
1985 | } elseif ($token['type'] === HTML5_Tokenizer::EOF) { | ||
1986 | // parse error | ||
1987 | /* If the current node is a script element, mark the script | ||
1988 | * element as "already executed". */ | ||
1989 | // probably not necessary | ||
1990 | array_pop($this->stack); | ||
1991 | $this->mode = $this->original_mode; | ||
1992 | $this->emitToken($token); | ||
1993 | } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'script') { | ||
1994 | array_pop($this->stack); | ||
1995 | $this->mode = $this->original_mode; | ||
1996 | // we're ignoring all of the execution stuff | ||
1997 | } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG) { | ||
1998 | array_pop($this->stack); | ||
1999 | $this->mode = $this->original_mode; | ||
2000 | } | ||
2001 | break; | ||
2002 | |||
2003 | case self::IN_TABLE: | ||
2004 | $clear = array('html', 'table'); | ||
2005 | |||
2006 | /* A character token */ | ||
2007 | if ($token['type'] === HTML5_Tokenizer::CHARACTER || | ||
2008 | $token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
2009 | /* Let the pending table character tokens | ||
2010 | * be an empty list of tokens. */ | ||
2011 | $this->pendingTableCharacters = ""; | ||
2012 | $this->pendingTableCharactersDirty = false; | ||
2013 | /* Let the original insertion mode be the current | ||
2014 | * insertion mode. */ | ||
2015 | $this->original_mode = $this->mode; | ||
2016 | /* Switch the insertion mode to | ||
2017 | * "in table text" and | ||
2018 | * reprocess the token. */ | ||
2019 | $this->mode = self::IN_TABLE_TEXT; | ||
2020 | $this->emitToken($token); | ||
2021 | |||
2022 | /* A comment token */ | ||
2023 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
2024 | /* Append a Comment node to the current node with the data | ||
2025 | attribute set to the data given in the comment token. */ | ||
2026 | $this->insertComment($token['data']); | ||
2027 | |||
2028 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
2029 | // parse error | ||
2030 | |||
2031 | /* A start tag whose tag name is "caption" */ | ||
2032 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2033 | $token['name'] === 'caption') { | ||
2034 | /* Clear the stack back to a table context. */ | ||
2035 | $this->clearStackToTableContext($clear); | ||
2036 | |||
2037 | /* Insert a marker at the end of the list of active | ||
2038 | formatting elements. */ | ||
2039 | $this->a_formatting[] = self::MARKER; | ||
2040 | |||
2041 | /* Insert an HTML element for the token, then switch the | ||
2042 | insertion mode to "in caption". */ | ||
2043 | $this->insertElement($token); | ||
2044 | $this->mode = self::IN_CAPTION; | ||
2045 | |||
2046 | /* A start tag whose tag name is "colgroup" */ | ||
2047 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2048 | $token['name'] === 'colgroup') { | ||
2049 | /* Clear the stack back to a table context. */ | ||
2050 | $this->clearStackToTableContext($clear); | ||
2051 | |||
2052 | /* Insert an HTML element for the token, then switch the | ||
2053 | insertion mode to "in column group". */ | ||
2054 | $this->insertElement($token); | ||
2055 | $this->mode = self::IN_COLUMN_GROUP; | ||
2056 | |||
2057 | /* A start tag whose tag name is "col" */ | ||
2058 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2059 | $token['name'] === 'col') { | ||
2060 | $this->emitToken(array( | ||
2061 | 'name' => 'colgroup', | ||
2062 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
2063 | 'attr' => array() | ||
2064 | )); | ||
2065 | |||
2066 | $this->emitToken($token); | ||
2067 | |||
2068 | /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ | ||
2069 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'], | ||
2070 | array('tbody', 'tfoot', 'thead'))) { | ||
2071 | /* Clear the stack back to a table context. */ | ||
2072 | $this->clearStackToTableContext($clear); | ||
2073 | |||
2074 | /* Insert an HTML element for the token, then switch the insertion | ||
2075 | mode to "in table body". */ | ||
2076 | $this->insertElement($token); | ||
2077 | $this->mode = self::IN_TABLE_BODY; | ||
2078 | |||
2079 | /* A start tag whose tag name is one of: "td", "th", "tr" */ | ||
2080 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2081 | in_array($token['name'], array('td', 'th', 'tr'))) { | ||
2082 | /* Act as if a start tag token with the tag name "tbody" had been | ||
2083 | seen, then reprocess the current token. */ | ||
2084 | $this->emitToken(array( | ||
2085 | 'name' => 'tbody', | ||
2086 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
2087 | 'attr' => array() | ||
2088 | )); | ||
2089 | |||
2090 | $this->emitToken($token); | ||
2091 | |||
2092 | /* A start tag whose tag name is "table" */ | ||
2093 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2094 | $token['name'] === 'table') { | ||
2095 | /* Parse error. Act as if an end tag token with the tag name "table" | ||
2096 | had been seen, then, if that token wasn't ignored, reprocess the | ||
2097 | current token. */ | ||
2098 | $this->emitToken(array( | ||
2099 | 'name' => 'table', | ||
2100 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2101 | )); | ||
2102 | |||
2103 | if (!$this->ignored) $this->emitToken($token); | ||
2104 | |||
2105 | /* An end tag whose tag name is "table" */ | ||
2106 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2107 | $token['name'] === 'table') { | ||
2108 | /* If the stack of open elements does not have an element in table | ||
2109 | scope with the same tag name as the token, this is a parse error. | ||
2110 | Ignore the token. (fragment case) */ | ||
2111 | if(!$this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2112 | $this->ignored = true; | ||
2113 | |||
2114 | /* Otherwise: */ | ||
2115 | } else { | ||
2116 | do { | ||
2117 | $node = array_pop($this->stack); | ||
2118 | } while ($node->tagName !== 'table'); | ||
2119 | |||
2120 | /* Reset the insertion mode appropriately. */ | ||
2121 | $this->resetInsertionMode(); | ||
2122 | } | ||
2123 | |||
2124 | /* An end tag whose tag name is one of: "body", "caption", "col", | ||
2125 | "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ | ||
2126 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'], | ||
2127 | array('body', 'caption', 'col', 'colgroup', 'html', 'tbody', 'td', | ||
2128 | 'tfoot', 'th', 'thead', 'tr'))) { | ||
2129 | // Parse error. Ignore the token. | ||
2130 | |||
2131 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2132 | ($token['name'] === 'style' || $token['name'] === 'script')) { | ||
2133 | $this->processWithRulesFor($token, self::IN_HEAD); | ||
2134 | |||
2135 | } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'input' && | ||
2136 | // assignment is intentional | ||
2137 | /* If the token does not have an attribute with the name "type", or | ||
2138 | * if it does, but that attribute's value is not an ASCII | ||
2139 | * case-insensitive match for the string "hidden", then: act as | ||
2140 | * described in the "anything else" entry below. */ | ||
2141 | ($type = $this->getAttr($token, 'type')) && strtolower($type) === 'hidden') { | ||
2142 | // I.e., if its an input with the type attribute == 'hidden' | ||
2143 | /* Otherwise */ | ||
2144 | // parse error | ||
2145 | $this->insertElement($token); | ||
2146 | array_pop($this->stack); | ||
2147 | } elseif ($token['type'] === HTML5_Tokenizer::EOF) { | ||
2148 | /* If the current node is not the root html element, then this is a parse error. */ | ||
2149 | if (end($this->stack)->tagName !== 'html') { | ||
2150 | // Note: It can only be the current node in the fragment case. | ||
2151 | // parse error | ||
2152 | } | ||
2153 | /* Stop parsing. */ | ||
2154 | /* Anything else */ | ||
2155 | } else { | ||
2156 | /* Parse error. Process the token as if the insertion mode was "in | ||
2157 | body", with the following exception: */ | ||
2158 | |||
2159 | $old = $this->foster_parent; | ||
2160 | $this->foster_parent = true; | ||
2161 | $this->processWithRulesFor($token, self::IN_BODY); | ||
2162 | $this->foster_parent = $old; | ||
2163 | } | ||
2164 | break; | ||
2165 | |||
2166 | case self::IN_TABLE_TEXT: | ||
2167 | /* A character token */ | ||
2168 | if($token['type'] === HTML5_Tokenizer::CHARACTER) { | ||
2169 | /* Append the character token to the pending table | ||
2170 | * character tokens list. */ | ||
2171 | $this->pendingTableCharacters .= $token['data']; | ||
2172 | $this->pendingTableCharactersDirty = true; | ||
2173 | } elseif ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
2174 | $this->pendingTableCharacters .= $token['data']; | ||
2175 | /* Anything else */ | ||
2176 | } else { | ||
2177 | if ($this->pendingTableCharacters !== '' && is_string($this->pendingTableCharacters)) { | ||
2178 | /* If any of the tokens in the pending table character tokens list | ||
2179 | * are character tokens that are not one of U+0009 CHARACTER | ||
2180 | * TABULATION, U+000A LINE FEED (LF), U+000C FORM FEED (FF), or | ||
2181 | * U+0020 SPACE, then reprocess those character tokens using the | ||
2182 | * rules given in the "anything else" entry in the in table" | ||
2183 | * insertion mode.*/ | ||
2184 | if ($this->pendingTableCharactersDirty) { | ||
2185 | /* Parse error. Process the token using the rules for the | ||
2186 | * "in body" insertion mode, except that if the current | ||
2187 | * node is a table, tbody, tfoot, thead, or tr element, | ||
2188 | * then, whenever a node would be inserted into the current | ||
2189 | * node, it must instead be foster parented. */ | ||
2190 | // XERROR | ||
2191 | $old = $this->foster_parent; | ||
2192 | $this->foster_parent = true; | ||
2193 | $text_token = array( | ||
2194 | 'type' => HTML5_Tokenizer::CHARACTER, | ||
2195 | 'data' => $this->pendingTableCharacters, | ||
2196 | ); | ||
2197 | $this->processWithRulesFor($text_token, self::IN_BODY); | ||
2198 | $this->foster_parent = $old; | ||
2199 | |||
2200 | /* Otherwise, insert the characters given by the pending table | ||
2201 | * character tokens list into the current node. */ | ||
2202 | } else { | ||
2203 | $this->insertText($this->pendingTableCharacters); | ||
2204 | } | ||
2205 | $this->pendingTableCharacters = null; | ||
2206 | $this->pendingTableCharactersNull = null; | ||
2207 | } | ||
2208 | |||
2209 | /* Switch the insertion mode to the original insertion mode and | ||
2210 | * reprocess the token. | ||
2211 | */ | ||
2212 | $this->mode = $this->original_mode; | ||
2213 | $this->emitToken($token); | ||
2214 | } | ||
2215 | break; | ||
2216 | |||
2217 | case self::IN_CAPTION: | ||
2218 | /* An end tag whose tag name is "caption" */ | ||
2219 | if($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'caption') { | ||
2220 | /* If the stack of open elements does not have an element in table | ||
2221 | scope with the same tag name as the token, this is a parse error. | ||
2222 | Ignore the token. (fragment case) */ | ||
2223 | if(!$this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2224 | $this->ignored = true; | ||
2225 | // Ignore | ||
2226 | |||
2227 | /* Otherwise: */ | ||
2228 | } else { | ||
2229 | /* Generate implied end tags. */ | ||
2230 | $this->generateImpliedEndTags(); | ||
2231 | |||
2232 | /* Now, if the current node is not a caption element, then this | ||
2233 | is a parse error. */ | ||
2234 | // XERROR: implement | ||
2235 | |||
2236 | /* Pop elements from this stack until a caption element has | ||
2237 | been popped from the stack. */ | ||
2238 | do { | ||
2239 | $node = array_pop($this->stack); | ||
2240 | } while ($node->tagName !== 'caption'); | ||
2241 | |||
2242 | /* Clear the list of active formatting elements up to the last | ||
2243 | marker. */ | ||
2244 | $this->clearTheActiveFormattingElementsUpToTheLastMarker(); | ||
2245 | |||
2246 | /* Switch the insertion mode to "in table". */ | ||
2247 | $this->mode = self::IN_TABLE; | ||
2248 | } | ||
2249 | |||
2250 | /* A start tag whose tag name is one of: "caption", "col", "colgroup", | ||
2251 | "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag | ||
2252 | name is "table" */ | ||
2253 | } elseif(($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'], | ||
2254 | array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', | ||
2255 | 'thead', 'tr'))) || ($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2256 | $token['name'] === 'table')) { | ||
2257 | /* Parse error. Act as if an end tag with the tag name "caption" | ||
2258 | had been seen, then, if that token wasn't ignored, reprocess the | ||
2259 | current token. */ | ||
2260 | $this->emitToken(array( | ||
2261 | 'name' => 'caption', | ||
2262 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2263 | )); | ||
2264 | |||
2265 | if (!$this->ignored) $this->emitToken($token); | ||
2266 | |||
2267 | /* An end tag whose tag name is one of: "body", "col", "colgroup", | ||
2268 | "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ | ||
2269 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'], | ||
2270 | array('body', 'col', 'colgroup', 'html', 'tbody', 'tfoot', 'th', | ||
2271 | 'thead', 'tr'))) { | ||
2272 | // Parse error. Ignore the token. | ||
2273 | $this->ignored = true; | ||
2274 | |||
2275 | /* Anything else */ | ||
2276 | } else { | ||
2277 | /* Process the token as if the insertion mode was "in body". */ | ||
2278 | $this->processWithRulesFor($token, self::IN_BODY); | ||
2279 | } | ||
2280 | break; | ||
2281 | |||
2282 | case self::IN_COLUMN_GROUP: | ||
2283 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
2284 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
2285 | or U+0020 SPACE */ | ||
2286 | if($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
2287 | /* Append the character to the current node. */ | ||
2288 | $this->insertText($token['data']); | ||
2289 | |||
2290 | /* A comment token */ | ||
2291 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
2292 | /* Append a Comment node to the current node with the data | ||
2293 | attribute set to the data given in the comment token. */ | ||
2294 | $this->insertToken($token['data']); | ||
2295 | |||
2296 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
2297 | // parse error | ||
2298 | |||
2299 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { | ||
2300 | $this->processWithRulesFor($token, self::IN_BODY); | ||
2301 | |||
2302 | /* A start tag whose tag name is "col" */ | ||
2303 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'col') { | ||
2304 | /* Insert a col element for the token. Immediately pop the current | ||
2305 | node off the stack of open elements. */ | ||
2306 | $this->insertElement($token); | ||
2307 | array_pop($this->stack); | ||
2308 | // XERROR: Acknowledge the token's self-closing flag, if it is set. | ||
2309 | |||
2310 | /* An end tag whose tag name is "colgroup" */ | ||
2311 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2312 | $token['name'] === 'colgroup') { | ||
2313 | /* If the current node is the root html element, then this is a | ||
2314 | parse error, ignore the token. (fragment case) */ | ||
2315 | if(end($this->stack)->tagName === 'html') { | ||
2316 | $this->ignored = true; | ||
2317 | |||
2318 | /* Otherwise, pop the current node (which will be a colgroup | ||
2319 | element) from the stack of open elements. Switch the insertion | ||
2320 | mode to "in table". */ | ||
2321 | } else { | ||
2322 | array_pop($this->stack); | ||
2323 | $this->mode = self::IN_TABLE; | ||
2324 | } | ||
2325 | |||
2326 | /* An end tag whose tag name is "col" */ | ||
2327 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'col') { | ||
2328 | /* Parse error. Ignore the token. */ | ||
2329 | $this->ignored = true; | ||
2330 | |||
2331 | /* An end-of-file token */ | ||
2332 | /* If the current node is the root html element */ | ||
2333 | } elseif($token['type'] === HTML5_Tokenizer::EOF && end($this->stack)->tagName === 'html') { | ||
2334 | /* Stop parsing */ | ||
2335 | |||
2336 | /* Anything else */ | ||
2337 | } else { | ||
2338 | /* Act as if an end tag with the tag name "colgroup" had been seen, | ||
2339 | and then, if that token wasn't ignored, reprocess the current token. */ | ||
2340 | $this->emitToken(array( | ||
2341 | 'name' => 'colgroup', | ||
2342 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2343 | )); | ||
2344 | |||
2345 | if (!$this->ignored) $this->emitToken($token); | ||
2346 | } | ||
2347 | break; | ||
2348 | |||
2349 | case self::IN_TABLE_BODY: | ||
2350 | $clear = array('tbody', 'tfoot', 'thead', 'html'); | ||
2351 | |||
2352 | /* A start tag whose tag name is "tr" */ | ||
2353 | if($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'tr') { | ||
2354 | /* Clear the stack back to a table body context. */ | ||
2355 | $this->clearStackToTableContext($clear); | ||
2356 | |||
2357 | /* Insert a tr element for the token, then switch the insertion | ||
2358 | mode to "in row". */ | ||
2359 | $this->insertElement($token); | ||
2360 | $this->mode = self::IN_ROW; | ||
2361 | |||
2362 | /* A start tag whose tag name is one of: "th", "td" */ | ||
2363 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2364 | ($token['name'] === 'th' || $token['name'] === 'td')) { | ||
2365 | /* Parse error. Act as if a start tag with the tag name "tr" had | ||
2366 | been seen, then reprocess the current token. */ | ||
2367 | $this->emitToken(array( | ||
2368 | 'name' => 'tr', | ||
2369 | 'type' => HTML5_Tokenizer::STARTTAG, | ||
2370 | 'attr' => array() | ||
2371 | )); | ||
2372 | |||
2373 | $this->emitToken($token); | ||
2374 | |||
2375 | /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ | ||
2376 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2377 | in_array($token['name'], array('tbody', 'tfoot', 'thead'))) { | ||
2378 | /* If the stack of open elements does not have an element in table | ||
2379 | scope with the same tag name as the token, this is a parse error. | ||
2380 | Ignore the token. */ | ||
2381 | if(!$this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2382 | // Parse error | ||
2383 | $this->ignored = true; | ||
2384 | |||
2385 | /* Otherwise: */ | ||
2386 | } else { | ||
2387 | /* Clear the stack back to a table body context. */ | ||
2388 | $this->clearStackToTableContext($clear); | ||
2389 | |||
2390 | /* Pop the current node from the stack of open elements. Switch | ||
2391 | the insertion mode to "in table". */ | ||
2392 | array_pop($this->stack); | ||
2393 | $this->mode = self::IN_TABLE; | ||
2394 | } | ||
2395 | |||
2396 | /* A start tag whose tag name is one of: "caption", "col", "colgroup", | ||
2397 | "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */ | ||
2398 | } elseif(($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'], | ||
2399 | array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead'))) || | ||
2400 | ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'table')) { | ||
2401 | /* If the stack of open elements does not have a tbody, thead, or | ||
2402 | tfoot element in table scope, this is a parse error. Ignore the | ||
2403 | token. (fragment case) */ | ||
2404 | if(!$this->elementInScope(array('tbody', 'thead', 'tfoot'), self::SCOPE_TABLE)) { | ||
2405 | // parse error | ||
2406 | $this->ignored = true; | ||
2407 | |||
2408 | /* Otherwise: */ | ||
2409 | } else { | ||
2410 | /* Clear the stack back to a table body context. */ | ||
2411 | $this->clearStackToTableContext($clear); | ||
2412 | |||
2413 | /* Act as if an end tag with the same tag name as the current | ||
2414 | node ("tbody", "tfoot", or "thead") had been seen, then | ||
2415 | reprocess the current token. */ | ||
2416 | $this->emitToken(array( | ||
2417 | 'name' => end($this->stack)->tagName, | ||
2418 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2419 | )); | ||
2420 | |||
2421 | $this->emitToken($token); | ||
2422 | } | ||
2423 | |||
2424 | /* An end tag whose tag name is one of: "body", "caption", "col", | ||
2425 | "colgroup", "html", "td", "th", "tr" */ | ||
2426 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'], | ||
2427 | array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'))) { | ||
2428 | /* Parse error. Ignore the token. */ | ||
2429 | $this->ignored = true; | ||
2430 | |||
2431 | /* Anything else */ | ||
2432 | } else { | ||
2433 | /* Process the token as if the insertion mode was "in table". */ | ||
2434 | $this->processWithRulesFor($token, self::IN_TABLE); | ||
2435 | } | ||
2436 | break; | ||
2437 | |||
2438 | case self::IN_ROW: | ||
2439 | $clear = array('tr', 'html'); | ||
2440 | |||
2441 | /* A start tag whose tag name is one of: "th", "td" */ | ||
2442 | if($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2443 | ($token['name'] === 'th' || $token['name'] === 'td')) { | ||
2444 | /* Clear the stack back to a table row context. */ | ||
2445 | $this->clearStackToTableContext($clear); | ||
2446 | |||
2447 | /* Insert an HTML element for the token, then switch the insertion | ||
2448 | mode to "in cell". */ | ||
2449 | $this->insertElement($token); | ||
2450 | $this->mode = self::IN_CELL; | ||
2451 | |||
2452 | /* Insert a marker at the end of the list of active formatting | ||
2453 | elements. */ | ||
2454 | $this->a_formatting[] = self::MARKER; | ||
2455 | |||
2456 | /* An end tag whose tag name is "tr" */ | ||
2457 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'tr') { | ||
2458 | /* If the stack of open elements does not have an element in table | ||
2459 | scope with the same tag name as the token, this is a parse error. | ||
2460 | Ignore the token. (fragment case) */ | ||
2461 | if(!$this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2462 | // Ignore. | ||
2463 | $this->ignored = true; | ||
2464 | |||
2465 | /* Otherwise: */ | ||
2466 | } else { | ||
2467 | /* Clear the stack back to a table row context. */ | ||
2468 | $this->clearStackToTableContext($clear); | ||
2469 | |||
2470 | /* Pop the current node (which will be a tr element) from the | ||
2471 | stack of open elements. Switch the insertion mode to "in table | ||
2472 | body". */ | ||
2473 | array_pop($this->stack); | ||
2474 | $this->mode = self::IN_TABLE_BODY; | ||
2475 | } | ||
2476 | |||
2477 | /* A start tag whose tag name is one of: "caption", "col", "colgroup", | ||
2478 | "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */ | ||
2479 | } elseif(($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'], | ||
2480 | array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr'))) || | ||
2481 | ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'table')) { | ||
2482 | /* Act as if an end tag with the tag name "tr" had been seen, then, | ||
2483 | if that token wasn't ignored, reprocess the current token. */ | ||
2484 | $this->emitToken(array( | ||
2485 | 'name' => 'tr', | ||
2486 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2487 | )); | ||
2488 | if (!$this->ignored) $this->emitToken($token); | ||
2489 | |||
2490 | /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ | ||
2491 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2492 | in_array($token['name'], array('tbody', 'tfoot', 'thead'))) { | ||
2493 | /* If the stack of open elements does not have an element in table | ||
2494 | scope with the same tag name as the token, this is a parse error. | ||
2495 | Ignore the token. */ | ||
2496 | if(!$this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2497 | $this->ignored = true; | ||
2498 | |||
2499 | /* Otherwise: */ | ||
2500 | } else { | ||
2501 | /* Otherwise, act as if an end tag with the tag name "tr" had | ||
2502 | been seen, then reprocess the current token. */ | ||
2503 | $this->emitToken(array( | ||
2504 | 'name' => 'tr', | ||
2505 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2506 | )); | ||
2507 | |||
2508 | $this->emitToken($token); | ||
2509 | } | ||
2510 | |||
2511 | /* An end tag whose tag name is one of: "body", "caption", "col", | ||
2512 | "colgroup", "html", "td", "th" */ | ||
2513 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'], | ||
2514 | array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th'))) { | ||
2515 | /* Parse error. Ignore the token. */ | ||
2516 | $this->ignored = true; | ||
2517 | |||
2518 | /* Anything else */ | ||
2519 | } else { | ||
2520 | /* Process the token as if the insertion mode was "in table". */ | ||
2521 | $this->processWithRulesFor($token, self::IN_TABLE); | ||
2522 | } | ||
2523 | break; | ||
2524 | |||
2525 | case self::IN_CELL: | ||
2526 | /* An end tag whose tag name is one of: "td", "th" */ | ||
2527 | if($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2528 | ($token['name'] === 'td' || $token['name'] === 'th')) { | ||
2529 | /* If the stack of open elements does not have an element in table | ||
2530 | scope with the same tag name as that of the token, then this is a | ||
2531 | parse error and the token must be ignored. */ | ||
2532 | if(!$this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2533 | $this->ignored = true; | ||
2534 | |||
2535 | /* Otherwise: */ | ||
2536 | } else { | ||
2537 | /* Generate implied end tags, except for elements with the same | ||
2538 | tag name as the token. */ | ||
2539 | $this->generateImpliedEndTags(array($token['name'])); | ||
2540 | |||
2541 | /* Now, if the current node is not an element with the same tag | ||
2542 | name as the token, then this is a parse error. */ | ||
2543 | // XERROR: Implement parse error code | ||
2544 | |||
2545 | /* Pop elements from this stack until an element with the same | ||
2546 | tag name as the token has been popped from the stack. */ | ||
2547 | do { | ||
2548 | $node = array_pop($this->stack); | ||
2549 | } while ($node->tagName !== $token['name']); | ||
2550 | |||
2551 | /* Clear the list of active formatting elements up to the last | ||
2552 | marker. */ | ||
2553 | $this->clearTheActiveFormattingElementsUpToTheLastMarker(); | ||
2554 | |||
2555 | /* Switch the insertion mode to "in row". (The current node | ||
2556 | will be a tr element at this point.) */ | ||
2557 | $this->mode = self::IN_ROW; | ||
2558 | } | ||
2559 | |||
2560 | /* A start tag whose tag name is one of: "caption", "col", "colgroup", | ||
2561 | "tbody", "td", "tfoot", "th", "thead", "tr" */ | ||
2562 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'], | ||
2563 | array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', | ||
2564 | 'thead', 'tr'))) { | ||
2565 | /* If the stack of open elements does not have a td or th element | ||
2566 | in table scope, then this is a parse error; ignore the token. | ||
2567 | (fragment case) */ | ||
2568 | if(!$this->elementInScope(array('td', 'th'), self::SCOPE_TABLE)) { | ||
2569 | // parse error | ||
2570 | $this->ignored = true; | ||
2571 | |||
2572 | /* Otherwise, close the cell (see below) and reprocess the current | ||
2573 | token. */ | ||
2574 | } else { | ||
2575 | $this->closeCell(); | ||
2576 | $this->emitToken($token); | ||
2577 | } | ||
2578 | |||
2579 | /* An end tag whose tag name is one of: "body", "caption", "col", | ||
2580 | "colgroup", "html" */ | ||
2581 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'], | ||
2582 | array('body', 'caption', 'col', 'colgroup', 'html'))) { | ||
2583 | /* Parse error. Ignore the token. */ | ||
2584 | $this->ignored = true; | ||
2585 | |||
2586 | /* An end tag whose tag name is one of: "table", "tbody", "tfoot", | ||
2587 | "thead", "tr" */ | ||
2588 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'], | ||
2589 | array('table', 'tbody', 'tfoot', 'thead', 'tr'))) { | ||
2590 | /* If the stack of open elements does not have a td or th element | ||
2591 | in table scope, then this is a parse error; ignore the token. | ||
2592 | (innerHTML case) */ | ||
2593 | if(!$this->elementInScope(array('td', 'th'), self::SCOPE_TABLE)) { | ||
2594 | // Parse error | ||
2595 | $this->ignored = true; | ||
2596 | |||
2597 | /* Otherwise, close the cell (see below) and reprocess the current | ||
2598 | token. */ | ||
2599 | } else { | ||
2600 | $this->closeCell(); | ||
2601 | $this->emitToken($token); | ||
2602 | } | ||
2603 | |||
2604 | /* Anything else */ | ||
2605 | } else { | ||
2606 | /* Process the token as if the insertion mode was "in body". */ | ||
2607 | $this->processWithRulesFor($token, self::IN_BODY); | ||
2608 | } | ||
2609 | break; | ||
2610 | |||
2611 | case self::IN_SELECT: | ||
2612 | /* Handle the token as follows: */ | ||
2613 | |||
2614 | /* A character token */ | ||
2615 | if( | ||
2616 | $token['type'] === HTML5_Tokenizer::CHARACTER || | ||
2617 | $token['type'] === HTML5_Tokenizer::SPACECHARACTER | ||
2618 | ) { | ||
2619 | /* Append the token's character to the current node. */ | ||
2620 | $this->insertText($token['data']); | ||
2621 | |||
2622 | /* A comment token */ | ||
2623 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
2624 | /* Append a Comment node to the current node with the data | ||
2625 | attribute set to the data given in the comment token. */ | ||
2626 | $this->insertComment($token['data']); | ||
2627 | |||
2628 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
2629 | // parse error | ||
2630 | |||
2631 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { | ||
2632 | $this->processWithRulesFor($token, self::INBODY); | ||
2633 | |||
2634 | /* A start tag token whose tag name is "option" */ | ||
2635 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2636 | $token['name'] === 'option') { | ||
2637 | /* If the current node is an option element, act as if an end tag | ||
2638 | with the tag name "option" had been seen. */ | ||
2639 | if(end($this->stack)->tagName === 'option') { | ||
2640 | $this->emitToken(array( | ||
2641 | 'name' => 'option', | ||
2642 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2643 | )); | ||
2644 | } | ||
2645 | |||
2646 | /* Insert an HTML element for the token. */ | ||
2647 | $this->insertElement($token); | ||
2648 | |||
2649 | /* A start tag token whose tag name is "optgroup" */ | ||
2650 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2651 | $token['name'] === 'optgroup') { | ||
2652 | /* If the current node is an option element, act as if an end tag | ||
2653 | with the tag name "option" had been seen. */ | ||
2654 | if(end($this->stack)->tagName === 'option') { | ||
2655 | $this->emitToken(array( | ||
2656 | 'name' => 'option', | ||
2657 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2658 | )); | ||
2659 | } | ||
2660 | |||
2661 | /* If the current node is an optgroup element, act as if an end tag | ||
2662 | with the tag name "optgroup" had been seen. */ | ||
2663 | if(end($this->stack)->tagName === 'optgroup') { | ||
2664 | $this->emitToken(array( | ||
2665 | 'name' => 'optgroup', | ||
2666 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2667 | )); | ||
2668 | } | ||
2669 | |||
2670 | /* Insert an HTML element for the token. */ | ||
2671 | $this->insertElement($token); | ||
2672 | |||
2673 | /* An end tag token whose tag name is "optgroup" */ | ||
2674 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2675 | $token['name'] === 'optgroup') { | ||
2676 | /* First, if the current node is an option element, and the node | ||
2677 | immediately before it in the stack of open elements is an optgroup | ||
2678 | element, then act as if an end tag with the tag name "option" had | ||
2679 | been seen. */ | ||
2680 | $elements_in_stack = count($this->stack); | ||
2681 | |||
2682 | if($this->stack[$elements_in_stack - 1]->tagName === 'option' && | ||
2683 | $this->stack[$elements_in_stack - 2]->tagName === 'optgroup') { | ||
2684 | $this->emitToken(array( | ||
2685 | 'name' => 'option', | ||
2686 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2687 | )); | ||
2688 | } | ||
2689 | |||
2690 | /* If the current node is an optgroup element, then pop that node | ||
2691 | from the stack of open elements. Otherwise, this is a parse error, | ||
2692 | ignore the token. */ | ||
2693 | if(end($this->stack)->tagName === 'optgroup') { | ||
2694 | array_pop($this->stack); | ||
2695 | } else { | ||
2696 | // parse error | ||
2697 | $this->ignored = true; | ||
2698 | } | ||
2699 | |||
2700 | /* An end tag token whose tag name is "option" */ | ||
2701 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2702 | $token['name'] === 'option') { | ||
2703 | /* If the current node is an option element, then pop that node | ||
2704 | from the stack of open elements. Otherwise, this is a parse error, | ||
2705 | ignore the token. */ | ||
2706 | if(end($this->stack)->tagName === 'option') { | ||
2707 | array_pop($this->stack); | ||
2708 | } else { | ||
2709 | // parse error | ||
2710 | $this->ignored = true; | ||
2711 | } | ||
2712 | |||
2713 | /* An end tag whose tag name is "select" */ | ||
2714 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2715 | $token['name'] === 'select') { | ||
2716 | /* If the stack of open elements does not have an element in table | ||
2717 | scope with the same tag name as the token, this is a parse error. | ||
2718 | Ignore the token. (fragment case) */ | ||
2719 | if(!$this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2720 | $this->ignored = true; | ||
2721 | // parse error | ||
2722 | |||
2723 | /* Otherwise: */ | ||
2724 | } else { | ||
2725 | /* Pop elements from the stack of open elements until a select | ||
2726 | element has been popped from the stack. */ | ||
2727 | do { | ||
2728 | $node = array_pop($this->stack); | ||
2729 | } while ($node->tagName !== 'select'); | ||
2730 | |||
2731 | /* Reset the insertion mode appropriately. */ | ||
2732 | $this->resetInsertionMode(); | ||
2733 | } | ||
2734 | |||
2735 | /* A start tag whose tag name is "select" */ | ||
2736 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'select') { | ||
2737 | /* Parse error. Act as if the token had been an end tag with the | ||
2738 | tag name "select" instead. */ | ||
2739 | $this->emitToken(array( | ||
2740 | 'name' => 'select', | ||
2741 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2742 | )); | ||
2743 | |||
2744 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2745 | ($token['name'] === 'input' || $token['name'] === 'keygen' || $token['name'] === 'textarea')) { | ||
2746 | // parse error | ||
2747 | $this->emitToken(array( | ||
2748 | 'name' => 'select', | ||
2749 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2750 | )); | ||
2751 | $this->emitToken($token); | ||
2752 | |||
2753 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'script') { | ||
2754 | $this->processWithRulesFor($token, self::IN_HEAD); | ||
2755 | |||
2756 | } elseif($token['type'] === HTML5_Tokenizer::EOF) { | ||
2757 | // XERROR: If the current node is not the root html element, then this is a parse error. | ||
2758 | /* Stop parsing */ | ||
2759 | |||
2760 | /* Anything else */ | ||
2761 | } else { | ||
2762 | /* Parse error. Ignore the token. */ | ||
2763 | $this->ignored = true; | ||
2764 | } | ||
2765 | break; | ||
2766 | |||
2767 | case self::IN_SELECT_IN_TABLE: | ||
2768 | |||
2769 | if($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2770 | in_array($token['name'], array('caption', 'table', 'tbody', | ||
2771 | 'tfoot', 'thead', 'tr', 'td', 'th'))) { | ||
2772 | // parse error | ||
2773 | $this->emitToken(array( | ||
2774 | 'name' => 'select', | ||
2775 | 'type' => HTML5_Tokenizer::ENDTAG, | ||
2776 | )); | ||
2777 | $this->emitToken($token); | ||
2778 | |||
2779 | /* An end tag whose tag name is one of: "caption", "table", "tbody", | ||
2780 | "tfoot", "thead", "tr", "td", "th" */ | ||
2781 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2782 | in_array($token['name'], array('caption', 'table', 'tbody', 'tfoot', 'thead', 'tr', 'td', 'th'))) { | ||
2783 | /* Parse error. */ | ||
2784 | // parse error | ||
2785 | |||
2786 | /* If the stack of open elements has an element in table scope with | ||
2787 | the same tag name as that of the token, then act as if an end tag | ||
2788 | with the tag name "select" had been seen, and reprocess the token. | ||
2789 | Otherwise, ignore the token. */ | ||
2790 | if($this->elementInScope($token['name'], self::SCOPE_TABLE)) { | ||
2791 | $this->emitToken(array( | ||
2792 | 'name' => 'select', | ||
2793 | 'type' => HTML5_Tokenizer::ENDTAG | ||
2794 | )); | ||
2795 | |||
2796 | $this->emitToken($token); | ||
2797 | } else { | ||
2798 | $this->ignored = true; | ||
2799 | } | ||
2800 | } else { | ||
2801 | $this->processWithRulesFor($token, self::IN_SELECT); | ||
2802 | } | ||
2803 | break; | ||
2804 | |||
2805 | case self::IN_FOREIGN_CONTENT: | ||
2806 | if ($token['type'] === HTML5_Tokenizer::CHARACTER || | ||
2807 | $token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
2808 | $this->insertText($token['data']); | ||
2809 | } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
2810 | $this->insertComment($token['data']); | ||
2811 | } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
2812 | // XERROR: parse error | ||
2813 | } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
2814 | $token['name'] === 'script' && end($this->stack)->tagName === 'script' && | ||
2815 | // XDOM | ||
2816 | end($this->stack)->namespaceURI === self::NS_SVG) { | ||
2817 | array_pop($this->stack); | ||
2818 | // a bunch of script running mumbo jumbo | ||
2819 | } elseif ( | ||
2820 | ($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2821 | (( | ||
2822 | $token['name'] !== 'mglyph' && | ||
2823 | $token['name'] !== 'malignmark' && | ||
2824 | // XDOM | ||
2825 | end($this->stack)->namespaceURI === self::NS_MATHML && | ||
2826 | in_array(end($this->stack)->tagName, array('mi', 'mo', 'mn', 'ms', 'mtext')) | ||
2827 | ) || | ||
2828 | ( | ||
2829 | $token['name'] === 'svg' && | ||
2830 | // XDOM | ||
2831 | end($this->stack)->namespaceURI === self::NS_MATHML && | ||
2832 | end($this->stack)->tagName === 'annotation-xml' | ||
2833 | ) || | ||
2834 | ( | ||
2835 | // XDOM | ||
2836 | end($this->stack)->namespaceURI === self::NS_SVG && | ||
2837 | in_array(end($this->stack)->tagName, array('foreignObject', 'desc', 'title')) | ||
2838 | ) || | ||
2839 | ( | ||
2840 | // XSKETCHY && XDOM | ||
2841 | end($this->stack)->namespaceURI === self::NS_HTML | ||
2842 | )) | ||
2843 | ) || $token['type'] === HTML5_Tokenizer::ENDTAG | ||
2844 | ) { | ||
2845 | $this->processWithRulesFor($token, $this->secondary_mode); | ||
2846 | /* If, after doing so, the insertion mode is still "in foreign | ||
2847 | * content", but there is no element in scope that has a namespace | ||
2848 | * other than the HTML namespace, switch the insertion mode to the | ||
2849 | * secondary insertion mode. */ | ||
2850 | if ($this->mode === self::IN_FOREIGN_CONTENT) { | ||
2851 | $found = false; | ||
2852 | // this basically duplicates elementInScope() | ||
2853 | for ($i = count($this->stack) - 1; $i >= 0; $i--) { | ||
2854 | // XDOM | ||
2855 | $node = $this->stack[$i]; | ||
2856 | if ($node->namespaceURI !== self::NS_HTML) { | ||
2857 | $found = true; | ||
2858 | break; | ||
2859 | } elseif (in_array($node->tagName, array('table', 'html', | ||
2860 | 'applet', 'caption', 'td', 'th', 'button', 'marquee', | ||
2861 | 'object')) || ($node->tagName === 'foreignObject' && | ||
2862 | $node->namespaceURI === self::NS_SVG)) { | ||
2863 | break; | ||
2864 | } | ||
2865 | } | ||
2866 | if (!$found) { | ||
2867 | $this->mode = $this->secondary_mode; | ||
2868 | } | ||
2869 | } | ||
2870 | } elseif ($token['type'] === HTML5_Tokenizer::EOF || ( | ||
2871 | $token['type'] === HTML5_Tokenizer::STARTTAG && | ||
2872 | (in_array($token['name'], array('b', "big", "blockquote", "body", "br", | ||
2873 | "center", "code", "dc", "dd", "div", "dl", "ds", "dt", "em", "embed", "h1", "h2", | ||
2874 | "h3", "h4", "h5", "h6", "head", "hr", "i", "img", "li", "listing", | ||
2875 | "menu", "meta", "nobr", "ol", "p", "pre", "ruby", "s", "small", | ||
2876 | "span", "strong", "strike", "sub", "sup", "table", "tt", "u", "ul", | ||
2877 | "var")) || ($token['name'] === 'font' && ($this->getAttr($token, 'color') || | ||
2878 | $this->getAttr($token, 'face') || $this->getAttr($token, 'size')))))) { | ||
2879 | // XERROR: parse error | ||
2880 | do { | ||
2881 | $node = array_pop($this->stack); | ||
2882 | // XDOM | ||
2883 | } while ($node->namespaceURI !== self::NS_HTML); | ||
2884 | $this->stack[] = $node; | ||
2885 | $this->mode = $this->secondary_mode; | ||
2886 | $this->emitToken($token); | ||
2887 | } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG) { | ||
2888 | static $svg_lookup = array( | ||
2889 | 'altglyph' => 'altGlyph', | ||
2890 | 'altglyphdef' => 'altGlyphDef', | ||
2891 | 'altglyphitem' => 'altGlyphItem', | ||
2892 | 'animatecolor' => 'animateColor', | ||
2893 | 'animatemotion' => 'animateMotion', | ||
2894 | 'animatetransform' => 'animateTransform', | ||
2895 | 'clippath' => 'clipPath', | ||
2896 | 'feblend' => 'feBlend', | ||
2897 | 'fecolormatrix' => 'feColorMatrix', | ||
2898 | 'fecomponenttransfer' => 'feComponentTransfer', | ||
2899 | 'fecomposite' => 'feComposite', | ||
2900 | 'feconvolvematrix' => 'feConvolveMatrix', | ||
2901 | 'fediffuselighting' => 'feDiffuseLighting', | ||
2902 | 'fedisplacementmap' => 'feDisplacementMap', | ||
2903 | 'fedistantlight' => 'feDistantLight', | ||
2904 | 'feflood' => 'feFlood', | ||
2905 | 'fefunca' => 'feFuncA', | ||
2906 | 'fefuncb' => 'feFuncB', | ||
2907 | 'fefuncg' => 'feFuncG', | ||
2908 | 'fefuncr' => 'feFuncR', | ||
2909 | 'fegaussianblur' => 'feGaussianBlur', | ||
2910 | 'feimage' => 'feImage', | ||
2911 | 'femerge' => 'feMerge', | ||
2912 | 'femergenode' => 'feMergeNode', | ||
2913 | 'femorphology' => 'feMorphology', | ||
2914 | 'feoffset' => 'feOffset', | ||
2915 | 'fepointlight' => 'fePointLight', | ||
2916 | 'fespecularlighting' => 'feSpecularLighting', | ||
2917 | 'fespotlight' => 'feSpotLight', | ||
2918 | 'fetile' => 'feTile', | ||
2919 | 'feturbulence' => 'feTurbulence', | ||
2920 | 'foreignobject' => 'foreignObject', | ||
2921 | 'glyphref' => 'glyphRef', | ||
2922 | 'lineargradient' => 'linearGradient', | ||
2923 | 'radialgradient' => 'radialGradient', | ||
2924 | 'textpath' => 'textPath', | ||
2925 | ); | ||
2926 | // XDOM | ||
2927 | $current = end($this->stack); | ||
2928 | if ($current->namespaceURI === self::NS_MATHML) { | ||
2929 | $token = $this->adjustMathMLAttributes($token); | ||
2930 | } | ||
2931 | if ($current->namespaceURI === self::NS_SVG && | ||
2932 | isset($svg_lookup[$token['name']])) { | ||
2933 | $token['name'] = $svg_lookup[$token['name']]; | ||
2934 | } | ||
2935 | if ($current->namespaceURI === self::NS_SVG) { | ||
2936 | $token = $this->adjustSVGAttributes($token); | ||
2937 | } | ||
2938 | $token = $this->adjustForeignAttributes($token); | ||
2939 | $this->insertForeignElement($token, $current->namespaceURI); | ||
2940 | if (isset($token['self-closing'])) { | ||
2941 | array_pop($this->stack); | ||
2942 | // XERROR: acknowledge self-closing flag | ||
2943 | } | ||
2944 | } | ||
2945 | break; | ||
2946 | |||
2947 | case self::AFTER_BODY: | ||
2948 | /* Handle the token as follows: */ | ||
2949 | |||
2950 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
2951 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
2952 | or U+0020 SPACE */ | ||
2953 | if($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
2954 | /* Process the token as it would be processed if the insertion mode | ||
2955 | was "in body". */ | ||
2956 | $this->processWithRulesFor($token, self::IN_BODY); | ||
2957 | |||
2958 | /* A comment token */ | ||
2959 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
2960 | /* Append a Comment node to the first element in the stack of open | ||
2961 | elements (the html element), with the data attribute set to the | ||
2962 | data given in the comment token. */ | ||
2963 | // XDOM | ||
2964 | $comment = $this->dom->createComment($token['data']); | ||
2965 | $this->stack[0]->appendChild($comment); | ||
2966 | |||
2967 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
2968 | // parse error | ||
2969 | |||
2970 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { | ||
2971 | $this->processWithRulesFor($token, self::IN_BODY); | ||
2972 | |||
2973 | /* An end tag with the tag name "html" */ | ||
2974 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'html') { | ||
2975 | /* If the parser was originally created as part of the HTML | ||
2976 | * fragment parsing algorithm, this is a parse error; ignore | ||
2977 | * the token. (fragment case) */ | ||
2978 | $this->ignored = true; | ||
2979 | // XERROR: implement this | ||
2980 | |||
2981 | $this->mode = self::AFTER_AFTER_BODY; | ||
2982 | |||
2983 | } elseif($token['type'] === HTML5_Tokenizer::EOF) { | ||
2984 | /* Stop parsing */ | ||
2985 | |||
2986 | /* Anything else */ | ||
2987 | } else { | ||
2988 | /* Parse error. Set the insertion mode to "in body" and reprocess | ||
2989 | the token. */ | ||
2990 | $this->mode = self::IN_BODY; | ||
2991 | $this->emitToken($token); | ||
2992 | } | ||
2993 | break; | ||
2994 | |||
2995 | case self::IN_FRAMESET: | ||
2996 | /* Handle the token as follows: */ | ||
2997 | |||
2998 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
2999 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
3000 | U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ | ||
3001 | if($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
3002 | /* Append the character to the current node. */ | ||
3003 | $this->insertText($token['data']); | ||
3004 | |||
3005 | /* A comment token */ | ||
3006 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
3007 | /* Append a Comment node to the current node with the data | ||
3008 | attribute set to the data given in the comment token. */ | ||
3009 | $this->insertComment($token['data']); | ||
3010 | |||
3011 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
3012 | // parse error | ||
3013 | |||
3014 | /* A start tag with the tag name "frameset" */ | ||
3015 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
3016 | $token['name'] === 'frameset') { | ||
3017 | $this->insertElement($token); | ||
3018 | |||
3019 | /* An end tag with the tag name "frameset" */ | ||
3020 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
3021 | $token['name'] === 'frameset') { | ||
3022 | /* If the current node is the root html element, then this is a | ||
3023 | parse error; ignore the token. (fragment case) */ | ||
3024 | if(end($this->stack)->tagName === 'html') { | ||
3025 | $this->ignored = true; | ||
3026 | // Parse error | ||
3027 | |||
3028 | } else { | ||
3029 | /* Otherwise, pop the current node from the stack of open | ||
3030 | elements. */ | ||
3031 | array_pop($this->stack); | ||
3032 | |||
3033 | /* If the parser was not originally created as part of the HTML | ||
3034 | * fragment parsing algorithm (fragment case), and the current | ||
3035 | * node is no longer a frameset element, then switch the | ||
3036 | * insertion mode to "after frameset". */ | ||
3037 | $this->mode = self::AFTER_FRAMESET; | ||
3038 | } | ||
3039 | |||
3040 | /* A start tag with the tag name "frame" */ | ||
3041 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
3042 | $token['name'] === 'frame') { | ||
3043 | /* Insert an HTML element for the token. */ | ||
3044 | $this->insertElement($token); | ||
3045 | |||
3046 | /* Immediately pop the current node off the stack of open elements. */ | ||
3047 | array_pop($this->stack); | ||
3048 | |||
3049 | // XERROR: Acknowledge the token's self-closing flag, if it is set. | ||
3050 | |||
3051 | /* A start tag with the tag name "noframes" */ | ||
3052 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
3053 | $token['name'] === 'noframes') { | ||
3054 | /* Process the token using the rules for the "in head" insertion mode. */ | ||
3055 | $this->processwithRulesFor($token, self::IN_HEAD); | ||
3056 | |||
3057 | } elseif($token['type'] === HTML5_Tokenizer::EOF) { | ||
3058 | // XERROR: If the current node is not the root html element, then this is a parse error. | ||
3059 | /* Stop parsing */ | ||
3060 | /* Anything else */ | ||
3061 | } else { | ||
3062 | /* Parse error. Ignore the token. */ | ||
3063 | $this->ignored = true; | ||
3064 | } | ||
3065 | break; | ||
3066 | |||
3067 | case self::AFTER_FRAMESET: | ||
3068 | /* Handle the token as follows: */ | ||
3069 | |||
3070 | /* A character token that is one of one of U+0009 CHARACTER TABULATION, | ||
3071 | U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), | ||
3072 | U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ | ||
3073 | if($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { | ||
3074 | /* Append the character to the current node. */ | ||
3075 | $this->insertText($token['data']); | ||
3076 | |||
3077 | /* A comment token */ | ||
3078 | } elseif($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
3079 | /* Append a Comment node to the current node with the data | ||
3080 | attribute set to the data given in the comment token. */ | ||
3081 | $this->insertComment($token['data']); | ||
3082 | |||
3083 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE) { | ||
3084 | // parse error | ||
3085 | |||
3086 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { | ||
3087 | $this->processWithRulesFor($token, self::IN_BODY); | ||
3088 | |||
3089 | /* An end tag with the tag name "html" */ | ||
3090 | } elseif($token['type'] === HTML5_Tokenizer::ENDTAG && | ||
3091 | $token['name'] === 'html') { | ||
3092 | $this->mode = self::AFTER_AFTER_FRAMESET; | ||
3093 | |||
3094 | /* A start tag with the tag name "noframes" */ | ||
3095 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && | ||
3096 | $token['name'] === 'noframes') { | ||
3097 | $this->processWithRulesFor($token, self::IN_HEAD); | ||
3098 | |||
3099 | } elseif($token['type'] === HTML5_Tokenizer::EOF) { | ||
3100 | /* Stop parsing */ | ||
3101 | |||
3102 | /* Anything else */ | ||
3103 | } else { | ||
3104 | /* Parse error. Ignore the token. */ | ||
3105 | $this->ignored = true; | ||
3106 | } | ||
3107 | break; | ||
3108 | |||
3109 | case self::AFTER_AFTER_BODY: | ||
3110 | /* A comment token */ | ||
3111 | if($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
3112 | /* Append a Comment node to the Document object with the data | ||
3113 | attribute set to the data given in the comment token. */ | ||
3114 | // XDOM | ||
3115 | $comment = $this->dom->createComment($token['data']); | ||
3116 | $this->dom->appendChild($comment); | ||
3117 | |||
3118 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE || | ||
3119 | $token['type'] === HTML5_Tokenizer::SPACECHARACTER || | ||
3120 | ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html')) { | ||
3121 | $this->processWithRulesFor($token, self::IN_BODY); | ||
3122 | |||
3123 | /* An end-of-file token */ | ||
3124 | } elseif($token['type'] === HTML5_Tokenizer::EOF) { | ||
3125 | /* OMG DONE!! */ | ||
3126 | } else { | ||
3127 | // parse error | ||
3128 | $this->mode = self::IN_BODY; | ||
3129 | $this->emitToken($token); | ||
3130 | } | ||
3131 | break; | ||
3132 | |||
3133 | case self::AFTER_AFTER_FRAMESET: | ||
3134 | /* A comment token */ | ||
3135 | if($token['type'] === HTML5_Tokenizer::COMMENT) { | ||
3136 | /* Append a Comment node to the Document object with the data | ||
3137 | attribute set to the data given in the comment token. */ | ||
3138 | // XDOM | ||
3139 | $comment = $this->dom->createComment($token['data']); | ||
3140 | $this->dom->appendChild($comment); | ||
3141 | |||
3142 | } elseif($token['type'] === HTML5_Tokenizer::DOCTYPE || | ||
3143 | $token['type'] === HTML5_Tokenizer::SPACECHARACTER || | ||
3144 | ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html')) { | ||
3145 | $this->processWithRulesFor($token, self::IN_BODY); | ||
3146 | |||
3147 | /* An end-of-file token */ | ||
3148 | } elseif($token['type'] === HTML5_Tokenizer::EOF) { | ||
3149 | /* OMG DONE!! */ | ||
3150 | } elseif($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'nofrmaes') { | ||
3151 | $this->processWithRulesFor($token, self::IN_HEAD); | ||
3152 | } else { | ||
3153 | // parse error | ||
3154 | } | ||
3155 | break; | ||
3156 | } | ||
3157 | // end funky indenting | ||
3158 | } | ||
3159 | |||
3160 | private function insertElement($token, $append = true) { | ||
3161 | //$el = $this->dom->createElementNS(self::NS_HTML, $token['name']); | ||
3162 | $namespaceURI = strpos($token['name'], ':') ? self::NS_XHTML : self::NS_HTML; | ||
3163 | $el = $this->dom->createElementNS($namespaceURI, $token['name']); | ||
3164 | |||
3165 | if (!empty($token['attr'])) { | ||
3166 | foreach($token['attr'] as $attr) { | ||
3167 | |||
3168 | // mike@macgirvin.com 2011-11-17, check attribute name for | ||
3169 | // validity (ignoring extenders and combiners) as illegal chars in names | ||
3170 | // causes everything to abort | ||
3171 | |||
3172 | $valid = preg_match('/^[a-zA-Z\_\:]([\-a-zA-Z0-9\_\:\.]+$)/',$attr['name']); | ||
3173 | if($attr['name'] && (!$el->hasAttribute($attr['name'])) && ($valid)) { | ||
3174 | $el->setAttribute($attr['name'], $attr['value']); | ||
3175 | } | ||
3176 | } | ||
3177 | } | ||
3178 | if ($append) { | ||
3179 | $this->appendToRealParent($el); | ||
3180 | $this->stack[] = $el; | ||
3181 | } | ||
3182 | |||
3183 | return $el; | ||
3184 | } | ||
3185 | |||
3186 | private function insertText($data) { | ||
3187 | if ($data === '') return; | ||
3188 | if ($this->ignore_lf_token) { | ||
3189 | if ($data[0] === "\n") { | ||
3190 | $data = substr($data, 1); | ||
3191 | if ($data === false) return; | ||
3192 | } | ||
3193 | } | ||
3194 | $text = $this->dom->createTextNode($data); | ||
3195 | $this->appendToRealParent($text); | ||
3196 | } | ||
3197 | |||
3198 | private function insertComment($data) { | ||
3199 | $comment = $this->dom->createComment($data); | ||
3200 | $this->appendToRealParent($comment); | ||
3201 | } | ||
3202 | |||
3203 | private function appendToRealParent($node) { | ||
3204 | // this is only for the foster_parent case | ||
3205 | /* If the current node is a table, tbody, tfoot, thead, or tr | ||
3206 | element, then, whenever a node would be inserted into the current | ||
3207 | node, it must instead be inserted into the foster parent element. */ | ||
3208 | if(!$this->foster_parent || !in_array(end($this->stack)->tagName, | ||
3209 | array('table', 'tbody', 'tfoot', 'thead', 'tr'))) { | ||
3210 | end($this->stack)->appendChild($node); | ||
3211 | } else { | ||
3212 | $this->fosterParent($node); | ||
3213 | } | ||
3214 | } | ||
3215 | |||
3216 | private function elementInScope($el, $scope = self::SCOPE) { | ||
3217 | if(is_array($el)) { | ||
3218 | foreach($el as $element) { | ||
3219 | if($this->elementInScope($element, $scope)) { | ||
3220 | return true; | ||
3221 | } | ||
3222 | } | ||
3223 | |||
3224 | return false; | ||
3225 | } | ||
3226 | |||
3227 | $leng = count($this->stack); | ||
3228 | |||
3229 | for($n = 0; $n < $leng; $n++) { | ||
3230 | /* 1. Initialise node to be the current node (the bottommost node of | ||
3231 | the stack). */ | ||
3232 | $node = $this->stack[$leng - 1 - $n]; | ||
3233 | |||
3234 | if($node->tagName === $el) { | ||
3235 | /* 2. If node is the target node, terminate in a match state. */ | ||
3236 | return true; | ||
3237 | |||
3238 | // We've expanded the logic for these states a little differently; | ||
3239 | // Hixie's refactoring into "specific scope" is more general, but | ||
3240 | // this "gets the job done" | ||
3241 | |||
3242 | // these are the common states for all scopes | ||
3243 | } elseif($node->tagName === 'table' || $node->tagName === 'html') { | ||
3244 | return false; | ||
3245 | |||
3246 | // these are valid for "in scope" and "in list item scope" | ||
3247 | } elseif($scope !== self::SCOPE_TABLE && | ||
3248 | (in_array($node->tagName, array('applet', 'caption', 'td', | ||
3249 | 'th', 'button', 'marquee', 'object')) || | ||
3250 | $node->tagName === 'foreignObject' && $node->namespaceURI === self::NS_SVG)) { | ||
3251 | return false; | ||
3252 | |||
3253 | |||
3254 | // these are valid for "in list item scope" | ||
3255 | } elseif($scope === self::SCOPE_LISTITEM && in_array($node->tagName, array('ol', 'ul'))) { | ||
3256 | return false; | ||
3257 | } | ||
3258 | |||
3259 | /* Otherwise, set node to the previous entry in the stack of open | ||
3260 | elements and return to step 2. (This will never fail, since the loop | ||
3261 | will always terminate in the previous step if the top of the stack | ||
3262 | is reached.) */ | ||
3263 | } | ||
3264 | } | ||
3265 | |||
3266 | private function reconstructActiveFormattingElements() { | ||
3267 | /* 1. If there are no entries in the list of active formatting elements, | ||
3268 | then there is nothing to reconstruct; stop this algorithm. */ | ||
3269 | $formatting_elements = count($this->a_formatting); | ||
3270 | |||
3271 | if($formatting_elements === 0) { | ||
3272 | return false; | ||
3273 | } | ||
3274 | |||
3275 | /* 3. Let entry be the last (most recently added) element in the list | ||
3276 | of active formatting elements. */ | ||
3277 | $entry = end($this->a_formatting); | ||
3278 | |||
3279 | /* 2. If the last (most recently added) entry in the list of active | ||
3280 | formatting elements is a marker, or if it is an element that is in the | ||
3281 | stack of open elements, then there is nothing to reconstruct; stop this | ||
3282 | algorithm. */ | ||
3283 | if($entry === self::MARKER || in_array($entry, $this->stack, true)) { | ||
3284 | return false; | ||
3285 | } | ||
3286 | |||
3287 | for($a = $formatting_elements - 1; $a >= 0; true) { | ||
3288 | /* 4. If there are no entries before entry in the list of active | ||
3289 | formatting elements, then jump to step 8. */ | ||
3290 | if($a === 0) { | ||
3291 | $step_seven = false; | ||
3292 | break; | ||
3293 | } | ||
3294 | |||
3295 | /* 5. Let entry be the entry one earlier than entry in the list of | ||
3296 | active formatting elements. */ | ||
3297 | $a--; | ||
3298 | $entry = $this->a_formatting[$a]; | ||
3299 | |||
3300 | /* 6. If entry is neither a marker nor an element that is also in | ||
3301 | thetack of open elements, go to step 4. */ | ||
3302 | if($entry === self::MARKER || in_array($entry, $this->stack, true)) { | ||
3303 | break; | ||
3304 | } | ||
3305 | } | ||
3306 | |||
3307 | while(true) { | ||
3308 | /* 7. Let entry be the element one later than entry in the list of | ||
3309 | active formatting elements. */ | ||
3310 | if(isset($step_seven) && $step_seven === true) { | ||
3311 | $a++; | ||
3312 | $entry = $this->a_formatting[$a]; | ||
3313 | } | ||
3314 | |||
3315 | /* 8. Perform a shallow clone of the element entry to obtain clone. */ | ||
3316 | $clone = $entry->cloneNode(); | ||
3317 | |||
3318 | /* 9. Append clone to the current node and push it onto the stack | ||
3319 | of open elements so that it is the new current node. */ | ||
3320 | $this->appendToRealParent($clone); | ||
3321 | $this->stack[] = $clone; | ||
3322 | |||
3323 | /* 10. Replace the entry for entry in the list with an entry for | ||
3324 | clone. */ | ||
3325 | $this->a_formatting[$a] = $clone; | ||
3326 | |||
3327 | /* 11. If the entry for clone in the list of active formatting | ||
3328 | elements is not the last entry in the list, return to step 7. */ | ||
3329 | if(end($this->a_formatting) !== $clone) { | ||
3330 | $step_seven = true; | ||
3331 | } else { | ||
3332 | break; | ||
3333 | } | ||
3334 | } | ||
3335 | } | ||
3336 | |||
3337 | private function clearTheActiveFormattingElementsUpToTheLastMarker() { | ||
3338 | /* When the steps below require the UA to clear the list of active | ||
3339 | formatting elements up to the last marker, the UA must perform the | ||
3340 | following steps: */ | ||
3341 | |||
3342 | while(true) { | ||
3343 | /* 1. Let entry be the last (most recently added) entry in the list | ||
3344 | of active formatting elements. */ | ||
3345 | $entry = end($this->a_formatting); | ||
3346 | |||
3347 | /* 2. Remove entry from the list of active formatting elements. */ | ||
3348 | array_pop($this->a_formatting); | ||
3349 | |||
3350 | /* 3. If entry was a marker, then stop the algorithm at this point. | ||
3351 | The list has been cleared up to the last marker. */ | ||
3352 | if($entry === self::MARKER) { | ||
3353 | break; | ||
3354 | } | ||
3355 | } | ||
3356 | } | ||
3357 | |||
3358 | private function generateImpliedEndTags($exclude = array()) { | ||
3359 | /* When the steps below require the UA to generate implied end tags, | ||
3360 | * then, while the current node is a dc element, a dd element, a ds | ||
3361 | * element, a dt element, an li element, an option element, an optgroup | ||
3362 | * element, a p element, an rp element, or an rt element, the UA must | ||
3363 | * pop the current node off the stack of open elements. */ | ||
3364 | $node = end($this->stack); | ||
3365 | $elements = array_diff(array('dc', 'dd', 'ds', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude); | ||
3366 | |||
3367 | while(in_array(end($this->stack)->tagName, $elements)) { | ||
3368 | array_pop($this->stack); | ||
3369 | } | ||
3370 | } | ||
3371 | |||
3372 | private function getElementCategory($node) { | ||
3373 | if (!is_object($node)) debug_print_backtrace(); | ||
3374 | $name = $node->tagName; | ||
3375 | if(in_array($name, $this->special)) | ||
3376 | return self::SPECIAL; | ||
3377 | |||
3378 | elseif(in_array($name, $this->scoping)) | ||
3379 | return self::SCOPING; | ||
3380 | |||
3381 | elseif(in_array($name, $this->formatting)) | ||
3382 | return self::FORMATTING; | ||
3383 | |||
3384 | else | ||
3385 | return self::PHRASING; | ||
3386 | } | ||
3387 | |||
3388 | private function clearStackToTableContext($elements) { | ||
3389 | /* When the steps above require the UA to clear the stack back to a | ||
3390 | table context, it means that the UA must, while the current node is not | ||
3391 | a table element or an html element, pop elements from the stack of open | ||
3392 | elements. */ | ||
3393 | while(true) { | ||
3394 | $name = end($this->stack)->tagName; | ||
3395 | |||
3396 | if(in_array($name, $elements)) { | ||
3397 | break; | ||
3398 | } else { | ||
3399 | array_pop($this->stack); | ||
3400 | } | ||
3401 | } | ||
3402 | } | ||
3403 | |||
3404 | private function resetInsertionMode($context = null) { | ||
3405 | /* 1. Let last be false. */ | ||
3406 | $last = false; | ||
3407 | $leng = count($this->stack); | ||
3408 | |||
3409 | for($n = $leng - 1; $n >= 0; $n--) { | ||
3410 | /* 2. Let node be the last node in the stack of open elements. */ | ||
3411 | $node = $this->stack[$n]; | ||
3412 | |||
3413 | /* 3. If node is the first node in the stack of open elements, then | ||
3414 | * set last to true and set node to the context element. (fragment | ||
3415 | * case) */ | ||
3416 | if($this->stack[0]->isSameNode($node)) { | ||
3417 | $last = true; | ||
3418 | $node = $context; | ||
3419 | } | ||
3420 | |||
3421 | /* 4. If node is a select element, then switch the insertion mode to | ||
3422 | "in select" and abort these steps. (fragment case) */ | ||
3423 | if($node->tagName === 'select') { | ||
3424 | $this->mode = self::IN_SELECT; | ||
3425 | break; | ||
3426 | |||
3427 | /* 5. If node is a td or th element, then switch the insertion mode | ||
3428 | to "in cell" and abort these steps. */ | ||
3429 | } elseif($node->tagName === 'td' || $node->nodeName === 'th') { | ||
3430 | $this->mode = self::IN_CELL; | ||
3431 | break; | ||
3432 | |||
3433 | /* 6. If node is a tr element, then switch the insertion mode to | ||
3434 | "in row" and abort these steps. */ | ||
3435 | } elseif($node->tagName === 'tr') { | ||
3436 | $this->mode = self::IN_ROW; | ||
3437 | break; | ||
3438 | |||
3439 | /* 7. If node is a tbody, thead, or tfoot element, then switch the | ||
3440 | insertion mode to "in table body" and abort these steps. */ | ||
3441 | } elseif(in_array($node->tagName, array('tbody', 'thead', 'tfoot'))) { | ||
3442 | $this->mode = self::IN_TABLE_BODY; | ||
3443 | break; | ||
3444 | |||
3445 | /* 8. If node is a caption element, then switch the insertion mode | ||
3446 | to "in caption" and abort these steps. */ | ||
3447 | } elseif($node->tagName === 'caption') { | ||
3448 | $this->mode = self::IN_CAPTION; | ||
3449 | break; | ||
3450 | |||
3451 | /* 9. If node is a colgroup element, then switch the insertion mode | ||
3452 | to "in column group" and abort these steps. (innerHTML case) */ | ||
3453 | } elseif($node->tagName === 'colgroup') { | ||
3454 | $this->mode = self::IN_COLUMN_GROUP; | ||
3455 | break; | ||
3456 | |||
3457 | /* 10. If node is a table element, then switch the insertion mode | ||
3458 | to "in table" and abort these steps. */ | ||
3459 | } elseif($node->tagName === 'table') { | ||
3460 | $this->mode = self::IN_TABLE; | ||
3461 | break; | ||
3462 | |||
3463 | /* 11. If node is an element from the MathML namespace or the SVG | ||
3464 | * namespace, then switch the insertion mode to "in foreign | ||
3465 | * content", let the secondary insertion mode be "in body", and | ||
3466 | * abort these steps. */ | ||
3467 | } elseif($node->namespaceURI === self::NS_SVG || | ||
3468 | $node->namespaceURI === self::NS_MATHML) { | ||
3469 | $this->mode = self::IN_FOREIGN_CONTENT; | ||
3470 | $this->secondary_mode = self::IN_BODY; | ||
3471 | break; | ||
3472 | |||
3473 | /* 12. If node is a head element, then switch the insertion mode | ||
3474 | to "in body" ("in body"! not "in head"!) and abort these steps. | ||
3475 | (fragment case) */ | ||
3476 | } elseif($node->tagName === 'head') { | ||
3477 | $this->mode = self::IN_BODY; | ||
3478 | break; | ||
3479 | |||
3480 | /* 13. If node is a body element, then switch the insertion mode to | ||
3481 | "in body" and abort these steps. */ | ||
3482 | } elseif($node->tagName === 'body') { | ||
3483 | $this->mode = self::IN_BODY; | ||
3484 | break; | ||
3485 | |||
3486 | /* 14. If node is a frameset element, then switch the insertion | ||
3487 | mode to "in frameset" and abort these steps. (fragment case) */ | ||
3488 | } elseif($node->tagName === 'frameset') { | ||
3489 | $this->mode = self::IN_FRAMESET; | ||
3490 | break; | ||
3491 | |||
3492 | /* 15. If node is an html element, then: if the head element | ||
3493 | pointer is null, switch the insertion mode to "before head", | ||
3494 | otherwise, switch the insertion mode to "after head". In either | ||
3495 | case, abort these steps. (fragment case) */ | ||
3496 | } elseif($node->tagName === 'html') { | ||
3497 | $this->mode = ($this->head_pointer === null) | ||
3498 | ? self::BEFORE_HEAD | ||
3499 | : self::AFTER_HEAD; | ||
3500 | |||
3501 | break; | ||
3502 | |||
3503 | /* 16. If last is true, then set the insertion mode to "in body" | ||
3504 | and abort these steps. (fragment case) */ | ||
3505 | } elseif($last) { | ||
3506 | $this->mode = self::IN_BODY; | ||
3507 | break; | ||
3508 | } | ||
3509 | } | ||
3510 | } | ||
3511 | |||
3512 | private function closeCell() { | ||
3513 | /* If the stack of open elements has a td or th element in table scope, | ||
3514 | then act as if an end tag token with that tag name had been seen. */ | ||
3515 | foreach(array('td', 'th') as $cell) { | ||
3516 | if($this->elementInScope($cell, self::SCOPE_TABLE)) { | ||
3517 | $this->emitToken(array( | ||
3518 | 'name' => $cell, | ||
3519 | 'type' => HTML5_Tokenizer::ENDTAG | ||
3520 | )); | ||
3521 | |||
3522 | break; | ||
3523 | } | ||
3524 | } | ||
3525 | } | ||
3526 | |||
3527 | private function processWithRulesFor($token, $mode) { | ||
3528 | /* "using the rules for the m insertion mode", where m is one of these | ||
3529 | * modes, the user agent must use the rules described under the m | ||
3530 | * insertion mode's section, but must leave the insertion mode | ||
3531 | * unchanged unless the rules in m themselves switch the insertion mode | ||
3532 | * to a new value. */ | ||
3533 | return $this->emitToken($token, $mode); | ||
3534 | } | ||
3535 | |||
3536 | private function insertCDATAElement($token) { | ||
3537 | $this->insertElement($token); | ||
3538 | $this->original_mode = $this->mode; | ||
3539 | $this->mode = self::IN_CDATA_RCDATA; | ||
3540 | $this->content_model = HTML5_Tokenizer::CDATA; | ||
3541 | } | ||
3542 | |||
3543 | private function insertRCDATAElement($token) { | ||
3544 | $this->insertElement($token); | ||
3545 | $this->original_mode = $this->mode; | ||
3546 | $this->mode = self::IN_CDATA_RCDATA; | ||
3547 | $this->content_model = HTML5_Tokenizer::RCDATA; | ||
3548 | } | ||
3549 | |||
3550 | private function getAttr($token, $key) { | ||
3551 | if (!isset($token['attr'])) return false; | ||
3552 | $ret = false; | ||
3553 | foreach ($token['attr'] as $keypair) { | ||
3554 | if ($keypair['name'] === $key) $ret = $keypair['value']; | ||
3555 | } | ||
3556 | return $ret; | ||
3557 | } | ||
3558 | |||
3559 | private function getCurrentTable() { | ||
3560 | /* The current table is the last table element in the stack of open | ||
3561 | * elements, if there is one. If there is no table element in the stack | ||
3562 | * of open elements (fragment case), then the current table is the | ||
3563 | * first element in the stack of open elements (the html element). */ | ||
3564 | for ($i = count($this->stack) - 1; $i >= 0; $i--) { | ||
3565 | if ($this->stack[$i]->tagName === 'table') { | ||
3566 | return $this->stack[$i]; | ||
3567 | } | ||
3568 | } | ||
3569 | return $this->stack[0]; | ||
3570 | } | ||
3571 | |||
3572 | private function getFosterParent() { | ||
3573 | /* The foster parent element is the parent element of the last | ||
3574 | table element in the stack of open elements, if there is a | ||
3575 | table element and it has such a parent element. If there is no | ||
3576 | table element in the stack of open elements (innerHTML case), | ||
3577 | then the foster parent element is the first element in the | ||
3578 | stack of open elements (the html element). Otherwise, if there | ||
3579 | is a table element in the stack of open elements, but the last | ||
3580 | table element in the stack of open elements has no parent, or | ||
3581 | its parent node is not an element, then the foster parent | ||
3582 | element is the element before the last table element in the | ||
3583 | stack of open elements. */ | ||
3584 | for($n = count($this->stack) - 1; $n >= 0; $n--) { | ||
3585 | if($this->stack[$n]->tagName === 'table') { | ||
3586 | $table = $this->stack[$n]; | ||
3587 | break; | ||
3588 | } | ||
3589 | } | ||
3590 | |||
3591 | if(isset($table) && $table->parentNode !== null) { | ||
3592 | return $table->parentNode; | ||
3593 | |||
3594 | } elseif(!isset($table)) { | ||
3595 | return $this->stack[0]; | ||
3596 | |||
3597 | } elseif(isset($table) && ($table->parentNode === null || | ||
3598 | $table->parentNode->nodeType !== XML_ELEMENT_NODE)) { | ||
3599 | return $this->stack[$n - 1]; | ||
3600 | } | ||
3601 | } | ||
3602 | |||
3603 | public function fosterParent($node) { | ||
3604 | $foster_parent = $this->getFosterParent(); | ||
3605 | $table = $this->getCurrentTable(); // almost equivalent to last table element, except it can be html | ||
3606 | /* When a node node is to be foster parented, the node node must be | ||
3607 | * be inserted into the foster parent element. */ | ||
3608 | /* If the foster parent element is the parent element of the last table | ||
3609 | * element in the stack of open elements, then node must be inserted | ||
3610 | * immediately before the last table element in the stack of open | ||
3611 | * elements in the foster parent element; otherwise, node must be | ||
3612 | * appended to the foster parent element. */ | ||
3613 | if ($table->tagName === 'table' && $table->parentNode->isSameNode($foster_parent)) { | ||
3614 | $foster_parent->insertBefore($node, $table); | ||
3615 | } else { | ||
3616 | $foster_parent->appendChild($node); | ||
3617 | } | ||
3618 | } | ||
3619 | |||
3620 | /** | ||
3621 | * For debugging, prints the stack | ||
3622 | */ | ||
3623 | private function printStack() { | ||
3624 | $names = array(); | ||
3625 | foreach ($this->stack as $i => $element) { | ||
3626 | $names[] = $element->tagName; | ||
3627 | } | ||
3628 | echo " -> stack [" . implode(', ', $names) . "]\n"; | ||
3629 | } | ||
3630 | |||
3631 | /** | ||
3632 | * For debugging, prints active formatting elements | ||
3633 | */ | ||
3634 | private function printActiveFormattingElements() { | ||
3635 | if (!$this->a_formatting) return; | ||
3636 | $names = array(); | ||
3637 | foreach ($this->a_formatting as $node) { | ||
3638 | if ($node === self::MARKER) $names[] = 'MARKER'; | ||
3639 | else $names[] = $node->tagName; | ||
3640 | } | ||
3641 | echo " -> active formatting [" . implode(', ', $names) . "]\n"; | ||
3642 | } | ||
3643 | |||
3644 | public function currentTableIsTainted() { | ||
3645 | return !empty($this->getCurrentTable()->tainted); | ||
3646 | } | ||
3647 | |||
3648 | /** | ||
3649 | * Sets up the tree constructor for building a fragment. | ||
3650 | */ | ||
3651 | public function setupContext($context = null) { | ||
3652 | $this->fragment = true; | ||
3653 | if ($context) { | ||
3654 | $context = $this->dom->createElementNS(self::NS_HTML, $context); | ||
3655 | /* 4.1. Set the HTML parser's tokenization stage's content model | ||
3656 | * flag according to the context element, as follows: */ | ||
3657 | switch ($context->tagName) { | ||
3658 | case 'title': case 'textarea': | ||
3659 | $this->content_model = HTML5_Tokenizer::RCDATA; | ||
3660 | break; | ||
3661 | case 'style': case 'script': case 'xmp': case 'iframe': | ||
3662 | case 'noembed': case 'noframes': | ||
3663 | $this->content_model = HTML5_Tokenizer::CDATA; | ||
3664 | break; | ||
3665 | case 'noscript': | ||
3666 | // XSCRIPT: assuming scripting is enabled | ||
3667 | $this->content_model = HTML5_Tokenizer::CDATA; | ||
3668 | break; | ||
3669 | case 'plaintext': | ||
3670 | $this->content_model = HTML5_Tokenizer::PLAINTEXT; | ||
3671 | break; | ||
3672 | } | ||
3673 | /* 4.2. Let root be a new html element with no attributes. */ | ||
3674 | $root = $this->dom->createElementNS(self::NS_HTML, 'html'); | ||
3675 | $this->root = $root; | ||
3676 | /* 4.3 Append the element root to the Document node created above. */ | ||
3677 | $this->dom->appendChild($root); | ||
3678 | /* 4.4 Set up the parser's stack of open elements so that it | ||
3679 | * contains just the single element root. */ | ||
3680 | $this->stack = array($root); | ||
3681 | /* 4.5 Reset the parser's insertion mode appropriately. */ | ||
3682 | $this->resetInsertionMode($context); | ||
3683 | /* 4.6 Set the parser's form element pointer to the nearest node | ||
3684 | * to the context element that is a form element (going straight up | ||
3685 | * the ancestor chain, and including the element itself, if it is a | ||
3686 | * form element), or, if there is no such form element, to null. */ | ||
3687 | $node = $context; | ||
3688 | do { | ||
3689 | if ($node->tagName === 'form') { | ||
3690 | $this->form_pointer = $node; | ||
3691 | break; | ||
3692 | } | ||
3693 | } while ($node = $node->parentNode); | ||
3694 | } | ||
3695 | } | ||
3696 | |||
3697 | public function adjustMathMLAttributes($token) { | ||
3698 | foreach ($token['attr'] as &$kp) { | ||
3699 | if ($kp['name'] === 'definitionurl') { | ||
3700 | $kp['name'] = 'definitionURL'; | ||
3701 | } | ||
3702 | } | ||
3703 | return $token; | ||
3704 | } | ||
3705 | |||
3706 | public function adjustSVGAttributes($token) { | ||
3707 | static $lookup = array( | ||
3708 | 'attributename' => 'attributeName', | ||
3709 | 'attributetype' => 'attributeType', | ||
3710 | 'basefrequency' => 'baseFrequency', | ||
3711 | 'baseprofile' => 'baseProfile', | ||
3712 | 'calcmode' => 'calcMode', | ||
3713 | 'clippathunits' => 'clipPathUnits', | ||
3714 | 'contentscripttype' => 'contentScriptType', | ||
3715 | 'contentstyletype' => 'contentStyleType', | ||
3716 | 'diffuseconstant' => 'diffuseConstant', | ||
3717 | 'edgemode' => 'edgeMode', | ||
3718 | 'externalresourcesrequired' => 'externalResourcesRequired', | ||
3719 | 'filterres' => 'filterRes', | ||
3720 | 'filterunits' => 'filterUnits', | ||
3721 | 'glyphref' => 'glyphRef', | ||
3722 | 'gradienttransform' => 'gradientTransform', | ||
3723 | 'gradientunits' => 'gradientUnits', | ||
3724 | 'kernelmatrix' => 'kernelMatrix', | ||
3725 | 'kernelunitlength' => 'kernelUnitLength', | ||
3726 | 'keypoints' => 'keyPoints', | ||
3727 | 'keysplines' => 'keySplines', | ||
3728 | 'keytimes' => 'keyTimes', | ||
3729 | 'lengthadjust' => 'lengthAdjust', | ||
3730 | 'limitingconeangle' => 'limitingConeAngle', | ||
3731 | 'markerheight' => 'markerHeight', | ||
3732 | 'markerunits' => 'markerUnits', | ||
3733 | 'markerwidth' => 'markerWidth', | ||
3734 | 'maskcontentunits' => 'maskContentUnits', | ||
3735 | 'maskunits' => 'maskUnits', | ||
3736 | 'numoctaves' => 'numOctaves', | ||
3737 | 'pathlength' => 'pathLength', | ||
3738 | 'patterncontentunits' => 'patternContentUnits', | ||
3739 | 'patterntransform' => 'patternTransform', | ||
3740 | 'patternunits' => 'patternUnits', | ||
3741 | 'pointsatx' => 'pointsAtX', | ||
3742 | 'pointsaty' => 'pointsAtY', | ||
3743 | 'pointsatz' => 'pointsAtZ', | ||
3744 | 'preservealpha' => 'preserveAlpha', | ||
3745 | 'preserveaspectratio' => 'preserveAspectRatio', | ||
3746 | 'primitiveunits' => 'primitiveUnits', | ||
3747 | 'refx' => 'refX', | ||
3748 | 'refy' => 'refY', | ||
3749 | 'repeatcount' => 'repeatCount', | ||
3750 | 'repeatdur' => 'repeatDur', | ||
3751 | 'requiredextensions' => 'requiredExtensions', | ||
3752 | 'requiredfeatures' => 'requiredFeatures', | ||
3753 | 'specularconstant' => 'specularConstant', | ||
3754 | 'specularexponent' => 'specularExponent', | ||
3755 | 'spreadmethod' => 'spreadMethod', | ||
3756 | 'startoffset' => 'startOffset', | ||
3757 | 'stddeviation' => 'stdDeviation', | ||
3758 | 'stitchtiles' => 'stitchTiles', | ||
3759 | 'surfacescale' => 'surfaceScale', | ||
3760 | 'systemlanguage' => 'systemLanguage', | ||
3761 | 'tablevalues' => 'tableValues', | ||
3762 | 'targetx' => 'targetX', | ||
3763 | 'targety' => 'targetY', | ||
3764 | 'textlength' => 'textLength', | ||
3765 | 'viewbox' => 'viewBox', | ||
3766 | 'viewtarget' => 'viewTarget', | ||
3767 | 'xchannelselector' => 'xChannelSelector', | ||
3768 | 'ychannelselector' => 'yChannelSelector', | ||
3769 | 'zoomandpan' => 'zoomAndPan', | ||
3770 | ); | ||
3771 | foreach ($token['attr'] as &$kp) { | ||
3772 | if (isset($lookup[$kp['name']])) { | ||
3773 | $kp['name'] = $lookup[$kp['name']]; | ||
3774 | } | ||
3775 | } | ||
3776 | return $token; | ||
3777 | } | ||
3778 | |||
3779 | public function adjustForeignAttributes($token) { | ||
3780 | static $lookup = array( | ||
3781 | 'xlink:actuate' => array('xlink', 'actuate', self::NS_XLINK), | ||
3782 | 'xlink:arcrole' => array('xlink', 'arcrole', self::NS_XLINK), | ||
3783 | 'xlink:href' => array('xlink', 'href', self::NS_XLINK), | ||
3784 | 'xlink:role' => array('xlink', 'role', self::NS_XLINK), | ||
3785 | 'xlink:show' => array('xlink', 'show', self::NS_XLINK), | ||
3786 | 'xlink:title' => array('xlink', 'title', self::NS_XLINK), | ||
3787 | 'xlink:type' => array('xlink', 'type', self::NS_XLINK), | ||
3788 | 'xml:base' => array('xml', 'base', self::NS_XML), | ||
3789 | 'xml:lang' => array('xml', 'lang', self::NS_XML), | ||
3790 | 'xml:space' => array('xml', 'space', self::NS_XML), | ||
3791 | 'xmlns' => array(null, 'xmlns', self::NS_XMLNS), | ||
3792 | 'xmlns:xlink' => array('xmlns', 'xlink', self::NS_XMLNS), | ||
3793 | ); | ||
3794 | foreach ($token['attr'] as &$kp) { | ||
3795 | if (isset($lookup[$kp['name']])) { | ||
3796 | $kp['name'] = $lookup[$kp['name']]; | ||
3797 | } | ||
3798 | } | ||
3799 | return $token; | ||
3800 | } | ||
3801 | |||
3802 | public function insertForeignElement($token, $namespaceURI) { | ||
3803 | $el = $this->dom->createElementNS($namespaceURI, $token['name']); | ||
3804 | if (!empty($token['attr'])) { | ||
3805 | foreach ($token['attr'] as $kp) { | ||
3806 | $attr = $kp['name']; | ||
3807 | if (is_array($attr)) { | ||
3808 | $ns = $attr[2]; | ||
3809 | $attr = $attr[1]; | ||
3810 | } else { | ||
3811 | $ns = self::NS_HTML; | ||
3812 | } | ||
3813 | if (!$el->hasAttributeNS($ns, $attr)) { | ||
3814 | // XSKETCHY: work around godawful libxml bug | ||
3815 | if ($ns === self::NS_XLINK) { | ||
3816 | $el->setAttribute('xlink:'.$attr, $kp['value']); | ||
3817 | } elseif ($ns === self::NS_HTML) { | ||
3818 | // Another godawful libxml bug | ||
3819 | $el->setAttribute($attr, $kp['value']); | ||
3820 | } else { | ||
3821 | $el->setAttributeNS($ns, $attr, $kp['value']); | ||
3822 | } | ||
3823 | } | ||
3824 | } | ||
3825 | } | ||
3826 | $this->appendToRealParent($el); | ||
3827 | $this->stack[] = $el; | ||
3828 | // XERROR: see below | ||
3829 | /* If the newly created element has an xmlns attribute in the XMLNS | ||
3830 | * namespace whose value is not exactly the same as the element's | ||
3831 | * namespace, that is a parse error. Similarly, if the newly created | ||
3832 | * element has an xmlns:xlink attribute in the XMLNS namespace whose | ||
3833 | * value is not the XLink Namespace, that is a parse error. */ | ||
3834 | } | ||
3835 | |||
3836 | public function save() { | ||
3837 | $this->dom->normalize(); | ||
3838 | if (!$this->fragment) { | ||
3839 | return $this->dom; | ||
3840 | } else { | ||
3841 | if ($this->root) { | ||
3842 | return $this->root->childNodes; | ||
3843 | } else { | ||
3844 | return $this->dom->childNodes; | ||
3845 | } | ||
3846 | } | ||
3847 | } | ||
3848 | } | ||
3849 | |||
diff --git a/inc/3rdparty/libraries/html5/named-character-references.ser b/inc/3rdparty/libraries/html5/named-character-references.ser deleted file mode 100644 index e3ae0502..00000000 --- a/inc/3rdparty/libraries/html5/named-character-references.ser +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | a:52:{s:1:"A";a:16:{s:1:"E";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:198;}s:9:"codepoint";i:198;}}}}s:1:"M";a:1:{s:1:"P";a:2:{s:1:";";a:1:{s:9:"codepoint";i:38;}s:9:"codepoint";i:38;}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:193;}s:9:"codepoint";i:193;}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:258;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:194;}s:9:"codepoint";i:194;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1040;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120068;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:192;}s:9:"codepoint";i:192;}}}}}s:1:"l";a:1:{s:1:"p";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:913;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:256;}}}}}s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10835;}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:260;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120120;}}}}s:1:"p";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"y";a:1:{s:1:"F";a:1:{s:1:"u";a:1:{s:1:"n";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8289;}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:197;}s:9:"codepoint";i:197;}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119964;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8788;}}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:195;}s:9:"codepoint";i:195;}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:196;}s:9:"codepoint";i:196;}}}}s:1:"B";a:8:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"s";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}}}}s:1:"r";a:2:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10983;}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8966;}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1041;}}}s:1:"e";a:3:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8757;}}}}}}s:1:"r";a:1:{s:1:"n";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8492;}}}}}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:914;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120069;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120121;}}}}s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:728;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8492;}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8782;}}}}}}}s:1:"C";a:14:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1063;}}}}s:1:"O";a:1:{s:1:"P";a:1:{s:1:"Y";a:2:{s:1:";";a:1:{s:9:"codepoint";i:169;}s:9:"codepoint";i:169;}}}s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:262;}}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8914;}s:1:"i";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:"i";a:1:{s:1:"f";a:1:{s:1:"f";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8517;}}}}}}}}}}}}}}}}}}}s:1:"y";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"y";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8493;}}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:268;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:199;}s:9:"codepoint";i:199;}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:264;}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8752;}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:266;}}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:184;}}}}}}s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:183;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8493;}}}s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:935;}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"l";a:1:{s:1:"e";a:4:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8857;}}}}s:1:"M";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8854;}}}}}}s:1:"P";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8853;}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8855;}}}}}}}}}}}s:1:"l";a:1:{s:1:"o";a:2:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"w";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8754;}}}}}}}}}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"C";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8221;}}}}}}}}}}}}s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8217;}}}}}}}}}}}}}}}s:1:"o";a:4:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8759;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10868;}}}}}s:1:"n";a:3:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8801;}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8751;}}}}s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8750;}}}}}}}}}}}}}}s:1:"p";a:2:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8450;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:"u";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8720;}}}}}}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"C";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"w";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8755;}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10799;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119966;}}}}s:1:"u";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8915;}s:1:"C";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8781;}}}}}}}s:1:"D";a:11:{s:1:"D";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8517;}s:1:"o";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"h";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10513;}}}}}}}}s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1026;}}}}s:1:"S";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1029;}}}}s:1:"Z";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1039;}}}}s:1:"a";a:3:{s:1:"g";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8225;}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8609;}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10980;}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:270;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1044;}}}s:1:"e";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8711;}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:916;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120071;}}}s:1:"i";a:2:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:4:{s:1:"A";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:180;}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:729;}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"A";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:733;}}}}}}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:96;}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:732;}}}}}}}}}}}}}}s:1:"m";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8900;}}}}}}s:1:"f";a:1:{s:1:"f";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8518;}}}}}}}}}}}}}s:1:"o";a:4:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120123;}}}s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:168;}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8412;}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8784;}}}}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:6:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8751;}}}}}}}}}}}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:168;}}s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8659;}}}}}}}}}}s:1:"L";a:2:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8656;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10980;}}}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:2:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10232;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10234;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10233;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8872;}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8657;}}}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8661;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:6:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8595;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10515;}}}}s:1:"U";a:1:{s:1:"p";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8693;}}}}}}}}}}}}}s:1:"B";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:785;}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:3:{s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10576;}}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10590;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8637;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10582;}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10591;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8641;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10583;}}}}}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8868;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8615;}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8659;}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119967;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:272;}}}}}}}s:1:"E";a:16:{s:1:"N";a:1:{s:1:"G";a:1:{s:1:";";a:1:{s:9:"codepoint";i:330;}}}s:1:"T";a:1:{s:1:"H";a:2:{s:1:";";a:1:{s:9:"codepoint";i:208;}s:9:"codepoint";i:208;}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:201;}s:9:"codepoint";i:201;}}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:282;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:202;}s:9:"codepoint";i:202;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1069;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:278;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120072;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:200;}s:9:"codepoint";i:200;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8712;}}}}}}}s:1:"m";a:2:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:274;}}}}s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:2:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9723;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9643;}}}}}}}}}}}}}}}}}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:280;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120124;}}}}s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:917;}}}}}}}s:1:"q";a:1:{s:1:"u";a:2:{s:1:"a";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10869;}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8770;}}}}}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8652;}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8496;}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10867;}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:919;}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:203;}s:9:"codepoint";i:203;}}}s:1:"x";a:2:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8707;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8519;}}}}}}}}}}}}}s:1:"F";a:5:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1060;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120073;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"d";a:2:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9724;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}}}}}}}}}}}}}}}}}}s:1:"o";a:3:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120125;}}}s:1:"r";a:1:{s:1:"A";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8704;}}}}}s:1:"u";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8497;}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8497;}}}}}s:1:"G";a:12:{s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1027;}}}}s:1:"T";a:2:{s:1:";";a:1:{s:9:"codepoint";i:62;}s:9:"codepoint";i:62;}s:1:"a";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:915;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:988;}}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:286;}}}}}}s:1:"c";a:3:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:290;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:284;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1043;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:288;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120074;}}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8921;}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120126;}}}}s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:6:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8805;}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8923;}}}}}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8807;}}}}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10914;}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8823;}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10878;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8819;}}}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119970;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8811;}}}s:1:"H";a:8:{s:1:"A";a:1:{s:1:"R";a:1:{s:1:"D";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1066;}}}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:711;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:94;}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:292;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8460;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"b";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8459;}}}}}}}}}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8461;}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"z";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"L";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9472;}}}}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8459;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:294;}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"p";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"H";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8782;}}}}}}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8783;}}}}}}}}}}s:1:"I";a:14:{s:1:"E";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1045;}}}}s:1:"J";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:306;}}}}}s:1:"O";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1025;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:205;}s:9:"codepoint";i:205;}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:206;}s:9:"codepoint";i:206;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1048;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:304;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8465;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:204;}s:9:"codepoint";i:204;}}}}}s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8465;}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:298;}}}s:1:"g";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"I";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8520;}}}}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}}}}}s:1:"n";a:2:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8748;}s:1:"e";a:2:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8747;}}}}}s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8898;}}}}}}}}}}}s:1:"v";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8291;}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8290;}}}}}}}}}}}}}}s:1:"o";a:3:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:302;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120128;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:921;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8464;}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:296;}}}}}}s:1:"u";a:2:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1030;}}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:207;}s:9:"codepoint";i:207;}}}}s:1:"J";a:5:{s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:308;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1049;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120077;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120129;}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119973;}}}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1032;}}}}}}s:1:"u";a:1:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1028;}}}}}}s:1:"K";a:7:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1061;}}}}s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1036;}}}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:922;}}}}}s:1:"c";a:2:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:310;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1050;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120078;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120130;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119974;}}}}}s:1:"L";a:11:{s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1033;}}}}s:1:"T";a:2:{s:1:";";a:1:{s:9:"codepoint";i:60;}s:9:"codepoint";i:60;}s:1:"a";a:5:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:313;}}}}}s:1:"m";a:1:{s:1:"b";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:923;}}}}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10218;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8466;}}}}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8606;}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:317;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:315;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1051;}}}s:1:"e";a:2:{s:1:"f";a:1:{s:1:"t";a:10:{s:1:"A";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10216;}}}}}}}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8592;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8676;}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8646;}}}}}}}}}}}}}}}}s:1:"C";a:1:{s:1:"e";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8968;}}}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10214;}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:2:{s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10593;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8643;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10585;}}}}}}}}}}}}}}s:1:"F";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8970;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8596;}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10574;}}}}}}}}}}}}s:1:"T";a:2:{s:1:"e";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8867;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8612;}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10586;}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8882;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10703;}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8884;}}}}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:3:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10577;}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10592;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8639;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10584;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8636;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10578;}}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8656;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"s";a:6:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8922;}}}}}}}}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8806;}}}}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8822;}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10913;}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10877;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8818;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120079;}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8920;}s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8666;}}}}}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:319;}}}}}}s:1:"o";a:3:{s:1:"n";a:1:{s:1:"g";a:4:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10229;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10231;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10230;}}}}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10232;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10234;}}}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10233;}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120131;}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8601;}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8600;}}}}}}}}}}}}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8466;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8624;}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:321;}}}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8810;}}}s:1:"M";a:8:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10501;}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1052;}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8287;}}}}}}}}}}s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8499;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120080;}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"P";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8723;}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120132;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8499;}}}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:924;}}}s:1:"N";a:9:{s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1034;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:323;}}}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:327;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:325;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1053;}}}s:1:"e";a:3:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"v";a:1:{s:1:"e";a:3:{s:1:"M";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}}}s:1:"T";a:1:{s:1:"h";a:1:{s:1:"i";a:2:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"T";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"d";a:2:{s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8811;}}}}}}}}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8810;}}}}}}}}}}}}}s:1:"w";a:1:{s:1:"L";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120081;}}}s:1:"o";a:4:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8288;}}}}}}s:1:"n";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"k";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:160;}}}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8469;}}}s:1:"t";a:11:{s:1:";";a:1:{s:9:"codepoint";i:10988;}s:1:"C";a:2:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8802;}}}}}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"C";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8813;}}}}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}}}}}}}}}}}}}}}s:1:"E";a:3:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8713;}}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8800;}}}}}s:1:"x";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8708;}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8815;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8817;}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8825;}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8821;}}}}}}}}}}}}}s:1:"L";a:1:{s:1:"e";a:2:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"T";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8938;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8940;}}}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8814;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8816;}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8824;}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8820;}}}}}}}}}}s:1:"P";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8832;}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8928;}}}}}}}}}}}}}}}}}}}s:1:"R";a:2:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"E";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8716;}}}}}}}}}}}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"T";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8939;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8941;}}}}}}}}}}}}}}}}}}}s:1:"S";a:2:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"S";a:1:{s:1:"u";a:2:{s:1:"b";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8930;}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8931;}}}}}}}}}}}}}}}}}}}s:1:"u";a:3:{s:1:"b";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8840;}}}}}}}}}}s:1:"c";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8833;}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8929;}}}}}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8841;}}}}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8769;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8772;}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8775;}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8777;}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119977;}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:209;}s:9:"codepoint";i:209;}}}}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:925;}}}s:1:"O";a:14:{s:1:"E";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:338;}}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:211;}s:9:"codepoint";i:211;}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:212;}s:9:"codepoint";i:212;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1054;}}}s:1:"d";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:336;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120082;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:210;}s:9:"codepoint";i:210;}}}}}s:1:"m";a:3:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:332;}}}}s:1:"e";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:937;}}}}s:1:"i";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:927;}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120134;}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"C";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8220;}}}}}}}}}}}}s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8216;}}}}}}}}}}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10836;}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119978;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:216;}s:9:"codepoint";i:216;}}}}}s:1:"t";a:1:{s:1:"i";a:2:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:213;}s:9:"codepoint";i:213;}}}s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10807;}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:214;}s:9:"codepoint";i:214;}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"B";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:175;}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9182;}}s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9140;}}}}}}}}s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9180;}}}}}}}}}}}}}}}}s:1:"P";a:9:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8706;}}}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1055;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120083;}}}s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:934;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:928;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"M";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:177;}}}}}}}}}s:1:"o";a:2:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8460;}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8473;}}}}s:1:"r";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10939;}s:1:"e";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8826;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10927;}}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8828;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8830;}}}}}}}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8243;}}}}s:1:"o";a:2:{s:1:"d";a:1:{s:1:"u";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8719;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8759;}s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119979;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:936;}}}}s:1:"Q";a:4:{s:1:"U";a:1:{s:1:"O";a:1:{s:1:"T";a:2:{s:1:";";a:1:{s:9:"codepoint";i:34;}s:9:"codepoint";i:34;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120084;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8474;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119980;}}}}}s:1:"R";a:12:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10512;}}}}}s:1:"E";a:1:{s:1:"G";a:2:{s:1:";";a:1:{s:9:"codepoint";i:174;}s:9:"codepoint";i:174;}}s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:340;}}}}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10219;}}}s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8608;}s:1:"t";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10518;}}}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:344;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:342;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1056;}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8476;}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:2:{s:1:"E";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8715;}}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8651;}}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10607;}}}}}}}}}}}}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8476;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:929;}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:8:{s:1:"A";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10217;}}}}}}}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8594;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8677;}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8644;}}}}}}}}}}}}}}}s:1:"C";a:1:{s:1:"e";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8969;}}}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10215;}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:2:{s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10589;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8642;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10581;}}}}}}}}}}}}}}s:1:"F";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8971;}}}}}}s:1:"T";a:2:{s:1:"e";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8866;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8614;}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10587;}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8883;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10704;}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8885;}}}}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:3:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10575;}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10588;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8638;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10580;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8640;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10579;}}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}}}}}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8477;}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:"I";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10608;}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8667;}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8475;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8625;}}}s:1:"u";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"D";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"y";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10740;}}}}}}}}}}}}s:1:"S";a:13:{s:1:"H";a:2:{s:1:"C";a:1:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1065;}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1064;}}}}s:1:"O";a:1:{s:1:"F";a:1:{s:1:"T";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1068;}}}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:346;}}}}}}s:1:"c";a:5:{s:1:";";a:1:{s:9:"codepoint";i:10940;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:352;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:350;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:348;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1057;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120086;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:4:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8595;}}}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8592;}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8594;}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8593;}}}}}}}}}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:931;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"C";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8728;}}}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120138;}}}}s:1:"q";a:2:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8730;}}}s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:9633;}s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8851;}}}}}}}}}}}}}s:1:"S";a:1:{s:1:"u";a:2:{s:1:"b";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8847;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8849;}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8848;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8850;}}}}}}}}}}}}}}s:1:"U";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8852;}}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119982;}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8902;}}}}s:1:"u";a:4:{s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8912;}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8912;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8838;}}}}}}}}}}s:1:"c";a:2:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8827;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10928;}}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8829;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8831;}}}}}}}}}}}s:1:"h";a:1:{s:1:"T";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8715;}}}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8721;}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8913;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8835;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8839;}}}}}}}}}}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8913;}}}}}}}s:1:"T";a:11:{s:1:"H";a:1:{s:1:"O";a:1:{s:1:"R";a:1:{s:1:"N";a:2:{s:1:";";a:1:{s:9:"codepoint";i:222;}s:9:"codepoint";i:222;}}}}s:1:"R";a:1:{s:1:"A";a:1:{s:1:"D";a:1:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8482;}}}}}s:1:"S";a:2:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1035;}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1062;}}}}s:1:"a";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:932;}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:356;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:354;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1058;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120087;}}}s:1:"h";a:2:{s:1:"e";a:2:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8756;}}}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:920;}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8201;}}}}}}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8764;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8771;}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8773;}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8776;}}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120139;}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8411;}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119983;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:358;}}}}}}}s:1:"U";a:14:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:218;}s:9:"codepoint";i:218;}}}}s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8607;}s:1:"o";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10569;}}}}}}}}s:1:"b";a:1:{s:1:"r";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1038;}}}s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:364;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:219;}s:9:"codepoint";i:219;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1059;}}}s:1:"d";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:368;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120088;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:217;}s:9:"codepoint";i:217;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:362;}}}}}s:1:"n";a:2:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"B";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:818;}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9183;}}s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9141;}}}}}}}}s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9181;}}}}}}}}}}}}}}}s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8899;}s:1:"P";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8846;}}}}}}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:370;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120140;}}}}s:1:"p";a:8:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8593;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10514;}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8645;}}}}}}}}}}}}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8597;}}}}}}}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10606;}}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8869;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8613;}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8657;}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8661;}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8598;}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8599;}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:978;}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:933;}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:366;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119984;}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:360;}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:220;}s:9:"codepoint";i:220;}}}}s:1:"V";a:9:{s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8875;}}}}}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10987;}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1042;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8873;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10982;}}}}}}s:1:"e";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8897;}}s:1:"r";a:3:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8214;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8214;}s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:4:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8739;}}}}s:1:"L";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:124;}}}}}s:1:"S";a:1:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10072;}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8768;}}}}}}}}}}}s:1:"y";a:1:{s:1:"T";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8202;}}}}}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120089;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120141;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119985;}}}}s:1:"v";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8874;}}}}}}}s:1:"W";a:5:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:372;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8896;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120090;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120142;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119986;}}}}}s:1:"X";a:4:{s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120091;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:926;}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120143;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119987;}}}}}s:1:"Y";a:9:{s:1:"A";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1071;}}}}s:1:"I";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1031;}}}}s:1:"U";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1070;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:221;}s:9:"codepoint";i:221;}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:374;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1067;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120092;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120144;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119988;}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:376;}}}}}s:1:"Z";a:8:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1046;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:377;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:381;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1047;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:379;}}}}s:1:"e";a:2:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"W";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:918;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8488;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8484;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119989;}}}}}s:1:"a";a:16:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:225;}s:9:"codepoint";i:225;}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:259;}}}}}}s:1:"c";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8766;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8767;}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:226;}s:9:"codepoint";i:226;}}}s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:180;}s:9:"codepoint";i:180;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1072;}}}s:1:"e";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:230;}s:9:"codepoint";i:230;}}}}s:1:"f";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8289;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120094;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:224;}s:9:"codepoint";i:224;}}}}}s:1:"l";a:2:{s:1:"e";a:2:{s:1:"f";a:1:{s:1:"s";a:1:{s:1:"y";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8501;}}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8501;}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:945;}}}}}s:1:"m";a:2:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:257;}}}s:1:"l";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10815;}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:38;}s:9:"codepoint";i:38;}}s:1:"n";a:2:{s:1:"d";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8743;}s:1:"a";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10837;}}}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10844;}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10840;}}}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10842;}}}s:1:"g";a:7:{s:1:";";a:1:{s:9:"codepoint";i:8736;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10660;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8736;}}}s:1:"m";a:1:{s:1:"s";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8737;}s:1:"a";a:8:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10664;}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10665;}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10666;}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10667;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10668;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10669;}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10670;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10671;}}}}}}s:1:"r";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8735;}s:1:"v";a:1:{s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8894;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10653;}}}}}}s:1:"s";a:2:{s:1:"p";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8738;}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8491;}}}s:1:"z";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9084;}}}}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:261;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120146;}}}}s:1:"p";a:7:{s:1:";";a:1:{s:9:"codepoint";i:8776;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10864;}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10863;}}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8778;}}s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8779;}}}s:1:"o";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:39;}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8776;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8778;}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:229;}s:9:"codepoint";i:229;}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119990;}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:42;}}s:1:"y";a:1:{s:1:"m";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8776;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8781;}}}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:227;}s:9:"codepoint";i:227;}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:228;}s:9:"codepoint";i:228;}}}s:1:"w";a:2:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8755;}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10769;}}}}}}s:1:"b";a:16:{s:1:"N";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10989;}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"k";a:4:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8780;}}}}}s:1:"e";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1014;}}}}}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8245;}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8765;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8909;}}}}}}}}s:1:"r";a:2:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8893;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8965;}s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8965;}}}}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9141;}s:1:"t";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9142;}}}}}}}}s:1:"c";a:2:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8780;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1073;}}}s:1:"d";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8222;}}}}}s:1:"e";a:5:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"u";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8757;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8757;}}}}}}s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10672;}}}}}}s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1014;}}}}s:1:"r";a:1:{s:1:"n";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8492;}}}}}s:1:"t";a:3:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:946;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8502;}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8812;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120095;}}}s:1:"i";a:1:{s:1:"g";a:7:{s:1:"c";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8898;}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9711;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8899;}}}}s:1:"o";a:3:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10752;}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10753;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10754;}}}}}}}s:1:"s";a:2:{s:1:"q";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10758;}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9733;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9661;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9651;}}}}}}}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10756;}}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8897;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8896;}}}}}}}}s:1:"k";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10509;}}}}}}s:1:"l";a:3:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"k";a:3:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"z";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10731;}}}}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:9652;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9662;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9666;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9656;}}}}}}}}}}}}}}}}s:1:"n";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9251;}}}}s:1:"k";a:2:{i:1;a:2:{i:2;a:1:{s:1:";";a:1:{s:9:"codepoint";i:9618;}}i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:9617;}}}i:3;a:1:{i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:9619;}}}}s:1:"o";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9608;}}}}}s:1:"n";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8976;}}}}s:1:"o";a:4:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120147;}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8869;}s:1:"t";a:1:{s:1:"o";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8869;}}}}}s:1:"w";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8904;}}}}}s:1:"x";a:12:{s:1:"D";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9559;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9556;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9558;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9555;}}}s:1:"H";a:5:{s:1:";";a:1:{s:9:"codepoint";i:9552;}s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9574;}}s:1:"U";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9577;}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9572;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9575;}}}s:1:"U";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9565;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9562;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9564;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9561;}}}s:1:"V";a:7:{s:1:";";a:1:{s:9:"codepoint";i:9553;}s:1:"H";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9580;}}s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9571;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9568;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9579;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9570;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9567;}}}s:1:"b";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10697;}}}}s:1:"d";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9557;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9554;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9488;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9484;}}}s:1:"h";a:5:{s:1:";";a:1:{s:9:"codepoint";i:9472;}s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9573;}}s:1:"U";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9576;}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9516;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9524;}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8863;}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8862;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8864;}}}}}}s:1:"u";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9563;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9560;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9496;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9492;}}}s:1:"v";a:7:{s:1:";";a:1:{s:9:"codepoint";i:9474;}s:1:"H";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9578;}}s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9569;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9566;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9532;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9508;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9500;}}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8245;}}}}}}s:1:"r";a:2:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:728;}}}}s:1:"v";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:166;}s:9:"codepoint";i:166;}}}}}s:1:"s";a:4:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119991;}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8271;}}}}s:1:"i";a:1:{s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8765;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8909;}}}}s:1:"o";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:92;}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10693;}}}}}s:1:"u";a:2:{s:1:"l";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8226;}s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8226;}}}}}s:1:"m";a:1:{s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8782;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10926;}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8783;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8783;}}}}}}}s:1:"c";a:15:{s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:263;}}}}}s:1:"p";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8745;}s:1:"a";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10820;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10825;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10827;}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10823;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10816;}}}}}s:1:"r";a:2:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8257;}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:711;}}}}}s:1:"c";a:4:{s:1:"a";a:2:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10829;}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:269;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:231;}s:9:"codepoint";i:231;}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:265;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10828;}s:1:"s";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10832;}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:267;}}}}s:1:"e";a:3:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:184;}s:9:"codepoint";i:184;}}}s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10674;}}}}}}s:1:"n";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:162;}s:9:"codepoint";i:162;s:1:"e";a:1:{s:1:"r";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:183;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120096;}}}s:1:"h";a:3:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1095;}}}s:1:"e";a:1:{s:1:"c";a:1:{s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10003;}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10003;}}}}}}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:967;}}}s:1:"i";a:1:{s:1:"r";a:7:{s:1:";";a:1:{s:9:"codepoint";i:9675;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10691;}}s:1:"c";a:3:{s:1:";";a:1:{s:9:"codepoint";i:710;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8791;}}}s:1:"l";a:1:{s:1:"e";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8634;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8635;}}}}}}}}}}}s:1:"d";a:5:{s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:174;}}s:1:"S";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9416;}}s:1:"a";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8859;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8858;}}}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8861;}}}}}}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8791;}}s:1:"f";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10768;}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10991;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10690;}}}}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9827;}s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9827;}}}}}}}}s:1:"o";a:4:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:58;}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8788;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8788;}}}}}}s:1:"m";a:2:{s:1:"m";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:44;}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64;}}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8705;}s:1:"f";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8728;}}}s:1:"l";a:1:{s:1:"e";a:2:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8705;}}}}}s:1:"x";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8450;}}}}}}}}s:1:"n";a:2:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8773;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10861;}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8750;}}}}}s:1:"p";a:3:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120148;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8720;}}}}s:1:"y";a:3:{s:1:";";a:1:{s:9:"codepoint";i:169;}s:9:"codepoint";i:169;s:1:"s";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8471;}}}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8629;}}}}s:1:"o";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10007;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119992;}}}s:1:"u";a:2:{s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10959;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10961;}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10960;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10962;}}}}}s:1:"t";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8943;}}}}}s:1:"u";a:7:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:2:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10552;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10549;}}}}}}s:1:"e";a:2:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8926;}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8927;}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8630;}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10557;}}}}}}s:1:"p";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8746;}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10824;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10822;}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10826;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8845;}}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10821;}}}}s:1:"r";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8631;}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10556;}}}}}s:1:"l";a:1:{s:1:"y";a:3:{s:1:"e";a:1:{s:1:"q";a:2:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8926;}}}}}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8927;}}}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8910;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8911;}}}}}}}}s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:164;}s:9:"codepoint";i:164;}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8630;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8631;}}}}}}}}}}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8910;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8911;}}}}}s:1:"w";a:2:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8754;}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8753;}}}}}s:1:"y";a:1:{s:1:"l";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9005;}}}}}}}s:1:"d";a:19:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8659;}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10597;}}}}s:1:"a";a:4:{s:1:"g";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8224;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8504;}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8595;}}}s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8208;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8867;}}}}}s:1:"b";a:2:{s:1:"k";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10511;}}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:733;}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:271;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1076;}}}s:1:"d";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8518;}s:1:"a";a:2:{s:1:"g";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8225;}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8650;}}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10871;}}}}}}}s:1:"e";a:3:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:176;}s:9:"codepoint";i:176;}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:948;}}}}s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10673;}}}}}}}s:1:"f";a:2:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10623;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120097;}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8643;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8642;}}}}}s:1:"i";a:5:{s:1:"a";a:1:{s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8900;}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8900;}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9830;}}}}}}}}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9830;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:168;}}s:1:"g";a:1:{s:1:"a";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:989;}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8946;}}}}s:1:"v";a:3:{s:1:";";a:1:{s:9:"codepoint";i:247;}s:1:"i";a:1:{s:1:"d";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:247;}s:9:"codepoint";i:247;s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8903;}}}}}}}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8903;}}}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1106;}}}}s:1:"l";a:1:{s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8990;}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8973;}}}}}}s:1:"o";a:5:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:36;}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120149;}}}s:1:"t";a:5:{s:1:";";a:1:{s:9:"codepoint";i:729;}s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8784;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8785;}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8760;}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8724;}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8865;}}}}}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8966;}}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8595;}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8650;}}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8643;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8642;}}}}}}}}}}}}}}}}s:1:"r";a:2:{s:1:"b";a:1:{s:1:"k";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10512;}}}}}}}s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8991;}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8972;}}}}}}s:1:"s";a:3:{s:1:"c";a:2:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119993;}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1109;}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10742;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:273;}}}}}}s:1:"t";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8945;}}}}s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9663;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9662;}}}}}s:1:"u";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8693;}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10607;}}}}}s:1:"w";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10662;}}}}}}}s:1:"z";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1119;}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10239;}}}}}}}}}s:1:"e";a:18:{s:1:"D";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10871;}}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8785;}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:233;}s:9:"codepoint";i:233;}}}}s:1:"s";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10862;}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:283;}}}}}s:1:"i";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8790;}s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:234;}s:9:"codepoint";i:234;}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8789;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1101;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:279;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8519;}}s:1:"f";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8786;}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120098;}}}s:1:"g";a:3:{s:1:";";a:1:{s:9:"codepoint";i:10906;}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:232;}s:9:"codepoint";i:232;}}}}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10902;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10904;}}}}}}s:1:"l";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10905;}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9191;}}}}}}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8467;}}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10901;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10903;}}}}}}s:1:"m";a:3:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:275;}}}}s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8709;}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8709;}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8709;}}}}}s:1:"s";a:1:{s:1:"p";a:2:{i:1;a:2:{i:3;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8196;}}i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8197;}}}s:1:";";a:1:{s:9:"codepoint";i:8195;}}}}s:1:"n";a:2:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:331;}}s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8194;}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:281;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120150;}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8917;}s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10723;}}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10865;}}}}s:1:"s";a:1:{s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:1013;}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:949;}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:949;}}}}}s:1:"q";a:4:{s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8790;}}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8789;}}}}}}s:1:"s";a:2:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8770;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:2:{s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10902;}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10901;}}}}}}}}}}s:1:"u";a:3:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:61;}}}}s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8799;}}}}s:1:"i";a:1:{s:1:"v";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8801;}s:1:"D";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10872;}}}}}}s:1:"v";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10725;}}}}}}}}s:1:"r";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8787;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10609;}}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8495;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8784;}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8770;}}}}s:1:"t";a:2:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:951;}}s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:240;}s:9:"codepoint";i:240;}}s:1:"u";a:2:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:235;}s:9:"codepoint";i:235;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8364;}}}}s:1:"x";a:3:{s:1:"c";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:33;}}}s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8707;}}}}s:1:"p";a:2:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8496;}}}}}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8519;}}}}}}}}}}}}}s:1:"f";a:11:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8786;}}}}}}}}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1092;}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9792;}}}}}}s:1:"f";a:3:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64259;}}}}}s:1:"l";a:2:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64256;}}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64260;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120099;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64257;}}}}}s:1:"l";a:3:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9837;}}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64258;}}}}s:1:"t";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9649;}}}}}s:1:"n";a:1:{s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:402;}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120151;}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8704;}}}}s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8916;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10969;}}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10765;}}}}}}}}s:1:"r";a:2:{s:1:"a";a:2:{s:1:"c";a:6:{i:1;a:6:{i:2;a:2:{s:1:";";a:1:{s:9:"codepoint";i:189;}s:9:"codepoint";i:189;}i:3;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8531;}}i:4;a:2:{s:1:";";a:1:{s:9:"codepoint";i:188;}s:9:"codepoint";i:188;}i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8533;}}i:6;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8537;}}i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8539;}}}i:2;a:2:{i:3;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8532;}}i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8534;}}}i:3;a:3:{i:4;a:2:{s:1:";";a:1:{s:9:"codepoint";i:190;}s:9:"codepoint";i:190;}i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8535;}}i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8540;}}}i:4;a:1:{i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8536;}}}i:5;a:2:{i:6;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8538;}}i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8541;}}}i:7;a:1:{i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8542;}}}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8260;}}}}s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8994;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119995;}}}}}s:1:"g";a:16:{s:1:"E";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8807;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10892;}}}s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:501;}}}}}s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:947;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:989;}}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10886;}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:287;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:285;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1075;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:289;}}}}s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8805;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8923;}}s:1:"q";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8805;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8807;}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10878;}}}}}}}s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10878;}s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10921;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10880;}s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10882;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10884;}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10900;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120100;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8811;}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8921;}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8503;}}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1107;}}}}s:1:"l";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8823;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10898;}}s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10917;}}s:1:"j";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10916;}}}s:1:"n";a:4:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8809;}}s:1:"a";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10890;}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10890;}}}}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10888;}s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10888;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8809;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8935;}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120152;}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:96;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8458;}}}s:1:"i";a:1:{s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8819;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10894;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10896;}}}}}s:1:"t";a:7:{s:1:";";a:1:{s:9:"codepoint";i:62;}s:9:"codepoint";i:62;s:1:"c";a:2:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10919;}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10874;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8919;}}}}s:1:"l";a:1:{s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10645;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10876;}}}}}}s:1:"r";a:5:{s:1:"a";a:2:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10886;}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10616;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8919;}}}}s:1:"e";a:1:{s:1:"q";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8923;}}}}}s:1:"q";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10892;}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8823;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8819;}}}}}}}s:1:"h";a:10:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}}}s:1:"a";a:4:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8202;}}}}}s:1:"l";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:189;}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8459;}}}}}s:1:"r";a:2:{s:1:"d";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1098;}}}}s:1:"r";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8596;}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10568;}}}}s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8621;}}}}}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8463;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:293;}}}}}s:1:"e";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9829;}s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9829;}}}}}}}}s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8230;}}}}}s:1:"r";a:1:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8889;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120101;}}}s:1:"k";a:1:{s:1:"s";a:2:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10533;}}}}}}s:1:"w";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10534;}}}}}}}}s:1:"o";a:5:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8703;}}}}s:1:"m";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8763;}}}}}s:1:"o";a:1:{s:1:"k";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8617;}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8618;}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120153;}}}s:1:"r";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8213;}}}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119997;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8463;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:295;}}}}}}s:1:"y";a:2:{s:1:"b";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8259;}}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8208;}}}}}}}s:1:"i";a:15:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:237;}s:9:"codepoint";i:237;}}}}}s:1:"c";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8291;}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:238;}s:9:"codepoint";i:238;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1080;}}}s:1:"e";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1077;}}}s:1:"x";a:1:{s:1:"c";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:161;}s:9:"codepoint";i:161;}}}}s:1:"f";a:2:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120102;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:236;}s:9:"codepoint";i:236;}}}}}s:1:"i";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8520;}s:1:"i";a:2:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10764;}}}}s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8749;}}}}s:1:"n";a:1:{s:1:"f";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10716;}}}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8489;}}}}}s:1:"j";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:307;}}}}}s:1:"m";a:3:{s:1:"a";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:299;}}}s:1:"g";a:3:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8465;}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8464;}}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8465;}}}}}}s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:305;}}}}s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8887;}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:437;}}}}}s:1:"n";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8712;}s:1:"c";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8453;}}}}}s:1:"f";a:1:{s:1:"i";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8734;}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10717;}}}}}}}s:1:"o";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:305;}}}}}s:1:"t";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8747;}s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8890;}}}}s:1:"e";a:2:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8484;}}}}}s:1:"r";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8890;}}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10775;}}}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10812;}}}}}}}s:1:"o";a:4:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1105;}}}s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:303;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120154;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:953;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10812;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:191;}s:9:"codepoint";i:191;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119998;}}}s:1:"i";a:1:{s:1:"n";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8712;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8953;}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8949;}}}}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8948;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8947;}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8712;}}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8290;}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:297;}}}}}}s:1:"u";a:2:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1110;}}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:239;}s:9:"codepoint";i:239;}}}}s:1:"j";a:6:{s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:309;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1081;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120103;}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:567;}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120155;}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119999;}}}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1112;}}}}}}s:1:"u";a:1:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1108;}}}}}}s:1:"k";a:8:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:954;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1008;}}}}}}s:1:"c";a:2:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:311;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1082;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120104;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:312;}}}}}}s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1093;}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1116;}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120156;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120000;}}}}}s:1:"l";a:22:{s:1:"A";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8666;}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8656;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10523;}}}}}}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10510;}}}}}s:1:"E";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8806;}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10891;}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10594;}}}}s:1:"a";a:9:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:314;}}}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10676;}}}}}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8466;}}}}}s:1:"m";a:1:{s:1:"b";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:955;}}}}}s:1:"n";a:1:{s:1:"g";a:3:{s:1:";";a:1:{s:9:"codepoint";i:10216;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10641;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10216;}}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10885;}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:171;}s:9:"codepoint";i:171;}}}s:1:"r";a:1:{s:1:"r";a:8:{s:1:";";a:1:{s:9:"codepoint";i:8592;}s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8676;}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10527;}}}}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10525;}}}s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8617;}}}s:1:"l";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8619;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10553;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10611;}}}}s:1:"t";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8610;}}}}}s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:10923;}s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10521;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10925;}}}}s:1:"b";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10508;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10098;}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:123;}}s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:91;}}}}s:1:"k";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10635;}}s:1:"s";a:1:{s:1:"l";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10639;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10637;}}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:318;}}}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:316;}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8968;}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:123;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1083;}}}s:1:"d";a:4:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10550;}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8220;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8222;}}}}}s:1:"r";a:2:{s:1:"d";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10599;}}}}}s:1:"u";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10571;}}}}}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8626;}}}}s:1:"e";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8804;}s:1:"f";a:1:{s:1:"t";a:5:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8592;}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8610;}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8637;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8636;}}}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8647;}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8596;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8646;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8651;}}}}}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8621;}}}}}}}}}}}}}}}}s:1:"t";a:1:{s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8907;}}}}}}}}}}}}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8922;}}s:1:"q";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8804;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8806;}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10877;}}}}}}}s:1:"s";a:5:{s:1:";";a:1:{s:9:"codepoint";i:10877;}s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10920;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10879;}s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10881;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10883;}}}}}}s:1:"g";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10899;}}}}s:1:"s";a:5:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10885;}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8918;}}}}s:1:"e";a:1:{s:1:"q";a:2:{s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8922;}}}}s:1:"q";a:1:{s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10891;}}}}}}}s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8822;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8818;}}}}}}}s:1:"f";a:3:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10620;}}}}}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8970;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120105;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8822;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10897;}}}s:1:"h";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8637;}}s:1:"u";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8636;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10602;}}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9604;}}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1113;}}}}s:1:"l";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8810;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8647;}}}}s:1:"c";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8990;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10603;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9722;}}}}}s:1:"m";a:2:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:320;}}}}}s:1:"o";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9136;}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9136;}}}}}}}}}}s:1:"n";a:4:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8808;}}s:1:"a";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10889;}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10889;}}}}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10887;}s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10887;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8808;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8934;}}}}}s:1:"o";a:8:{s:1:"a";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10220;}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8701;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10214;}}}}s:1:"n";a:1:{s:1:"g";a:3:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10229;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10231;}}}}}}}}}}}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10236;}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10230;}}}}}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8619;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8620;}}}}}}}}}}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10629;}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120157;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10797;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10804;}}}}}}s:1:"w";a:2:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8727;}}}}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:95;}}}}}s:1:"z";a:3:{s:1:";";a:1:{s:9:"codepoint";i:9674;}s:1:"e";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9674;}}}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10731;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:40;}s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10643;}}}}}}s:1:"r";a:5:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8646;}}}}s:1:"c";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8991;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8651;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10605;}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8206;}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8895;}}}}}s:1:"s";a:6:{s:1:"a";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8249;}}}}}s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120001;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8624;}}s:1:"i";a:1:{s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8818;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10893;}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10895;}}}}s:1:"q";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:91;}}s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8216;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8218;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:322;}}}}}}s:1:"t";a:9:{s:1:";";a:1:{s:9:"codepoint";i:60;}s:9:"codepoint";i:60;s:1:"c";a:2:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10918;}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10873;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8918;}}}}s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8907;}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8905;}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10614;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10875;}}}}}}s:1:"r";a:2:{s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10646;}}}}s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:9667;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8884;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9666;}}}}}s:1:"u";a:1:{s:1:"r";a:2:{s:1:"d";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10570;}}}}}}s:1:"u";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10598;}}}}}}}}s:1:"m";a:14:{s:1:"D";a:1:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8762;}}}}}s:1:"a";a:4:{s:1:"c";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:175;}s:9:"codepoint";i:175;}}s:1:"l";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9794;}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10016;}s:1:"e";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10016;}}}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8614;}s:1:"s";a:1:{s:1:"t";a:1:{s:1:"o";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8614;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8615;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8612;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8613;}}}}}}}s:1:"r";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9646;}}}}}}s:1:"c";a:2:{s:1:"o";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10793;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1084;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8212;}}}}}s:1:"e";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8737;}}}}}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120106;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8487;}}}s:1:"i";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:181;}s:9:"codepoint";i:181;}}}s:1:"d";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8739;}s:1:"a";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:42;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10992;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:183;}s:9:"codepoint";i:183;}}}}s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8722;}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8863;}}s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8760;}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10794;}}}}}}}s:1:"l";a:2:{s:1:"c";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10971;}}}s:1:"d";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8230;}}}}s:1:"n";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8723;}}}}}}s:1:"o";a:2:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8871;}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120158;}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8723;}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120002;}}}s:1:"t";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8766;}}}}}}s:1:"u";a:3:{s:1:";";a:1:{s:9:"codepoint";i:956;}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8888;}}}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8888;}}}}}}s:1:"n";a:23:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8653;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8654;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8655;}}}}}}}}}}}s:1:"V";a:2:{s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8879;}}}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8878;}}}}}}s:1:"a";a:4:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8711;}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:324;}}}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8777;}s:1:"o";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:329;}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8777;}}}}}}s:1:"t";a:1:{s:1:"u";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9838;}s:1:"a";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9838;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8469;}}}}}}}}s:1:"b";a:1:{s:1:"s";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:160;}s:9:"codepoint";i:160;}}}s:1:"c";a:5:{s:1:"a";a:2:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10819;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:328;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:326;}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8775;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10818;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1085;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8211;}}}}}s:1:"e";a:6:{s:1:";";a:1:{s:9:"codepoint";i:8800;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8663;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10532;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8599;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8599;}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8802;}}}}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10536;}}}}}s:1:"x";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8708;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8708;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120107;}}}s:1:"g";a:3:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8817;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8817;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8821;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8815;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8815;}}}}s:1:"h";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8654;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8622;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10994;}}}}}s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8715;}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8956;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8954;}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8715;}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1114;}}}}s:1:"l";a:6:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8653;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8602;}}}}s:1:"d";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8229;}}}s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8816;}s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8602;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8622;}}}}}}}}}}}}}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8816;}}s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8814;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8820;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8814;}s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8938;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8940;}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120159;}}}s:1:"t";a:4:{s:1:";";a:1:{s:9:"codepoint";i:172;}s:9:"codepoint";i:172;s:1:"i";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8713;}s:1:"v";a:3:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8713;}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8951;}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8950;}}}}}s:1:"n";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8716;}s:1:"v";a:3:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8716;}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8958;}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8957;}}}}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8742;}s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}}}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10772;}}}}}}s:1:"r";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8832;}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8928;}}}}s:1:"e";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8832;}}}}}s:1:"r";a:4:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8655;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8603;}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8603;}}}}}}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8939;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8941;}}}}}}s:1:"s";a:7:{s:1:"c";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8833;}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8929;}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120003;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:2:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}}}}}}}}}}s:1:"i";a:1:{s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8769;}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8772;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8772;}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}s:1:"q";a:1:{s:1:"s";a:1:{s:1:"u";a:2:{s:1:"b";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8930;}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8931;}}}}}}s:1:"u";a:3:{s:1:"b";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8836;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8840;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8840;}}}}}}}s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8833;}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8837;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8841;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8841;}}}}}}}}}s:1:"t";a:4:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8825;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:241;}s:9:"codepoint";i:241;}}}}s:1:"l";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8824;}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8938;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8940;}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8939;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8941;}}}}}}}}}}}}}}}}s:1:"u";a:2:{s:1:";";a:1:{s:9:"codepoint";i:957;}s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:35;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8470;}}}}s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8199;}}}}}s:1:"v";a:6:{s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8877;}}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10500;}}}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8876;}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"f";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10718;}}}}}}s:1:"l";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10498;}}}}}s:1:"r";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10499;}}}}}}s:1:"w";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8662;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10531;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8598;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8598;}}}}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10535;}}}}}}}s:1:"o";a:18:{s:1:"S";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9416;}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:243;}s:9:"codepoint";i:243;}}}}s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8859;}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8858;}s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:244;}s:9:"codepoint";i:244;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1086;}}}s:1:"d";a:5:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8861;}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:337;}}}}}s:1:"i";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10808;}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8857;}}}s:1:"s";a:1:{s:1:"o";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10684;}}}}}}s:1:"e";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:339;}}}}}s:1:"f";a:2:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10687;}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120108;}}}s:1:"g";a:3:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:731;}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:242;}s:9:"codepoint";i:242;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10689;}}}s:1:"h";a:2:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10677;}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8486;}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8750;}}}}s:1:"l";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8634;}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10686;}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10683;}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8254;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10688;}}}s:1:"m";a:3:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:333;}}}}s:1:"e";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:969;}}}}s:1:"i";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:959;}}}}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10678;}}s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8854;}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120160;}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10679;}}}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10681;}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8853;}}}}}s:1:"r";a:7:{s:1:";";a:1:{s:9:"codepoint";i:8744;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8635;}}}}s:1:"d";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10845;}s:1:"e";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8500;}s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8500;}}}}}s:1:"f";a:2:{s:1:";";a:1:{s:9:"codepoint";i:170;}s:9:"codepoint";i:170;}s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:186;}s:9:"codepoint";i:186;}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8886;}}}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10838;}}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10839;}}}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10843;}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8500;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:248;}s:9:"codepoint";i:248;}}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8856;}}}}s:1:"t";a:1:{s:1:"i";a:2:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:245;}s:9:"codepoint";i:245;}}}s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8855;}s:1:"a";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10806;}}}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:246;}s:9:"codepoint";i:246;}}}s:1:"v";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9021;}}}}}}s:1:"p";a:12:{s:1:"a";a:1:{s:1:"r";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8741;}s:1:"a";a:3:{s:1:";";a:1:{s:9:"codepoint";i:182;}s:9:"codepoint";i:182;s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}}}s:1:"s";a:2:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10995;}}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:11005;}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8706;}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1087;}}}s:1:"e";a:1:{s:1:"r";a:5:{s:1:"c";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:37;}}}}s:1:"i";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:46;}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8240;}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8869;}}s:1:"t";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8241;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120109;}}}s:1:"h";a:3:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:966;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:966;}}}s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8499;}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9742;}}}}}s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:960;}s:1:"t";a:1:{s:1:"c";a:1:{s:1:"h";a:1:{s:1:"f";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8916;}}}}}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:982;}}}s:1:"l";a:2:{s:1:"a";a:1:{s:1:"n";a:2:{s:1:"c";a:1:{s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8463;}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8462;}}}}s:1:"k";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8463;}}}}}s:1:"u";a:1:{s:1:"s";a:9:{s:1:";";a:1:{s:9:"codepoint";i:43;}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10787;}}}}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8862;}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10786;}}}}s:1:"d";a:2:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8724;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10789;}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10866;}}s:1:"m";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:177;}s:9:"codepoint";i:177;}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10790;}}}}s:1:"t";a:1:{s:1:"w";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10791;}}}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:177;}}s:1:"o";a:3:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10773;}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120161;}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:163;}s:9:"codepoint";i:163;}}}}s:1:"r";a:10:{s:1:";";a:1:{s:9:"codepoint";i:8826;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10931;}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10935;}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8828;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10927;}s:1:"c";a:6:{s:1:";";a:1:{s:9:"codepoint";i:8826;}s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10935;}}}}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8828;}}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10927;}}}s:1:"n";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10937;}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10933;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8936;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8830;}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8242;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8473;}}}}}s:1:"n";a:3:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10933;}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10937;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8936;}}}}}s:1:"o";a:3:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8719;}}s:1:"f";a:3:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9006;}}}}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8978;}}}}}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8979;}}}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8733;}s:1:"t";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8830;}}}}s:1:"u";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8880;}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120005;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:968;}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"c";a:1:{s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8200;}}}}}}}s:1:"q";a:6:{s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120110;}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10764;}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120162;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8279;}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120006;}}}}s:1:"u";a:3:{s:1:"a";a:1:{s:1:"t";a:2:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8461;}}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10774;}}}}}}s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:63;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8799;}}}}}}s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:34;}s:9:"codepoint";i:34;}}}}s:1:"r";a:21:{s:1:"A";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8667;}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10524;}}}}}}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10511;}}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10596;}}}}s:1:"a";a:7:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10714;}}s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:341;}}}}}s:1:"d";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8730;}}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10675;}}}}}}}s:1:"n";a:1:{s:1:"g";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10217;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10642;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10661;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10217;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:187;}s:9:"codepoint";i:187;}}}s:1:"r";a:1:{s:1:"r";a:11:{s:1:";";a:1:{s:9:"codepoint";i:8594;}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10613;}}}s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8677;}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10528;}}}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10547;}}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10526;}}}s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8618;}}}s:1:"l";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8620;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10565;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10612;}}}}s:1:"t";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8611;}}}s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8605;}}}}s:1:"t";a:2:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10522;}}}}s:1:"i";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8758;}s:1:"n";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8474;}}}}}}}}}s:1:"b";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10509;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10099;}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:125;}}s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:93;}}}}s:1:"k";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10636;}}s:1:"s";a:1:{s:1:"l";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10638;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10640;}}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:345;}}}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:343;}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8969;}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:125;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1088;}}}s:1:"d";a:4:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10551;}}}s:1:"l";a:1:{s:1:"d";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10601;}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8221;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8221;}}}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8627;}}}}s:1:"e";a:3:{s:1:"a";a:1:{s:1:"l";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8476;}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8475;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8476;}}}}}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8477;}}}}s:1:"c";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9645;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:174;}s:9:"codepoint";i:174;}}s:1:"f";a:3:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10621;}}}}}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8971;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120111;}}}s:1:"h";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8641;}}s:1:"u";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8640;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10604;}}}}}s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:961;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1009;}}}}s:1:"i";a:3:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:6:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8594;}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8611;}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8641;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8640;}}}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8644;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8652;}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8649;}}}}}}}}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8605;}}}}}}}}}}}s:1:"t";a:1:{s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8908;}}}}}}}}}}}}}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:730;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8787;}}}}}}}}}}}}s:1:"l";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8644;}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8652;}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8207;}}}s:1:"m";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9137;}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9137;}}}}}}}}}}s:1:"n";a:1:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10990;}}}}}s:1:"o";a:4:{s:1:"a";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10221;}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8702;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10215;}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10630;}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120163;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10798;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10805;}}}}}}}s:1:"p";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:41;}s:1:"g";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10644;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10770;}}}}}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8649;}}}}}s:1:"s";a:4:{s:1:"a";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8250;}}}}}s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120007;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8625;}}s:1:"q";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:93;}}s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8217;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8217;}}}}}}s:1:"t";a:3:{s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8908;}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8906;}}}}}s:1:"r";a:1:{s:1:"i";a:4:{s:1:";";a:1:{s:9:"codepoint";i:9657;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8885;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9656;}}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10702;}}}}}}}}s:1:"u";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10600;}}}}}}}s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8478;}}}s:1:"s";a:19:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:347;}}}}}}s:1:"b";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8218;}}}}}s:1:"c";a:10:{s:1:";";a:1:{s:9:"codepoint";i:8827;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10932;}}s:1:"a";a:2:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10936;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:353;}}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8829;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10928;}s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:351;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:349;}}}}s:1:"n";a:3:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10934;}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10938;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8937;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10771;}}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8831;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1089;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8901;}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8865;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10854;}}}}}s:1:"e";a:7:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8664;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10533;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8600;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8600;}}}}}}s:1:"c";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:167;}s:9:"codepoint";i:167;}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:59;}}}s:1:"s";a:1:{s:1:"w";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10537;}}}}}s:1:"t";a:1:{s:1:"m";a:2:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}s:1:"x";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10038;}}}}s:1:"f";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:120112;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8994;}}}}}}s:1:"h";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9839;}}}}s:1:"c";a:2:{s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1097;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1096;}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:2:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8739;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}}}}}}}}}s:1:"y";a:2:{s:1:";";a:1:{s:9:"codepoint";i:173;}s:9:"codepoint";i:173;}}s:1:"i";a:2:{s:1:"g";a:1:{s:1:"m";a:1:{s:1:"a";a:3:{s:1:";";a:1:{s:9:"codepoint";i:963;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:962;}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:962;}}}}}s:1:"m";a:8:{s:1:";";a:1:{s:9:"codepoint";i:8764;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10858;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8771;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8771;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10910;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10912;}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10909;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10911;}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8774;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10788;}}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10610;}}}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8592;}}}}}s:1:"m";a:4:{s:1:"a";a:2:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}}}}}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10803;}}}}}s:1:"e";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10724;}}}}}}}s:1:"i";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8739;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8995;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10922;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10924;}}}}s:1:"o";a:3:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1100;}}}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:47;}s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10692;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9023;}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120164;}}}}s:1:"p";a:1:{s:1:"a";a:2:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9824;}s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9824;}}}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}s:1:"q";a:3:{s:1:"c";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8851;}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8852;}}}}s:1:"s";a:1:{s:1:"u";a:2:{s:1:"b";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8847;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8849;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8847;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8849;}}}}}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8848;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8850;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8848;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8850;}}}}}}}}}s:1:"u";a:3:{s:1:";";a:1:{s:9:"codepoint";i:9633;}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9633;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8594;}}}}}s:1:"s";a:4:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120008;}}}s:1:"e";a:1:{s:1:"t";a:1:{s:1:"m";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8995;}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8902;}}}}}}s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9734;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9733;}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1013;}}}}}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:981;}}}}}}}}}s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:175;}}}}}s:1:"u";a:5:{s:1:"b";a:9:{s:1:";";a:1:{s:9:"codepoint";i:8834;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10949;}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10941;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8838;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10947;}}}}}s:1:"m";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10945;}}}}}s:1:"n";a:2:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10955;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8842;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10943;}}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10617;}}}}}s:1:"s";a:3:{s:1:"e";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8834;}s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8838;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10949;}}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8842;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10955;}}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10951;}}}s:1:"u";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10965;}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10963;}}}}}s:1:"c";a:1:{s:1:"c";a:6:{s:1:";";a:1:{s:9:"codepoint";i:8827;}s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10936;}}}}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8829;}}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10928;}}}s:1:"n";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10938;}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10934;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8937;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8831;}}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8721;}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9834;}}}s:1:"p";a:13:{i:1;a:2:{s:1:";";a:1:{s:9:"codepoint";i:185;}s:9:"codepoint";i:185;}i:2;a:2:{s:1:";";a:1:{s:9:"codepoint";i:178;}s:9:"codepoint";i:178;}i:3;a:2:{s:1:";";a:1:{s:9:"codepoint";i:179;}s:9:"codepoint";i:179;}s:1:";";a:1:{s:9:"codepoint";i:8835;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10950;}}s:1:"d";a:2:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10942;}}}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10968;}}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8839;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10948;}}}}}s:1:"h";a:1:{s:1:"s";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10967;}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10619;}}}}}s:1:"m";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10946;}}}}}s:1:"n";a:2:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10956;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8843;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10944;}}}}}s:1:"s";a:3:{s:1:"e";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8835;}s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8839;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10950;}}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8843;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10956;}}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10952;}}}s:1:"u";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10964;}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10966;}}}}}}s:1:"w";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8665;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10534;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8601;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8601;}}}}}}s:1:"n";a:1:{s:1:"w";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10538;}}}}}}s:1:"z";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:223;}s:9:"codepoint";i:223;}}}}}s:1:"t";a:13:{s:1:"a";a:2:{s:1:"r";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8982;}}}}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:964;}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9140;}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:357;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:355;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1090;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8411;}}}}s:1:"e";a:1:{s:1:"l";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8981;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120113;}}}s:1:"h";a:4:{s:1:"e";a:2:{s:1:"r";a:1:{s:1:"e";a:2:{i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8756;}}s:1:"f";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8756;}}}}}}}s:1:"t";a:1:{s:1:"a";a:3:{s:1:";";a:1:{s:9:"codepoint";i:952;}s:1:"s";a:1:{s:1:"y";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:977;}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:977;}}}}}s:1:"i";a:2:{s:1:"c";a:1:{s:1:"k";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8776;}}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8764;}}}}}}s:1:"n";a:1:{s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8201;}}}}}s:1:"k";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8776;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8764;}}}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:254;}s:9:"codepoint";i:254;}}}}s:1:"i";a:3:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:732;}}}}s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:215;}s:9:"codepoint";i:215;s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8864;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10801;}}}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10800;}}}}}s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8749;}}}}s:1:"o";a:3:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10536;}}}s:1:"p";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8868;}s:1:"b";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9014;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10993;}}}}s:1:"f";a:2:{s:1:";";a:1:{s:9:"codepoint";i:120165;}s:1:"o";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10970;}}}}}}s:1:"s";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10537;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8244;}}}}}}s:1:"r";a:3:{s:1:"a";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8482;}}}}s:1:"i";a:7:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:5:{s:1:";";a:1:{s:9:"codepoint";i:9653;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9663;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9667;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8884;}}}}}}}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8796;}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9657;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8885;}}}}}}}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9708;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8796;}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10810;}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10809;}}}}}s:1:"s";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10701;}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10811;}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"z";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9186;}}}}}}}}s:1:"s";a:3:{s:1:"c";a:2:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120009;}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1094;}}}s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1115;}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:359;}}}}}}s:1:"w";a:2:{s:1:"i";a:1:{s:1:"x";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8812;}}}}s:1:"o";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"d";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8606;}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8608;}}}}}}}}}}}}}}}}}}s:1:"u";a:18:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8657;}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10595;}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:250;}s:9:"codepoint";i:250;}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8593;}}}}s:1:"b";a:1:{s:1:"r";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1118;}}}s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:365;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:251;}s:9:"codepoint";i:251;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1091;}}}s:1:"d";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8645;}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:369;}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10606;}}}}}s:1:"f";a:2:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10622;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120114;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:249;}s:9:"codepoint";i:249;}}}}}s:1:"h";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8639;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8638;}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9600;}}}}}s:1:"l";a:2:{s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8988;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8988;}}}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8975;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9720;}}}}}s:1:"m";a:2:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:363;}}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:168;}s:9:"codepoint";i:168;}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:371;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120166;}}}}s:1:"p";a:6:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8593;}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8597;}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8639;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8638;}}}}}}}}}}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8846;}}}}s:1:"s";a:1:{s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:965;}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:978;}}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:965;}}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8648;}}}}}}}}}}s:1:"r";a:3:{s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8989;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8989;}}}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8974;}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:367;}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9721;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120010;}}}}s:1:"t";a:3:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8944;}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:361;}}}}}s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9653;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9652;}}}}}s:1:"u";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8648;}}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:252;}s:9:"codepoint";i:252;}}}s:1:"w";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10663;}}}}}}}}s:1:"v";a:14:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8661;}}}}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10984;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10985;}}}}}s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8872;}}}}}s:1:"a";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10652;}}}}}s:1:"r";a:7:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:949;}}}}}}}}s:1:"k";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1008;}}}}}}s:1:"n";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8709;}}}}}}}}s:1:"p";a:3:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:966;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:982;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8597;}s:1:"h";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1009;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:962;}}}}}}s:1:"t";a:2:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:977;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8882;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8883;}}}}}}}}}}}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1074;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8866;}}}}}s:1:"e";a:3:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8744;}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8891;}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8794;}}}}s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8942;}}}}}s:1:"r";a:2:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:124;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:124;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120115;}}}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8882;}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120167;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}s:1:"r";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8883;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120011;}}}}s:1:"z";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"z";a:1:{s:1:"a";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10650;}}}}}}}}s:1:"w";a:7:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:373;}}}}}s:1:"e";a:2:{s:1:"d";a:2:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10847;}}}}s:1:"g";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8743;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8793;}}}}}s:1:"i";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8472;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120116;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120168;}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8472;}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8768;}s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8768;}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120012;}}}}}s:1:"x";a:14:{s:1:"c";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8898;}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9711;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8899;}}}}s:1:"d";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9661;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120117;}}}s:1:"h";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10234;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10231;}}}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:958;}}s:1:"l";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10232;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10229;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10236;}}}}s:1:"n";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8955;}}}}s:1:"o";a:3:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10752;}}}}s:1:"p";a:2:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120169;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10753;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10754;}}}}}}s:1:"r";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10233;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10230;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120013;}}}s:1:"q";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10758;}}}}}}s:1:"u";a:2:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10756;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9651;}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8897;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8896;}}}}}}}s:1:"y";a:8:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:253;}s:9:"codepoint";i:253;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1103;}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:375;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1099;}}}s:1:"e";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:165;}s:9:"codepoint";i:165;}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120118;}}}s:1:"i";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1111;}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120170;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120014;}}}}s:1:"u";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1102;}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:255;}s:9:"codepoint";i:255;}}}}s:1:"z";a:10:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:378;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:382;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1079;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:380;}}}}s:1:"e";a:2:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8488;}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:950;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120119;}}}s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1078;}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8669;}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120171;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120015;}}}}s:1:"w";a:2:{s:1:"j";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8205;}}s:1:"n";a:1:{s:1:"j";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8204;}}}}}} \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/humble-http-agent/CookieJar.php b/inc/3rdparty/libraries/humble-http-agent/CookieJar.php deleted file mode 100644 index e4d5f495..00000000 --- a/inc/3rdparty/libraries/humble-http-agent/CookieJar.php +++ /dev/null | |||
@@ -1,403 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Cookie Jar | ||
4 | * | ||
5 | * PHP class for handling cookies, as defined by the Netscape spec: | ||
6 | * <http://curl.haxx.se/rfc/cookie_spec.html> | ||
7 | * | ||
8 | * This class should be used to handle cookies (storing cookies from HTTP response messages, and | ||
9 | * sending out cookies in HTTP request messages). This has been adapted for FiveFilters.org | ||
10 | * from the original version used in HTTP Navigator. See http://www.keyvan.net/code/http-navigator/ | ||
11 | * | ||
12 | * This class is mainly based on Cookies.pm <http://search.cpan.org/author/GAAS/libwww-perl-5.65/ | ||
13 | * lib/HTTP/Cookies.pm> from the libwww-perl collection <http://www.linpro.no/lwp/>. | ||
14 | * Unlike Cookies.pm, this class only supports the Netscape cookie spec, not RFC 2965. | ||
15 | * | ||
16 | * @version 0.5 | ||
17 | * @date 2011-03-15 | ||
18 | * @see http://php.net/HttpRequestPool | ||
19 | * @author Keyvan Minoukadeh | ||
20 | * @copyright 2011 Keyvan Minoukadeh | ||
21 | * @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3 | ||
22 | */ | ||
23 | |||
24 | class CookieJar | ||
25 | { | ||
26 | /** | ||
27 | * Cookies - array containing all cookies. | ||
28 | * | ||
29 | * <pre> | ||
30 | * Cookies are stored like this: | ||
31 | * [domain][path][name] = array | ||
32 | * where array is: | ||
33 | * 0 => value, 1 => secure, 2 => expires | ||
34 | * </pre> | ||
35 | * @var array | ||
36 | * @access private | ||
37 | */ | ||
38 | public $cookies = array(); | ||
39 | public $debug = false; | ||
40 | |||
41 | /** | ||
42 | * Constructor | ||
43 | */ | ||
44 | function __construct() { | ||
45 | } | ||
46 | |||
47 | protected function debug($msg, $file=null, $line=null) { | ||
48 | if ($this->debug) { | ||
49 | $mem = round(memory_get_usage()/1024, 2); | ||
50 | $memPeak = round(memory_get_peak_usage()/1024, 2); | ||
51 | echo '* ',$msg; | ||
52 | if (isset($file, $line)) echo " ($file line $line)"; | ||
53 | echo ' - mem used: ',$mem," (peak: $memPeak)\n"; | ||
54 | ob_flush(); | ||
55 | flush(); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Get matching cookies | ||
61 | * | ||
62 | * Only use this method if you cannot use add_cookie_header(), for example, if you want to use | ||
63 | * this cookie jar class without using the request class. | ||
64 | * | ||
65 | * @param array $param associative array containing 'domain', 'path', 'secure' keys | ||
66 | * @return string | ||
67 | * @see add_cookie_header() | ||
68 | */ | ||
69 | public function getMatchingCookies($url) | ||
70 | { | ||
71 | if (($parts = @parse_url($url)) && isset($parts['scheme'], $parts['host'], $parts['path'])) { | ||
72 | $param['domain'] = $parts['host']; | ||
73 | $param['path'] = $parts['path']; | ||
74 | $param['secure'] = (strtolower($parts['scheme']) == 'https'); | ||
75 | unset($parts); | ||
76 | } else { | ||
77 | return false; | ||
78 | } | ||
79 | // RFC 2965 notes: | ||
80 | // If multiple cookies satisfy the criteria above, they are ordered in | ||
81 | // the Cookie header such that those with more specific Path attributes | ||
82 | // precede those with less specific. Ordering with respect to other | ||
83 | // attributes (e.g., Domain) is unspecified. | ||
84 | $domain = $param['domain']; | ||
85 | if (strpos($domain, '.') === false) $domain .= '.local'; | ||
86 | $request_path = $param['path']; | ||
87 | if ($request_path == '') $request_path = '/'; | ||
88 | $request_secure = $param['secure']; | ||
89 | $now = time(); | ||
90 | $matched_cookies = array(); | ||
91 | // domain - find matching domains | ||
92 | $this->debug('Finding matching domains for '.$domain, __FILE__, __LINE__); | ||
93 | while (strpos($domain, '.') !== false) { | ||
94 | if (isset($this->cookies[$domain])) { | ||
95 | $this->debug(' domain match found: '.$domain); | ||
96 | $cookies =& $this->cookies[$domain]; | ||
97 | } else { | ||
98 | $domain = $this->_reduce_domain($domain); | ||
99 | continue; | ||
100 | } | ||
101 | // paths - find matching paths starting from most specific | ||
102 | $this->debug(' - Finding matching paths for '.$request_path); | ||
103 | $paths = array_keys($cookies); | ||
104 | usort($paths, array($this, '_cmp_length')); | ||
105 | foreach ($paths as $path) { | ||
106 | // continue to next cookie if request path does not path-match cookie path | ||
107 | if (!$this->_path_match($request_path, $path)) continue; | ||
108 | // loop through cookie names | ||
109 | $this->debug(' path match found: '.$path); | ||
110 | foreach ($cookies[$path] as $name => $values) { | ||
111 | // if this cookie is secure but request isn't, continue to next cookie | ||
112 | if ($values[1] && !$request_secure) continue; | ||
113 | // if cookie is not a session cookie and has expired, continue to next cookie | ||
114 | if (is_int($values[2]) && ($values[2] < $now)) continue; | ||
115 | // cookie matches request | ||
116 | $this->debug(' cookie match: '.$name.'='.$values[0]); | ||
117 | $matched_cookies[] = $name.'='.$values[0]; | ||
118 | } | ||
119 | } | ||
120 | $domain = $this->_reduce_domain($domain); | ||
121 | } | ||
122 | // return cookies | ||
123 | return implode('; ', $matched_cookies); | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * Parse Set-Cookie values. | ||
128 | * | ||
129 | * Only use this method if you cannot use extract_cookies(), for example, if you want to use | ||
130 | * this cookie jar class without using the response class. | ||
131 | * | ||
132 | * @param array $set_cookies array holding 1 or more "Set-Cookie" header values | ||
133 | * @param array $param associative array containing 'host', 'path' keys | ||
134 | * @return void | ||
135 | * @see extract_cookies() | ||
136 | */ | ||
137 | public function storeCookies($url, $set_cookies) | ||
138 | { | ||
139 | if (count($set_cookies) == 0) return; | ||
140 | $param = @parse_url($url); | ||
141 | if (!is_array($param) || !isset($param['host'])) return; | ||
142 | $request_host = $param['host']; | ||
143 | if (strpos($request_host, '.') === false) $request_host .= '.local'; | ||
144 | $request_path = @$param['path']; | ||
145 | if ($request_path == '') $request_path = '/'; | ||
146 | // | ||
147 | // loop through set-cookie headers | ||
148 | // | ||
149 | foreach ($set_cookies as $set_cookie) { | ||
150 | $this->debug('Parsing: '.$set_cookie); | ||
151 | // temporary cookie store (before adding to jar) | ||
152 | $tmp_cookie = array(); | ||
153 | $param = explode(';', $set_cookie); | ||
154 | // loop through params | ||
155 | for ($x=0; $x<count($param); $x++) { | ||
156 | $key_val = explode('=', $param[$x], 2); | ||
157 | if (count($key_val) != 2) { | ||
158 | // if the first param isn't a name=value pair, continue to the next set-cookie | ||
159 | // header | ||
160 | if ($x == 0) continue 2; | ||
161 | // check for secure flag | ||
162 | if (strtolower(trim($key_val[0])) == 'secure') $tmp_cookie['secure'] = true; | ||
163 | // continue to next param | ||
164 | continue; | ||
165 | } | ||
166 | list($key, $val) = array_map('trim', $key_val); | ||
167 | // first name=value pair is the cookie name and value | ||
168 | // the name and value are stored under 'name' and 'value' to avoid conflicts | ||
169 | // with later parameters. | ||
170 | if ($x == 0) { | ||
171 | $tmp_cookie = array('name'=>$key, 'value'=>$val); | ||
172 | continue; | ||
173 | } | ||
174 | $key = strtolower($key); | ||
175 | if (in_array($key, array('expires', 'path', 'domain', 'secure'))) { | ||
176 | $tmp_cookie[$key] = $val; | ||
177 | } | ||
178 | } | ||
179 | // | ||
180 | // set cookie | ||
181 | // | ||
182 | // check domain | ||
183 | if (isset($tmp_cookie['domain']) && ($tmp_cookie['domain'] != $request_host) && | ||
184 | ($tmp_cookie['domain'] != ".$request_host")) { | ||
185 | $domain = $tmp_cookie['domain']; | ||
186 | if ((strpos($domain, '.') === false) && ($domain != 'local')) { | ||
187 | $this->debug(' - domain "'.$domain.'" has no dot and is not a local domain'); | ||
188 | continue; | ||
189 | } | ||
190 | if (preg_match('/\.[0-9]+$/', $domain)) { | ||
191 | $this->debug(' - domain "'.$domain.'" appears to be an ip address'); | ||
192 | continue; | ||
193 | } | ||
194 | if (substr($domain, 0, 1) != '.') $domain = ".$domain"; | ||
195 | if (!$this->_domain_match($request_host, $domain)) { | ||
196 | $this->debug(' - request host "'.$request_host.'" does not domain-match "'.$domain.'"'); | ||
197 | continue; | ||
198 | } | ||
199 | } else { | ||
200 | // if domain is not specified in the set-cookie header, domain will default to | ||
201 | // the request host | ||
202 | $domain = $request_host; | ||
203 | } | ||
204 | // check path | ||
205 | if (isset($tmp_cookie['path']) && ($tmp_cookie['path'] != '')) { | ||
206 | $path = urldecode($tmp_cookie['path']); | ||
207 | if (!$this->_path_match($request_path, $path)) { | ||
208 | $this->debug(' - request path "'.$request_path.'" does not path-match "'.$path.'"'); | ||
209 | continue; | ||
210 | } | ||
211 | } else { | ||
212 | $path = $request_path; | ||
213 | $path = substr($path, 0, strrpos($path, '/')); | ||
214 | if ($path == '') $path = '/'; | ||
215 | } | ||
216 | // check if secure | ||
217 | $secure = (isset($tmp_cookie['secure'])) ? true : false; | ||
218 | // check expiry | ||
219 | if (isset($tmp_cookie['expires'])) { | ||
220 | if (($expires = strtotime($tmp_cookie['expires'])) < 0) { | ||
221 | $expires = null; | ||
222 | } | ||
223 | } else { | ||
224 | $expires = null; | ||
225 | } | ||
226 | // set cookie | ||
227 | $this->set_cookie($domain, $path, $tmp_cookie['name'], $tmp_cookie['value'], $secure, $expires); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | // return array of set-cookie values extracted from HTTP response headers (string $h) | ||
232 | public function extractCookies($h) { | ||
233 | $x = 0; | ||
234 | $lines = 0; | ||
235 | $headers = array(); | ||
236 | $last_match = false; | ||
237 | $h = explode("\n", $h); | ||
238 | foreach ($h as $line) { | ||
239 | $line = rtrim($line); | ||
240 | $lines++; | ||
241 | |||
242 | $trimmed_line = trim($line); | ||
243 | if (isset($line_last)) { | ||
244 | // check if we have \r\n\r\n (indicating the end of headers) | ||
245 | // some servers will not use CRLF (\r\n), so we make CR (\r) optional. | ||
246 | // if (preg_match('/\015?\012\015?\012/', $line_last.$line)) { | ||
247 | // break; | ||
248 | // } | ||
249 | // As an alternative, we can check if the current trimmed line is empty | ||
250 | if ($trimmed_line == '') { | ||
251 | break; | ||
252 | } | ||
253 | |||
254 | // check for continuation line... | ||
255 | // RFC 2616 Section 2.2 "Basic Rules": | ||
256 | // HTTP/1.1 header field values can be folded onto multiple lines if the | ||
257 | // continuation line begins with a space or horizontal tab. All linear | ||
258 | // white space, including folding, has the same semantics as SP. A | ||
259 | // recipient MAY replace any linear white space with a single SP before | ||
260 | // interpreting the field value or forwarding the message downstream. | ||
261 | if ($last_match && preg_match('/^\s+(.*)/', $line, $match)) { | ||
262 | // append to previous header value | ||
263 | $headers[$x-1] .= ' '.rtrim($match[1]); | ||
264 | continue; | ||
265 | } | ||
266 | } | ||
267 | $line_last = $line; | ||
268 | |||
269 | // split header name and value | ||
270 | if (preg_match('/^Set-Cookie\s*:\s*(.*)/i', $line, $match)) { | ||
271 | $headers[$x++] = rtrim($match[1]); | ||
272 | $last_match = true; | ||
273 | } else { | ||
274 | $last_match = false; | ||
275 | } | ||
276 | } | ||
277 | return $headers; | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * Set Cookie | ||
282 | * @param string $domain | ||
283 | * @param string $path | ||
284 | * @param string $name cookie name | ||
285 | * @param string $value cookie value | ||
286 | * @param bool $secure | ||
287 | * @param int $expires expiry time (null if session cookie, <= 0 will delete cookie) | ||
288 | * @return void | ||
289 | */ | ||
290 | function set_cookie($domain, $path, $name, $value, $secure=false, $expires=null) | ||
291 | { | ||
292 | if ($domain == '') return; | ||
293 | if ($path == '') return; | ||
294 | if ($name == '') return; | ||
295 | // check if cookie needs to go | ||
296 | if (isset($expires) && ($expires <= 0)) { | ||
297 | if (isset($this->cookies[$domain][$path][$name])) unset($this->cookies[$domain][$path][$name]); | ||
298 | return; | ||
299 | } | ||
300 | if ($value == '') return; | ||
301 | $this->cookies[$domain][$path][$name] = array($value, $secure, $expires); | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | /** | ||
306 | * Clear cookies - [domain [,path [,name]]] - call method with no arguments to clear all cookies. | ||
307 | * @param string $domain | ||
308 | * @param string $path | ||
309 | * @param string $name | ||
310 | * @return void | ||
311 | */ | ||
312 | function clear($domain=null, $path=null, $name=null) | ||
313 | { | ||
314 | if (!isset($domain)) { | ||
315 | $this->cookies = array(); | ||
316 | } elseif (!isset($path)) { | ||
317 | if (isset($this->cookies[$domain])) unset($this->cookies[$domain]); | ||
318 | } elseif (!isset($name)) { | ||
319 | if (isset($this->cookies[$domain][$path])) unset($this->cookies[$domain][$path]); | ||
320 | } elseif (isset($name)) { | ||
321 | if (isset($this->cookies[$domain][$path][$name])) unset($this->cookies[$domain][$path][$name]); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | /** | ||
326 | * Compare string length - used for sorting | ||
327 | * @access private | ||
328 | * @return int | ||
329 | */ | ||
330 | function _cmp_length($a, $b) | ||
331 | { | ||
332 | $la = strlen($a); $lb = strlen($b); | ||
333 | if ($la == $lb) return 0; | ||
334 | return ($la > $lb) ? -1 : 1; | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * Reduce domain | ||
339 | * @param string $domain | ||
340 | * @return string | ||
341 | * @access private | ||
342 | */ | ||
343 | function _reduce_domain($domain) | ||
344 | { | ||
345 | if ($domain == '') return ''; | ||
346 | if (substr($domain, 0, 1) == '.') return substr($domain, 1); | ||
347 | return substr($domain, strpos($domain, '.')); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Path match - check if path1 path-matches path2 | ||
352 | * | ||
353 | * From RFC 2965: | ||
354 | * <i>For two strings that represent paths, P1 and P2, P1 path-matches P2 | ||
355 | * if P2 is a prefix of P1 (including the case where P1 and P2 string- | ||
356 | * compare equal). Thus, the string /tec/waldo path-matches /tec.</i> | ||
357 | * @param string $path1 | ||
358 | * @param string $path2 | ||
359 | * @return bool | ||
360 | * @access private | ||
361 | */ | ||
362 | function _path_match($path1, $path2) | ||
363 | { | ||
364 | return (substr($path1, 0, strlen($path2)) == $path2); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Domain match - check if domain1 domain-matches domain2 | ||
369 | * | ||
370 | * A few extracts from RFC 2965: | ||
371 | * - A Set-Cookie2 from request-host y.x.foo.com for Domain=.foo.com | ||
372 | * would be rejected, because H is y.x and contains a dot. | ||
373 | * | ||
374 | * - A Set-Cookie2 from request-host x.foo.com for Domain=.foo.com | ||
375 | * would be accepted. | ||
376 | * | ||
377 | * - A Set-Cookie2 with Domain=.com or Domain=.com., will always be | ||
378 | * rejected, because there is no embedded dot. | ||
379 | * | ||
380 | * - A Set-Cookie2 from request-host example for Domain=.local will | ||
381 | * be accepted, because the effective host name for the request- | ||
382 | * host is example.local, and example.local domain-matches .local. | ||
383 | * | ||
384 | * I'm ignoring the first point for now (must check to see how other browsers handle | ||
385 | * this rule for Set-Cookie headers) | ||
386 | * | ||
387 | * @param string $domain1 | ||
388 | * @param string $domain2 | ||
389 | * @return bool | ||
390 | * @access private | ||
391 | */ | ||
392 | function _domain_match($domain1, $domain2) | ||
393 | { | ||
394 | $domain1 = strtolower($domain1); | ||
395 | $domain2 = strtolower($domain2); | ||
396 | while (strpos($domain1, '.') !== false) { | ||
397 | if ($domain1 == $domain2) return true; | ||
398 | $domain1 = $this->_reduce_domain($domain1); | ||
399 | continue; | ||
400 | } | ||
401 | return false; | ||
402 | } | ||
403 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/humble-http-agent/HumbleHttpAgent.php b/inc/3rdparty/libraries/humble-http-agent/HumbleHttpAgent.php deleted file mode 100644 index 963f0c05..00000000 --- a/inc/3rdparty/libraries/humble-http-agent/HumbleHttpAgent.php +++ /dev/null | |||
@@ -1,810 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Humble HTTP Agent | ||
4 | * | ||
5 | * This class is designed to take advantage of parallel HTTP requests | ||
6 | * offered by PHP's PECL HTTP extension or the curl_multi_* functions. | ||
7 | * For environments which do not have these options, it reverts to standard sequential | ||
8 | * requests (using file_get_contents()) | ||
9 | * | ||
10 | * @version 1.4 | ||
11 | * @date 2013-05-10 | ||
12 | * @see http://php.net/HttpRequestPool | ||
13 | * @author Keyvan Minoukadeh | ||
14 | * @copyright 2011-2013 Keyvan Minoukadeh | ||
15 | * @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3 | ||
16 | */ | ||
17 | |||
18 | class HumbleHttpAgent | ||
19 | { | ||
20 | const METHOD_REQUEST_POOL = 1; | ||
21 | const METHOD_CURL_MULTI = 2; | ||
22 | const METHOD_FILE_GET_CONTENTS = 4; | ||
23 | //const UA_BROWSER = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'; | ||
24 | const UA_BROWSER = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.92 Safari/535.2'; | ||
25 | const UA_PHP = 'PHP/5.4'; | ||
26 | const REF_GOOGLE = 'http://www.google.co.uk/url?sa=t&source=web&cd=1'; | ||
27 | |||
28 | protected $requests = array(); | ||
29 | protected $redirectQueue = array(); | ||
30 | protected $requestOptions; | ||
31 | protected $maxParallelRequests = 5; | ||
32 | protected $cache = null; //TODO | ||
33 | protected $httpContext; | ||
34 | protected $minimiseMemoryUse = false; //TODO | ||
35 | protected $method; | ||
36 | protected $cookieJar; | ||
37 | public $debug = false; | ||
38 | public $debugVerbose = false; | ||
39 | public $rewriteHashbangFragment = true; // see http://code.google.com/web/ajaxcrawling/docs/specification.html | ||
40 | public $maxRedirects = 5; | ||
41 | public $userAgentMap = array(); | ||
42 | public $rewriteUrls = array(); | ||
43 | public $userAgentDefault; | ||
44 | public $referer; | ||
45 | //public $userAgent = 'Mozilla/5.0'; | ||
46 | |||
47 | // Prevent certain file/mime types | ||
48 | // HTTP responses which match these content types will | ||
49 | // be returned without body. | ||
50 | public $headerOnlyTypes = array(); | ||
51 | // URLs ending with one of these extensions will | ||
52 | // prompt Humble HTTP Agent to send a HEAD request first | ||
53 | // to see if returned content type matches $headerOnlyTypes. | ||
54 | public $headerOnlyClues = array('pdf','mp3','zip','exe','gif','gzip','gz','jpeg','jpg','mpg','mpeg','png','ppt','mov'); | ||
55 | // AJAX triggers to search for. | ||
56 | // for AJAX sites, e.g. Blogger with its dynamic views templates. | ||
57 | public $ajaxTriggers = array("<meta name='fragment' content='!'",'<meta name="fragment" content="!"',"<meta content='!' name='fragment'",'<meta content="!" name="fragment"'); | ||
58 | |||
59 | //TODO: set max file size | ||
60 | //TODO: normalise headers | ||
61 | |||
62 | function __construct($requestOptions=null, $method=null) { | ||
63 | $this->userAgentDefault = self::UA_BROWSER; | ||
64 | $this->referer = self::REF_GOOGLE; | ||
65 | // set the request method | ||
66 | if (in_array($method, array(1,2,4))) { | ||
67 | $this->method = $method; | ||
68 | } else { | ||
69 | if (class_exists('HttpRequestPool')) { | ||
70 | $this->method = self::METHOD_REQUEST_POOL; | ||
71 | } elseif (function_exists('curl_multi_init')) { | ||
72 | $this->method = self::METHOD_CURL_MULTI; | ||
73 | } else { | ||
74 | $this->method = self::METHOD_FILE_GET_CONTENTS; | ||
75 | } | ||
76 | } | ||
77 | if ($this->method == self::METHOD_CURL_MULTI) { | ||
78 | require_once(dirname(__FILE__).'/RollingCurl.php'); | ||
79 | } | ||
80 | // create cookie jar | ||
81 | $this->cookieJar = new CookieJar(); | ||
82 | // set request options (redirect must be 0) | ||
83 | $this->requestOptions = array( | ||
84 | 'timeout' => 15, | ||
85 | 'connecttimeout' => 15, | ||
86 | 'dns_cache_timeout' => 300, | ||
87 | 'redirect' => 0 // we handle redirects manually so we can rewrite the new hashbang URLs that are creeping up over the web | ||
88 | // TODO: test onprogress? | ||
89 | ); | ||
90 | if (is_array($requestOptions)) { | ||
91 | $this->requestOptions = array_merge($this->requestOptions, $requestOptions); | ||
92 | } | ||
93 | $this->httpContext = array( | ||
94 | 'http' => array( | ||
95 | 'ignore_errors' => true, | ||
96 | 'timeout' => $this->requestOptions['timeout'], | ||
97 | 'max_redirects' => $this->requestOptions['redirect'], | ||
98 | 'header' => "Accept: */*\r\n" | ||
99 | ) | ||
100 | ); | ||
101 | } | ||
102 | |||
103 | protected function debug($msg) { | ||
104 | if ($this->debug) { | ||
105 | $mem = round(memory_get_usage()/1024, 2); | ||
106 | $memPeak = round(memory_get_peak_usage()/1024, 2); | ||
107 | echo '* ',$msg; | ||
108 | if ($this->debugVerbose) echo ' - mem used: ',$mem," (peak: $memPeak)"; | ||
109 | echo "\n"; | ||
110 | ob_flush(); | ||
111 | flush(); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | protected function getUserAgent($url, $asArray=false) { | ||
116 | $host = @parse_url($url, PHP_URL_HOST); | ||
117 | if (strtolower(substr($host, 0, 4)) == 'www.') { | ||
118 | $host = substr($host, 4); | ||
119 | } | ||
120 | if ($host) { | ||
121 | $try = array($host); | ||
122 | $split = explode('.', $host); | ||
123 | if (count($split) > 1) { | ||
124 | array_shift($split); | ||
125 | $try[] = '.'.implode('.', $split); | ||
126 | } | ||
127 | foreach ($try as $h) { | ||
128 | if (isset($this->userAgentMap[$h])) { | ||
129 | $ua = $this->userAgentMap[$h]; | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | if (!isset($ua)) $ua = $this->userAgentDefault; | ||
135 | if ($asArray) { | ||
136 | return array('User-Agent' => $ua); | ||
137 | } else { | ||
138 | return 'User-Agent: '.$ua; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | public function rewriteHashbangFragment($url) { | ||
143 | // return $url if there's no '#!' | ||
144 | if (strpos($url, '#!') === false) return $url; | ||
145 | // split $url and rewrite | ||
146 | // TODO: is SimplePie_IRI included? | ||
147 | $iri = new SimplePie_IRI($url); | ||
148 | $fragment = substr($iri->fragment, 1); // strip '!' | ||
149 | $iri->fragment = null; | ||
150 | if (isset($iri->query)) { | ||
151 | parse_str($iri->query, $query); | ||
152 | } else { | ||
153 | $query = array(); | ||
154 | } | ||
155 | $query['_escaped_fragment_'] = (string)$fragment; | ||
156 | $iri->query = str_replace('%2F', '/', http_build_query($query)); // needed for some sites | ||
157 | return $iri->get_iri(); | ||
158 | } | ||
159 | |||
160 | public function getRedirectURLfromHTML($url, $html) { | ||
161 | $redirect_url = $this->getMetaRefreshURL($url, $html); | ||
162 | if (!$redirect_url) { | ||
163 | $redirect_url = $this->getUglyURL($url, $html); | ||
164 | } | ||
165 | return $redirect_url; | ||
166 | } | ||
167 | |||
168 | public function getMetaRefreshURL($url, $html) { | ||
169 | if ($html == '') return false; | ||
170 | // <meta HTTP-EQUIV="REFRESH" content="0; url=http://www.bernama.com/bernama/v6/newsindex.php?id=943513"> | ||
171 | if (!preg_match('!<meta http-equiv=["\']?refresh["\']? content=["\']?[0-9];\s*url=["\']?([^"\'>]+)["\']*>!i', $html, $match)) { | ||
172 | return false; | ||
173 | } | ||
174 | $redirect_url = $match[1]; | ||
175 | if (preg_match('!^https?://!i', $redirect_url)) { | ||
176 | // already absolute | ||
177 | $this->debug('Meta refresh redirect found (http-equiv="refresh"), new URL: '.$redirect_url); | ||
178 | return $redirect_url; | ||
179 | } | ||
180 | // absolutize redirect URL | ||
181 | $base = new SimplePie_IRI($url); | ||
182 | // remove '//' in URL path (causes URLs not to resolve properly) | ||
183 | if (isset($base->path)) $base->path = preg_replace('!//+!', '/', $base->path); | ||
184 | if ($absolute = SimplePie_IRI::absolutize($base, $redirect_url)) { | ||
185 | $this->debug('Meta refresh redirect found (http-equiv="refresh"), new URL: '.$absolute); | ||
186 | return $absolute; | ||
187 | } | ||
188 | return false; | ||
189 | } | ||
190 | |||
191 | public function getUglyURL($url, $html) { | ||
192 | if ($html == '') return false; | ||
193 | $found = false; | ||
194 | foreach ($this->ajaxTriggers as $string) { | ||
195 | if (stripos($html, $string)) { | ||
196 | $found = true; | ||
197 | break; | ||
198 | } | ||
199 | } | ||
200 | if (!$found) return false; | ||
201 | $iri = new SimplePie_IRI($url); | ||
202 | if (isset($iri->query)) { | ||
203 | parse_str($iri->query, $query); | ||
204 | } else { | ||
205 | $query = array(); | ||
206 | } | ||
207 | $query['_escaped_fragment_'] = ''; | ||
208 | $iri->query = str_replace('%2F', '/', http_build_query($query)); // needed for some sites | ||
209 | $ugly_url = $iri->get_iri(); | ||
210 | $this->debug('AJAX trigger (meta name="fragment" content="!") found, new URL: '.$ugly_url); | ||
211 | return $ugly_url; | ||
212 | } | ||
213 | |||
214 | public function removeFragment($url) { | ||
215 | $pos = strpos($url, '#'); | ||
216 | if ($pos === false) { | ||
217 | return $url; | ||
218 | } else { | ||
219 | return substr($url, 0, $pos); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | public function rewriteUrls($url) { | ||
224 | foreach ($this->rewriteUrls as $find => $action) { | ||
225 | if (strpos($url, $find) !== false) { | ||
226 | if (is_array($action)) { | ||
227 | return strtr($url, $action); | ||
228 | } | ||
229 | } | ||
230 | } | ||
231 | return $url; | ||
232 | } | ||
233 | |||
234 | public function enableDebug($bool=true) { | ||
235 | $this->debug = (bool)$bool; | ||
236 | } | ||
237 | |||
238 | public function minimiseMemoryUse($bool = true) { | ||
239 | $this->minimiseMemoryUse = $bool; | ||
240 | } | ||
241 | |||
242 | public function setMaxParallelRequests($max) { | ||
243 | $this->maxParallelRequests = $max; | ||
244 | } | ||
245 | |||
246 | public function validateUrl($url) { | ||
247 | $url = filter_var($url, FILTER_SANITIZE_URL); | ||
248 | $test = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED); | ||
249 | // deal with bug http://bugs.php.net/51192 (present in PHP 5.2.13 and PHP 5.3.2) | ||
250 | if ($test === false) { | ||
251 | $test = filter_var(strtr($url, '-', '_'), FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED); | ||
252 | } | ||
253 | if ($test !== false && $test !== null && preg_match('!^https?://!', $url)) { | ||
254 | return $url; | ||
255 | } else { | ||
256 | return false; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | public function fetchAll(array $urls) { | ||
261 | $this->fetchAllOnce($urls, $isRedirect=false); | ||
262 | $redirects = 0; | ||
263 | while (!empty($this->redirectQueue) && ++$redirects <= $this->maxRedirects) { | ||
264 | $this->debug("Following redirects #$redirects..."); | ||
265 | $this->fetchAllOnce($this->redirectQueue, $isRedirect=true); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | // fetch all URLs without following redirects | ||
270 | public function fetchAllOnce(array $urls, $isRedirect=false) { | ||
271 | if (!$isRedirect) $urls = array_unique($urls); | ||
272 | if (empty($urls)) return; | ||
273 | |||
274 | ////////////////////////////////////////////////////// | ||
275 | // parallel (HttpRequestPool) | ||
276 | if ($this->method == self::METHOD_REQUEST_POOL) { | ||
277 | $this->debug('Starting parallel fetch (HttpRequestPool)'); | ||
278 | try { | ||
279 | while (count($urls) > 0) { | ||
280 | $this->debug('Processing set of '.min($this->maxParallelRequests, count($urls))); | ||
281 | $subset = array_splice($urls, 0, $this->maxParallelRequests); | ||
282 | $pool = new HttpRequestPool(); | ||
283 | foreach ($subset as $orig => $url) { | ||
284 | if (!$isRedirect) $orig = $url; | ||
285 | unset($this->redirectQueue[$orig]); | ||
286 | $this->debug("...$url"); | ||
287 | if (!$isRedirect && isset($this->requests[$url])) { | ||
288 | $this->debug("......in memory"); | ||
289 | /* | ||
290 | } elseif ($this->isCached($url)) { | ||
291 | $this->debug("......is cached"); | ||
292 | if (!$this->minimiseMemoryUse) { | ||
293 | $this->requests[$url] = $this->getCached($url); | ||
294 | } | ||
295 | */ | ||
296 | } else { | ||
297 | $this->debug("......adding to pool"); | ||
298 | $req_url = $this->rewriteUrls($url); | ||
299 | $req_url = ($this->rewriteHashbangFragment) ? $this->rewriteHashbangFragment($req_url) : $req_url; | ||
300 | $req_url = $this->removeFragment($req_url); | ||
301 | if (!empty($this->headerOnlyTypes) && !isset($this->requests[$orig]['wrongGuess']) && $this->possibleUnsupportedType($req_url)) { | ||
302 | $_meth = HttpRequest::METH_HEAD; | ||
303 | } else { | ||
304 | $_meth = HttpRequest::METH_GET; | ||
305 | unset($this->requests[$orig]['wrongGuess']); | ||
306 | } | ||
307 | $httpRequest = new HttpRequest($req_url, $_meth, $this->requestOptions); | ||
308 | // send cookies, if we have any | ||
309 | if ($cookies = $this->cookieJar->getMatchingCookies($req_url)) { | ||
310 | $this->debug("......sending cookies: $cookies"); | ||
311 | $httpRequest->addHeaders(array('Cookie' => $cookies)); | ||
312 | } | ||
313 | //$httpRequest->addHeaders(array('User-Agent' => $this->userAgent)); | ||
314 | $httpRequest->addHeaders($this->getUserAgent($req_url, true)); | ||
315 | // add referer for picky sites | ||
316 | $httpRequest->addheaders(array('Referer' => $this->referer)); | ||
317 | $this->requests[$orig] = array('headers'=>null, 'body'=>null, 'httpRequest'=>$httpRequest); | ||
318 | $this->requests[$orig]['original_url'] = $orig; | ||
319 | $pool->attach($httpRequest); | ||
320 | } | ||
321 | } | ||
322 | // did we get anything into the pool? | ||
323 | if (count($pool) > 0) { | ||
324 | $this->debug('Sending request...'); | ||
325 | try { | ||
326 | $pool->send(); | ||
327 | } catch (HttpRequestPoolException $e) { | ||
328 | // do nothing | ||
329 | } | ||
330 | $this->debug('Received responses'); | ||
331 | foreach($subset as $orig => $url) { | ||
332 | if (!$isRedirect) $orig = $url; | ||
333 | $request = $this->requests[$orig]['httpRequest']; | ||
334 | //$this->requests[$orig]['headers'] = $this->headersToString($request->getResponseHeader()); | ||
335 | // getResponseHeader() doesn't return status line, so, for consistency... | ||
336 | $this->requests[$orig]['headers'] = substr($request->getRawResponseMessage(), 0, $request->getResponseInfo('header_size')); | ||
337 | // check content type | ||
338 | // TODO: use getResponseHeader('content-type') or getResponseInfo() | ||
339 | if ($this->headerOnlyType($this->requests[$orig]['headers'])) { | ||
340 | $this->requests[$orig]['body'] = ''; | ||
341 | $_header_only_type = true; | ||
342 | $this->debug('Header only type returned'); | ||
343 | } else { | ||
344 | $this->requests[$orig]['body'] = $request->getResponseBody(); | ||
345 | $_header_only_type = false; | ||
346 | } | ||
347 | $this->requests[$orig]['effective_url'] = $request->getResponseInfo('effective_url'); | ||
348 | $this->requests[$orig]['status_code'] = $status_code = $request->getResponseCode(); | ||
349 | // is redirect? | ||
350 | if ((in_array($status_code, array(300, 301, 302, 303, 307)) || $status_code > 307 && $status_code < 400) && $request->getResponseHeader('location')) { | ||
351 | $redirectURL = $request->getResponseHeader('location'); | ||
352 | if (!preg_match('!^https?://!i', $redirectURL)) { | ||
353 | $redirectURL = SimplePie_Misc::absolutize_url($redirectURL, $url); | ||
354 | } | ||
355 | if ($this->validateURL($redirectURL)) { | ||
356 | $this->debug('Redirect detected. Valid URL: '.$redirectURL); | ||
357 | // store any cookies | ||
358 | $cookies = $request->getResponseHeader('set-cookie'); | ||
359 | if ($cookies && !is_array($cookies)) $cookies = array($cookies); | ||
360 | if ($cookies) $this->cookieJar->storeCookies($url, $cookies); | ||
361 | $this->redirectQueue[$orig] = $redirectURL; | ||
362 | } else { | ||
363 | $this->debug('Redirect detected. Invalid URL: '.$redirectURL); | ||
364 | } | ||
365 | } elseif (!$_header_only_type && $request->getMethod() === HttpRequest::METH_HEAD) { | ||
366 | // the response content-type did not match our 'header only' types, | ||
367 | // but we'd issues a HEAD request because we assumed it would. So | ||
368 | // let's queue a proper GET request for this item... | ||
369 | $this->debug('Wrong guess at content-type, queing GET request'); | ||
370 | $this->requests[$orig]['wrongGuess'] = true; | ||
371 | $this->redirectQueue[$orig] = $this->requests[$orig]['effective_url']; | ||
372 | } elseif (strpos($this->requests[$orig]['effective_url'], '_escaped_fragment_') === false) { | ||
373 | // check for <meta name='fragment' content='!'/> | ||
374 | // for AJAX sites, e.g. Blogger with its dynamic views templates. | ||
375 | // Based on Google's spec: https://developers.google.com/webmasters/ajax-crawling/docs/specification | ||
376 | if (isset($this->requests[$orig]['body'])) { | ||
377 | $redirectURL = $this->getRedirectURLfromHTML($this->requests[$orig]['effective_url'], substr($this->requests[$orig]['body'], 0, 4000)); | ||
378 | if ($redirectURL) { | ||
379 | $this->redirectQueue[$orig] = $redirectURL; | ||
380 | } | ||
381 | } | ||
382 | } | ||
383 | //die($url.' -multi- '.$request->getResponseInfo('effective_url')); | ||
384 | $pool->detach($request); | ||
385 | unset($this->requests[$orig]['httpRequest'], $request); | ||
386 | /* | ||
387 | if ($this->minimiseMemoryUse) { | ||
388 | if ($this->cache($url)) { | ||
389 | unset($this->requests[$url]); | ||
390 | } | ||
391 | } | ||
392 | */ | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | } catch (HttpException $e) { | ||
397 | $this->debug($e); | ||
398 | return false; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | ////////////////////////////////////////////////////////// | ||
403 | // parallel (curl_multi_*) | ||
404 | elseif ($this->method == self::METHOD_CURL_MULTI) { | ||
405 | $this->debug('Starting parallel fetch (curl_multi_*)'); | ||
406 | while (count($urls) > 0) { | ||
407 | $this->debug('Processing set of '.min($this->maxParallelRequests, count($urls))); | ||
408 | $subset = array_splice($urls, 0, $this->maxParallelRequests); | ||
409 | $pool = new RollingCurl(array($this, 'handleCurlResponse')); | ||
410 | $pool->window_size = count($subset); | ||
411 | |||
412 | foreach ($subset as $orig => $url) { | ||
413 | if (!$isRedirect) $orig = $url; | ||
414 | unset($this->redirectQueue[$orig]); | ||
415 | $this->debug("...$url"); | ||
416 | if (!$isRedirect && isset($this->requests[$url])) { | ||
417 | $this->debug("......in memory"); | ||
418 | /* | ||
419 | } elseif ($this->isCached($url)) { | ||
420 | $this->debug("......is cached"); | ||
421 | if (!$this->minimiseMemoryUse) { | ||
422 | $this->requests[$url] = $this->getCached($url); | ||
423 | } | ||
424 | */ | ||
425 | } else { | ||
426 | $this->debug("......adding to pool"); | ||
427 | $req_url = $this->rewriteUrls($url); | ||
428 | $req_url = ($this->rewriteHashbangFragment) ? $this->rewriteHashbangFragment($req_url) : $req_url; | ||
429 | $req_url = $this->removeFragment($req_url); | ||
430 | if (!empty($this->headerOnlyTypes) && !isset($this->requests[$orig]['wrongGuess']) && $this->possibleUnsupportedType($req_url)) { | ||
431 | $_meth = 'HEAD'; | ||
432 | } else { | ||
433 | $_meth = 'GET'; | ||
434 | unset($this->requests[$orig]['wrongGuess']); | ||
435 | } | ||
436 | $headers = array(); | ||
437 | //$headers[] = 'User-Agent: '.$this->userAgent; | ||
438 | $headers[] = $this->getUserAgent($req_url); | ||
439 | // add referer for picky sites | ||
440 | $headers[] = 'Referer: '.$this->referer; | ||
441 | // send cookies, if we have any | ||
442 | if ($cookies = $this->cookieJar->getMatchingCookies($req_url)) { | ||
443 | $this->debug("......sending cookies: $cookies"); | ||
444 | $headers[] = 'Cookie: '.$cookies; | ||
445 | } | ||
446 | $httpRequest = new RollingCurlRequest($req_url, $_meth, null, $headers, array( | ||
447 | CURLOPT_CONNECTTIMEOUT => $this->requestOptions['timeout'], | ||
448 | CURLOPT_TIMEOUT => $this->requestOptions['timeout'] | ||
449 | )); | ||
450 | $httpRequest->set_original_url($orig); | ||
451 | $this->requests[$orig] = array('headers'=>null, 'body'=>null, 'httpRequest'=>$httpRequest); | ||
452 | $this->requests[$orig]['original_url'] = $orig; // TODO: is this needed anymore? | ||
453 | $pool->add($httpRequest); | ||
454 | } | ||
455 | } | ||
456 | // did we get anything into the pool? | ||
457 | if (count($pool) > 0) { | ||
458 | $this->debug('Sending request...'); | ||
459 | $pool->execute(); // this will call handleCurlResponse() and populate $this->requests[$orig] | ||
460 | $this->debug('Received responses'); | ||
461 | foreach($subset as $orig => $url) { | ||
462 | if (!$isRedirect) $orig = $url; | ||
463 | // $this->requests[$orig]['headers'] | ||
464 | // $this->requests[$orig]['body'] | ||
465 | // $this->requests[$orig]['effective_url'] | ||
466 | // check content type | ||
467 | if ($this->headerOnlyType($this->requests[$orig]['headers'])) { | ||
468 | $this->requests[$orig]['body'] = ''; | ||
469 | $_header_only_type = true; | ||
470 | $this->debug('Header only type returned'); | ||
471 | } else { | ||
472 | $_header_only_type = false; | ||
473 | } | ||
474 | $status_code = $this->requests[$orig]['status_code']; | ||
475 | if ((in_array($status_code, array(300, 301, 302, 303, 307)) || $status_code > 307 && $status_code < 400) && isset($this->requests[$orig]['location'])) { | ||
476 | $redirectURL = $this->requests[$orig]['location']; | ||
477 | if (!preg_match('!^https?://!i', $redirectURL)) { | ||
478 | $redirectURL = SimplePie_Misc::absolutize_url($redirectURL, $url); | ||
479 | } | ||
480 | if ($this->validateURL($redirectURL)) { | ||
481 | $this->debug('Redirect detected. Valid URL: '.$redirectURL); | ||
482 | // store any cookies | ||
483 | $cookies = $this->cookieJar->extractCookies($this->requests[$orig]['headers']); | ||
484 | if (!empty($cookies)) $this->cookieJar->storeCookies($url, $cookies); | ||
485 | $this->redirectQueue[$orig] = $redirectURL; | ||
486 | } else { | ||
487 | $this->debug('Redirect detected. Invalid URL: '.$redirectURL); | ||
488 | } | ||
489 | } elseif (!$_header_only_type && $this->requests[$orig]['method'] == 'HEAD') { | ||
490 | // the response content-type did not match our 'header only' types, | ||
491 | // but we'd issues a HEAD request because we assumed it would. So | ||
492 | // let's queue a proper GET request for this item... | ||
493 | $this->debug('Wrong guess at content-type, queing GET request'); | ||
494 | $this->requests[$orig]['wrongGuess'] = true; | ||
495 | $this->redirectQueue[$orig] = $this->requests[$orig]['effective_url']; | ||
496 | } elseif (strpos($this->requests[$orig]['effective_url'], '_escaped_fragment_') === false) { | ||
497 | // check for <meta name='fragment' content='!'/> | ||
498 | // for AJAX sites, e.g. Blogger with its dynamic views templates. | ||
499 | // Based on Google's spec: https://developers.google.com/webmasters/ajax-crawling/docs/specification | ||
500 | if (isset($this->requests[$orig]['body'])) { | ||
501 | $redirectURL = $this->getRedirectURLfromHTML($this->requests[$orig]['effective_url'], substr($this->requests[$orig]['body'], 0, 4000)); | ||
502 | if ($redirectURL) { | ||
503 | $this->redirectQueue[$orig] = $redirectURL; | ||
504 | } | ||
505 | } | ||
506 | } | ||
507 | // die($url.' -multi- '.$request->getResponseInfo('effective_url')); | ||
508 | unset($this->requests[$orig]['httpRequest'], $this->requests[$orig]['method']); | ||
509 | } | ||
510 | } | ||
511 | } | ||
512 | } | ||
513 | |||
514 | ////////////////////////////////////////////////////// | ||
515 | // sequential (file_get_contents) | ||
516 | else { | ||
517 | $this->debug('Starting sequential fetch (file_get_contents)'); | ||
518 | $this->debug('Processing set of '.count($urls)); | ||
519 | foreach ($urls as $orig => $url) { | ||
520 | if (!$isRedirect) $orig = $url; | ||
521 | unset($this->redirectQueue[$orig]); | ||
522 | $this->debug("...$url"); | ||
523 | if (!$isRedirect && isset($this->requests[$url])) { | ||
524 | $this->debug("......in memory"); | ||
525 | /* | ||
526 | } elseif ($this->isCached($url)) { | ||
527 | $this->debug("......is cached"); | ||
528 | if (!$this->minimiseMemoryUse) { | ||
529 | $this->requests[$url] = $this->getCached($url); | ||
530 | } | ||
531 | */ | ||
532 | } else { | ||
533 | $this->debug("Sending request for $url"); | ||
534 | $this->requests[$orig]['original_url'] = $orig; | ||
535 | $req_url = $this->rewriteUrls($url); | ||
536 | $req_url = ($this->rewriteHashbangFragment) ? $this->rewriteHashbangFragment($req_url) : $req_url; | ||
537 | $req_url = $this->removeFragment($req_url); | ||
538 | // send cookies, if we have any | ||
539 | $httpContext = $this->httpContext; | ||
540 | $httpContext['http']['header'] .= $this->getUserAgent($req_url)."\r\n"; | ||
541 | // add referer for picky sites | ||
542 | $httpContext['http']['header'] .= 'Referer: '.$this->referer."\r\n"; | ||
543 | if ($cookies = $this->cookieJar->getMatchingCookies($req_url)) { | ||
544 | $this->debug("......sending cookies: $cookies"); | ||
545 | $httpContext['http']['header'] .= 'Cookie: '.$cookies."\r\n"; | ||
546 | } | ||
547 | if (false !== ($html = @file_get_contents($req_url, false, stream_context_create($httpContext)))) { | ||
548 | $this->debug('Received response'); | ||
549 | // get status code | ||
550 | if (!isset($http_response_header[0]) || !preg_match('!^HTTP/\d+\.\d+\s+(\d+)!', trim($http_response_header[0]), $match)) { | ||
551 | $this->debug('Error: no status code found'); | ||
552 | // TODO: handle error - no status code | ||
553 | } else { | ||
554 | $this->requests[$orig]['headers'] = $this->headersToString($http_response_header, false); | ||
555 | // check content type | ||
556 | if ($this->headerOnlyType($this->requests[$orig]['headers'])) { | ||
557 | $this->requests[$orig]['body'] = ''; | ||
558 | } else { | ||
559 | $this->requests[$orig]['body'] = $html; | ||
560 | } | ||
561 | $this->requests[$orig]['effective_url'] = $req_url; | ||
562 | $this->requests[$orig]['status_code'] = $status_code = (int)$match[1]; | ||
563 | unset($match); | ||
564 | // handle redirect | ||
565 | if (preg_match('/^Location:(.*?)$/mi', $this->requests[$orig]['headers'], $match)) { | ||
566 | $this->requests[$orig]['location'] = trim($match[1]); | ||
567 | } | ||
568 | if ((in_array($status_code, array(300, 301, 302, 303, 307)) || $status_code > 307 && $status_code < 400) && isset($this->requests[$orig]['location'])) { | ||
569 | $redirectURL = $this->requests[$orig]['location']; | ||
570 | if (!preg_match('!^https?://!i', $redirectURL)) { | ||
571 | $redirectURL = SimplePie_Misc::absolutize_url($redirectURL, $url); | ||
572 | } | ||
573 | if ($this->validateURL($redirectURL)) { | ||
574 | $this->debug('Redirect detected. Valid URL: '.$redirectURL); | ||
575 | // store any cookies | ||
576 | $cookies = $this->cookieJar->extractCookies($this->requests[$orig]['headers']); | ||
577 | if (!empty($cookies)) $this->cookieJar->storeCookies($url, $cookies); | ||
578 | $this->redirectQueue[$orig] = $redirectURL; | ||
579 | } else { | ||
580 | $this->debug('Redirect detected. Invalid URL: '.$redirectURL); | ||
581 | } | ||
582 | } elseif (strpos($this->requests[$orig]['effective_url'], '_escaped_fragment_') === false) { | ||
583 | // check for <meta name='fragment' content='!'/> | ||
584 | // for AJAX sites, e.g. Blogger with its dynamic views templates. | ||
585 | // Based on Google's spec: https://developers.google.com/webmasters/ajax-crawling/docs/specification | ||
586 | if (isset($this->requests[$orig]['body'])) { | ||
587 | $redirectURL = $this->getRedirectURLfromHTML($this->requests[$orig]['effective_url'], substr($this->requests[$orig]['body'], 0, 4000)); | ||
588 | if ($redirectURL) { | ||
589 | $this->redirectQueue[$orig] = $redirectURL; | ||
590 | } | ||
591 | } | ||
592 | } | ||
593 | } | ||
594 | } else { | ||
595 | $this->debug('Error retrieving URL'); | ||
596 | //print_r($req_url); | ||
597 | //print_r($http_response_header); | ||
598 | //print_r($html); | ||
599 | |||
600 | // TODO: handle error - failed to retrieve URL | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | } | ||
606 | |||
607 | public function handleCurlResponse($response, $info, $request) { | ||
608 | $orig = $request->url_original; | ||
609 | $this->requests[$orig]['headers'] = substr($response, 0, $info['header_size']); | ||
610 | $this->requests[$orig]['body'] = substr($response, $info['header_size']); | ||
611 | $this->requests[$orig]['method'] = $request->method; | ||
612 | $this->requests[$orig]['effective_url'] = $info['url']; | ||
613 | $this->requests[$orig]['status_code'] = (int)$info['http_code']; | ||
614 | if (preg_match('/^Location:(.*?)$/mi', $this->requests[$orig]['headers'], $match)) { | ||
615 | $this->requests[$orig]['location'] = trim($match[1]); | ||
616 | } | ||
617 | } | ||
618 | |||
619 | protected function headersToString(array $headers, $associative=true) { | ||
620 | if (!$associative) { | ||
621 | return implode("\n", $headers); | ||
622 | } else { | ||
623 | $str = ''; | ||
624 | foreach ($headers as $key => $val) { | ||
625 | if (is_array($val)) { | ||
626 | foreach ($val as $v) $str .= "$key: $v\n"; | ||
627 | } else { | ||
628 | $str .= "$key: $val\n"; | ||
629 | } | ||
630 | } | ||
631 | return rtrim($str); | ||
632 | } | ||
633 | } | ||
634 | |||
635 | public function get($url, $remove=false, $gzdecode=true) { | ||
636 | $url = "$url"; | ||
637 | if (isset($this->requests[$url]) && isset($this->requests[$url]['body'])) { | ||
638 | $this->debug("URL already fetched - in memory ($url, effective: {$this->requests[$url]['effective_url']})"); | ||
639 | $response = $this->requests[$url]; | ||
640 | /* | ||
641 | } elseif ($this->isCached($url)) { | ||
642 | $this->debug("URL already fetched - in disk cache ($url)"); | ||
643 | $response = $this->getCached($url); | ||
644 | $this->requests[$url] = $response; | ||
645 | */ | ||
646 | } else { | ||
647 | $this->debug("Fetching URL ($url)"); | ||
648 | $this->fetchAll(array($url)); | ||
649 | if (isset($this->requests[$url]) && isset($this->requests[$url]['body'])) { | ||
650 | $response = $this->requests[$url]; | ||
651 | } else { | ||
652 | $this->debug("Request failed"); | ||
653 | $response = false; | ||
654 | } | ||
655 | } | ||
656 | /* | ||
657 | if ($this->minimiseMemoryUse && $response) { | ||
658 | $this->cache($url); | ||
659 | unset($this->requests[$url]); | ||
660 | } | ||
661 | */ | ||
662 | if ($remove && $response) unset($this->requests[$url]); | ||
663 | if ($gzdecode && stripos($response['headers'], 'Content-Encoding: gzip')) { | ||
664 | if ($html = gzdecode($response['body'])) { | ||
665 | $response['body'] = $html; | ||
666 | } | ||
667 | } | ||
668 | return $response; | ||
669 | } | ||
670 | |||
671 | public function parallelSupport() { | ||
672 | return class_exists('HttpRequestPool') || function_exists('curl_multi_init'); | ||
673 | } | ||
674 | |||
675 | private function headerOnlyType($headers) { | ||
676 | if (preg_match('!^Content-Type:\s*(([a-z-]+)/([^;\r\n ]+))!im', $headers, $match)) { | ||
677 | // look for full mime type (e.g. image/jpeg) or just type (e.g. image) | ||
678 | $match[1] = strtolower(trim($match[1])); | ||
679 | $match[2] = strtolower(trim($match[2])); | ||
680 | foreach (array($match[1], $match[2]) as $mime) { | ||
681 | if (in_array($mime, $this->headerOnlyTypes)) return true; | ||
682 | } | ||
683 | } | ||
684 | return false; | ||
685 | } | ||
686 | |||
687 | private function possibleUnsupportedType($url) { | ||
688 | $path = @parse_url($url, PHP_URL_PATH); | ||
689 | if ($path && strpos($path, '.') !== false) { | ||
690 | $ext = strtolower(trim(pathinfo($path, PATHINFO_EXTENSION))); | ||
691 | return in_array($ext, $this->headerOnlyClues); | ||
692 | } | ||
693 | return false; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | // gzdecode from http://www.php.net/manual/en/function.gzdecode.php#82930 | ||
698 | if (!function_exists('gzdecode')) { | ||
699 | function gzdecode($data,&$filename='',&$error='',$maxlength=null) | ||
700 | { | ||
701 | $len = strlen($data); | ||
702 | if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) { | ||
703 | $error = "Not in GZIP format."; | ||
704 | return null; // Not GZIP format (See RFC 1952) | ||
705 | } | ||
706 | $method = ord(substr($data,2,1)); // Compression method | ||
707 | $flags = ord(substr($data,3,1)); // Flags | ||
708 | if ($flags & 31 != $flags) { | ||
709 | $error = "Reserved bits not allowed."; | ||
710 | return null; | ||
711 | } | ||
712 | // NOTE: $mtime may be negative (PHP integer limitations) | ||
713 | $mtime = unpack("V", substr($data,4,4)); | ||
714 | $mtime = $mtime[1]; | ||
715 | $xfl = substr($data,8,1); | ||
716 | $os = substr($data,8,1); | ||
717 | $headerlen = 10; | ||
718 | $extralen = 0; | ||
719 | $extra = ""; | ||
720 | if ($flags & 4) { | ||
721 | // 2-byte length prefixed EXTRA data in header | ||
722 | if ($len - $headerlen - 2 < 8) { | ||
723 | return false; // invalid | ||
724 | } | ||
725 | $extralen = unpack("v",substr($data,8,2)); | ||
726 | $extralen = $extralen[1]; | ||
727 | if ($len - $headerlen - 2 - $extralen < 8) { | ||
728 | return false; // invalid | ||
729 | } | ||
730 | $extra = substr($data,10,$extralen); | ||
731 | $headerlen += 2 + $extralen; | ||
732 | } | ||
733 | $filenamelen = 0; | ||
734 | $filename = ""; | ||
735 | if ($flags & 8) { | ||
736 | // C-style string | ||
737 | if ($len - $headerlen - 1 < 8) { | ||
738 | return false; // invalid | ||
739 | } | ||
740 | $filenamelen = strpos(substr($data,$headerlen),chr(0)); | ||
741 | if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) { | ||
742 | return false; // invalid | ||
743 | } | ||
744 | $filename = substr($data,$headerlen,$filenamelen); | ||
745 | $headerlen += $filenamelen + 1; | ||
746 | } | ||
747 | $commentlen = 0; | ||
748 | $comment = ""; | ||
749 | if ($flags & 16) { | ||
750 | // C-style string COMMENT data in header | ||
751 | if ($len - $headerlen - 1 < 8) { | ||
752 | return false; // invalid | ||
753 | } | ||
754 | $commentlen = strpos(substr($data,$headerlen),chr(0)); | ||
755 | if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) { | ||
756 | return false; // Invalid header format | ||
757 | } | ||
758 | $comment = substr($data,$headerlen,$commentlen); | ||
759 | $headerlen += $commentlen + 1; | ||
760 | } | ||
761 | $headercrc = ""; | ||
762 | if ($flags & 2) { | ||
763 | // 2-bytes (lowest order) of CRC32 on header present | ||
764 | if ($len - $headerlen - 2 < 8) { | ||
765 | return false; // invalid | ||
766 | } | ||
767 | $calccrc = crc32(substr($data,0,$headerlen)) & 0xffff; | ||
768 | $headercrc = unpack("v", substr($data,$headerlen,2)); | ||
769 | $headercrc = $headercrc[1]; | ||
770 | if ($headercrc != $calccrc) { | ||
771 | $error = "Header checksum failed."; | ||
772 | return false; // Bad header CRC | ||
773 | } | ||
774 | $headerlen += 2; | ||
775 | } | ||
776 | // GZIP FOOTER | ||
777 | $datacrc = unpack("V",substr($data,-8,4)); | ||
778 | $datacrc = sprintf('%u',$datacrc[1] & 0xFFFFFFFF); | ||
779 | $isize = unpack("V",substr($data,-4)); | ||
780 | $isize = $isize[1]; | ||
781 | // decompression: | ||
782 | $bodylen = $len-$headerlen-8; | ||
783 | if ($bodylen < 1) { | ||
784 | // IMPLEMENTATION BUG! | ||
785 | return null; | ||
786 | } | ||
787 | $body = substr($data,$headerlen,$bodylen); | ||
788 | $data = ""; | ||
789 | if ($bodylen > 0) { | ||
790 | switch ($method) { | ||
791 | case 8: | ||
792 | // Currently the only supported compression method: | ||
793 | $data = gzinflate($body,$maxlength); | ||
794 | break; | ||
795 | default: | ||
796 | $error = "Unknown compression method."; | ||
797 | return false; | ||
798 | } | ||
799 | } // zero-byte body content is allowed | ||
800 | // Verifiy CRC32 | ||
801 | $crc = sprintf("%u",crc32($data)); | ||
802 | $crcOK = $crc == $datacrc; | ||
803 | $lenOK = $isize == strlen($data); | ||
804 | if (!$lenOK || !$crcOK) { | ||
805 | $error = ( $lenOK ? '' : 'Length check FAILED. ') . ( $crcOK ? '' : 'Checksum FAILED.'); | ||
806 | return false; | ||
807 | } | ||
808 | return $data; | ||
809 | } | ||
810 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/humble-http-agent/RollingCurl.php b/inc/3rdparty/libraries/humble-http-agent/RollingCurl.php deleted file mode 100644 index d24dc690..00000000 --- a/inc/3rdparty/libraries/humble-http-agent/RollingCurl.php +++ /dev/null | |||
@@ -1,402 +0,0 @@ | |||
1 | <?php | ||
2 | /* | ||
3 | Authored by Josh Fraser (www.joshfraser.com) | ||
4 | Released under Apache License 2.0 | ||
5 | |||
6 | Maintained by Alexander Makarov, http://rmcreative.ru/ | ||
7 | |||
8 | Modified by Keyvan Minoukadeh for the Five Filters project: http://fivefilters.org | ||
9 | */ | ||
10 | |||
11 | /** | ||
12 | * Class that represent a single curl request | ||
13 | */ | ||
14 | class RollingCurlRequest { | ||
15 | public $url = false; | ||
16 | public $url_original = false; // used for tracking redirects | ||
17 | public $method = 'GET'; | ||
18 | public $post_data = null; | ||
19 | public $headers = null; | ||
20 | public $options = null; | ||
21 | |||
22 | /** | ||
23 | * @param string $url | ||
24 | * @param string $method | ||
25 | * @param $post_data | ||
26 | * @param $headers | ||
27 | * @param $options | ||
28 | * @return void | ||
29 | */ | ||
30 | function __construct($url, $method = "GET", $post_data = null, $headers = null, $options = null) { | ||
31 | $this->url = $url; | ||
32 | $this->url_original = $url; | ||
33 | $this->method = $method; | ||
34 | $this->post_data = $post_data; | ||
35 | $this->headers = $headers; | ||
36 | $this->options = $options; | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * @param string $url | ||
41 | * @return void | ||
42 | */ | ||
43 | public function set_original_url($url) { | ||
44 | $this->url_original = $url; | ||
45 | } | ||
46 | /** | ||
47 | * @return void | ||
48 | */ | ||
49 | public function __destruct() { | ||
50 | unset($this->url, $this->url_original, $this->method, $this->post_data, $this->headers, $this->options); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * RollingCurl custom exception | ||
56 | */ | ||
57 | class RollingCurlException extends Exception { | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * Class that holds a rolling queue of curl requests. | ||
62 | * | ||
63 | * @throws RollingCurlException | ||
64 | */ | ||
65 | class RollingCurl implements Countable { | ||
66 | /** | ||
67 | * @var int | ||
68 | * | ||
69 | * Window size is the max number of simultaneous connections allowed. | ||
70 | * | ||
71 | * REMEMBER TO RESPECT THE SERVERS: | ||
72 | * Sending too many requests at one time can easily be perceived | ||
73 | * as a DOS attack. Increase this window_size if you are making requests | ||
74 | * to multiple servers or have permission from the receving server admins. | ||
75 | */ | ||
76 | private $window_size = 5; | ||
77 | |||
78 | /** | ||
79 | * @var float | ||
80 | * | ||
81 | * Timeout is the timeout used for curl_multi_select. | ||
82 | */ | ||
83 | private $timeout = 10; | ||
84 | |||
85 | /** | ||
86 | * @var string|array | ||
87 | * | ||
88 | * Callback function to be applied to each result. | ||
89 | */ | ||
90 | private $callback; | ||
91 | |||
92 | /** | ||
93 | * @var array | ||
94 | * | ||
95 | * Set your base options that you want to be used with EVERY request. | ||
96 | */ | ||
97 | protected $options = array( | ||
98 | CURLOPT_SSL_VERIFYPEER => 0, | ||
99 | CURLOPT_RETURNTRANSFER => 1, | ||
100 | CURLOPT_CONNECTTIMEOUT => 30, | ||
101 | CURLOPT_TIMEOUT => 30 | ||
102 | ); | ||
103 | |||
104 | /** | ||
105 | * @var array | ||
106 | */ | ||
107 | private $headers = array(); | ||
108 | |||
109 | /** | ||
110 | * @var Request[] | ||
111 | * | ||
112 | * The request queue | ||
113 | */ | ||
114 | private $requests = array(); | ||
115 | |||
116 | /** | ||
117 | * @var RequestMap[] | ||
118 | * | ||
119 | * Maps handles to request indexes | ||
120 | */ | ||
121 | private $requestMap = array(); | ||
122 | |||
123 | /** | ||
124 | * @param $callback | ||
125 | * Callback function to be applied to each result. | ||
126 | * | ||
127 | * Can be specified as 'my_callback_function' | ||
128 | * or array($object, 'my_callback_method'). | ||
129 | * | ||
130 | * Function should take three parameters: $response, $info, $request. | ||
131 | * $response is response body, $info is additional curl info. | ||
132 | * $request is the original request | ||
133 | * | ||
134 | * @return void | ||
135 | */ | ||
136 | function __construct($callback = null) { | ||
137 | $this->callback = $callback; | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * @param string $name | ||
142 | * @return mixed | ||
143 | */ | ||
144 | public function __get($name) { | ||
145 | return (isset($this->{$name})) ? $this->{$name} : null; | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * @param string $name | ||
150 | * @param mixed $value | ||
151 | * @return bool | ||
152 | */ | ||
153 | public function __set($name, $value) { | ||
154 | // append the base options & headers | ||
155 | if ($name == "options" || $name == "headers") { | ||
156 | $this->{$name} = $value + $this->{$name}; | ||
157 | } else { | ||
158 | $this->{$name} = $value; | ||
159 | } | ||
160 | return true; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Count number of requests added (Countable interface) | ||
165 | * | ||
166 | * @return int | ||
167 | */ | ||
168 | public function count() { | ||
169 | return count($this->requests); | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * Add a request to the request queue | ||
174 | * | ||
175 | * @param Request $request | ||
176 | * @return bool | ||
177 | */ | ||
178 | public function add($request) { | ||
179 | $this->requests[] = $request; | ||
180 | return true; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * Create new Request and add it to the request queue | ||
185 | * | ||
186 | * @param string $url | ||
187 | * @param string $method | ||
188 | * @param $post_data | ||
189 | * @param $headers | ||
190 | * @param $options | ||
191 | * @return bool | ||
192 | */ | ||
193 | public function request($url, $method = "GET", $post_data = null, $headers = null, $options = null) { | ||
194 | $this->requests[] = new RollingCurlRequest($url, $method, $post_data, $headers, $options); | ||
195 | return true; | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * Perform GET request | ||
200 | * | ||
201 | * @param string $url | ||
202 | * @param $headers | ||
203 | * @param $options | ||
204 | * @return bool | ||
205 | */ | ||
206 | public function get($url, $headers = null, $options = null) { | ||
207 | return $this->request($url, "GET", null, $headers, $options); | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * Perform POST request | ||
212 | * | ||
213 | * @param string $url | ||
214 | * @param $post_data | ||
215 | * @param $headers | ||
216 | * @param $options | ||
217 | * @return bool | ||
218 | */ | ||
219 | public function post($url, $post_data = null, $headers = null, $options = null) { | ||
220 | return $this->request($url, "POST", $post_data, $headers, $options); | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * Execute processing | ||
225 | * | ||
226 | * @param int $window_size Max number of simultaneous connections | ||
227 | * @return string|bool | ||
228 | */ | ||
229 | public function execute($window_size = null) { | ||
230 | // rolling curl window must always be greater than 1 | ||
231 | if (sizeof($this->requests) == 1) { | ||
232 | return $this->single_curl(); | ||
233 | } else { | ||
234 | // start the rolling curl. window_size is the max number of simultaneous connections | ||
235 | return $this->rolling_curl($window_size); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * Performs a single curl request | ||
241 | * | ||
242 | * @access private | ||
243 | * @return string | ||
244 | */ | ||
245 | private function single_curl() { | ||
246 | $ch = curl_init(); | ||
247 | $request = array_shift($this->requests); | ||
248 | $options = $this->get_options($request); | ||
249 | curl_setopt_array($ch, $options); | ||
250 | $output = curl_exec($ch); | ||
251 | $info = curl_getinfo($ch); | ||
252 | |||
253 | // it's not neccesary to set a callback for one-off requests | ||
254 | if ($this->callback) { | ||
255 | $callback = $this->callback; | ||
256 | if (is_callable($this->callback)) { | ||
257 | call_user_func($callback, $output, $info, $request); | ||
258 | } | ||
259 | } | ||
260 | else | ||
261 | return $output; | ||
262 | return true; | ||
263 | } | ||
264 | |||
265 | /** | ||
266 | * Performs multiple curl requests | ||
267 | * | ||
268 | * @access private | ||
269 | * @throws RollingCurlException | ||
270 | * @param int $window_size Max number of simultaneous connections | ||
271 | * @return bool | ||
272 | */ | ||
273 | private function rolling_curl($window_size = null) { | ||
274 | if ($window_size) | ||
275 | $this->window_size = $window_size; | ||
276 | |||
277 | // make sure the rolling window isn't greater than the # of urls | ||
278 | if (sizeof($this->requests) < $this->window_size) | ||
279 | $this->window_size = sizeof($this->requests); | ||
280 | |||
281 | if ($this->window_size < 2) { | ||
282 | throw new RollingCurlException("Window size must be greater than 1"); | ||
283 | } | ||
284 | |||
285 | $master = curl_multi_init(); | ||
286 | |||
287 | // start the first batch of requests | ||
288 | for ($i = 0; $i < $this->window_size; $i++) { | ||
289 | $ch = curl_init(); | ||
290 | |||
291 | $options = $this->get_options($this->requests[$i]); | ||
292 | |||
293 | curl_setopt_array($ch, $options); | ||
294 | curl_multi_add_handle($master, $ch); | ||
295 | |||
296 | // Add to our request Maps | ||
297 | $key = (string) $ch; | ||
298 | $this->requestMap[$key] = $i; | ||
299 | } | ||
300 | |||
301 | do { | ||
302 | while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM) ; | ||
303 | if ($execrun != CURLM_OK) | ||
304 | break; | ||
305 | // a request was just completed -- find out which one | ||
306 | while ($done = curl_multi_info_read($master)) { | ||
307 | |||
308 | // get the info and content returned on the request | ||
309 | $info = curl_getinfo($done['handle']); | ||
310 | $output = curl_multi_getcontent($done['handle']); | ||
311 | |||
312 | // send the return values to the callback function. | ||
313 | $callback = $this->callback; | ||
314 | if (is_callable($callback)) { | ||
315 | $key = (string) $done['handle']; | ||
316 | $request = $this->requests[$this->requestMap[$key]]; | ||
317 | unset($this->requestMap[$key]); | ||
318 | call_user_func($callback, $output, $info, $request); | ||
319 | } | ||
320 | |||
321 | // start a new request (it's important to do this before removing the old one) | ||
322 | if ($i < sizeof($this->requests) && isset($this->requests[$i]) && $i < count($this->requests)) { | ||
323 | $ch = curl_init(); | ||
324 | $options = $this->get_options($this->requests[$i]); | ||
325 | curl_setopt_array($ch, $options); | ||
326 | curl_multi_add_handle($master, $ch); | ||
327 | |||
328 | // Add to our request Maps | ||
329 | $key = (string) $ch; | ||
330 | $this->requestMap[$key] = $i; | ||
331 | $i++; | ||
332 | } | ||
333 | |||
334 | // remove the curl handle that just completed | ||
335 | curl_multi_remove_handle($master, $done['handle']); | ||
336 | |||
337 | } | ||
338 | |||
339 | // Block for data in / output; error handling is done by curl_multi_exec | ||
340 | //if ($running) curl_multi_select($master, $this->timeout); | ||
341 | // removing timeout as it causes problems on Windows with PHP 5.3.5 and Curl 7.20.0 | ||
342 | if ($running) curl_multi_select($master); | ||
343 | |||
344 | } while ($running); | ||
345 | curl_multi_close($master); | ||
346 | return true; | ||
347 | } | ||
348 | |||
349 | |||
350 | /** | ||
351 | * Helper function to set up a new request by setting the appropriate options | ||
352 | * | ||
353 | * @access private | ||
354 | * @param Request $request | ||
355 | * @return array | ||
356 | */ | ||
357 | private function get_options($request) { | ||
358 | // options for this entire curl object | ||
359 | $options = $this->__get('options'); | ||
360 | // We're managing reirects in PHP - allows us to intervene and rewrite/block URLs | ||
361 | // before the next request goes out. | ||
362 | $options[CURLOPT_FOLLOWLOCATION] = 0; | ||
363 | $options[CURLOPT_MAXREDIRS] = 0; | ||
364 | //if (ini_get('safe_mode') == 'Off' || !ini_get('safe_mode')) { | ||
365 | // $options[CURLOPT_FOLLOWLOCATION] = 1; | ||
366 | // $options[CURLOPT_MAXREDIRS] = 5; | ||
367 | //} | ||
368 | $headers = $this->__get('headers'); | ||
369 | // append custom headers for this specific request | ||
370 | if ($request->headers) { | ||
371 | $headers = $headers + $request->headers; | ||
372 | } | ||
373 | |||
374 | // append custom options for this specific request | ||
375 | if ($request->options) { | ||
376 | $options = $request->options + $options; | ||
377 | } | ||
378 | |||
379 | // set the request URL | ||
380 | $options[CURLOPT_URL] = $request->url; | ||
381 | |||
382 | if ($headers) { | ||
383 | $options[CURLOPT_HTTPHEADER] = $headers; | ||
384 | } | ||
385 | // return response headers | ||
386 | $options[CURLOPT_HEADER] = 1; | ||
387 | |||
388 | // send HEAD request? | ||
389 | if ($request->method == 'HEAD') { | ||
390 | $options[CURLOPT_NOBODY] = 1; | ||
391 | } | ||
392 | |||
393 | return $options; | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * @return void | ||
398 | */ | ||
399 | public function __destruct() { | ||
400 | unset($this->window_size, $this->callback, $this->options, $this->headers, $this->requests); | ||
401 | } | ||
402 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/humble-http-agent/SimplePie_HumbleHttpAgent.php b/inc/3rdparty/libraries/humble-http-agent/SimplePie_HumbleHttpAgent.php deleted file mode 100644 index c524a1ee..00000000 --- a/inc/3rdparty/libraries/humble-http-agent/SimplePie_HumbleHttpAgent.php +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Humble HTTP Agent extension for SimplePie_File | ||
4 | * | ||
5 | * This class is designed to extend and override SimplePie_File | ||
6 | * in order to prevent duplicate HTTP requests being sent out. | ||
7 | * The idea is to initialise an instance of Humble HTTP Agent | ||
8 | * and attach it, to a static class variable, of this class. | ||
9 | * SimplePie will then automatically initialise this class | ||
10 | * | ||
11 | * @date 2011-02-28 | ||
12 | */ | ||
13 | |||
14 | class SimplePie_HumbleHttpAgent extends SimplePie_File | ||
15 | { | ||
16 | protected static $agent; | ||
17 | var $url; | ||
18 | var $useragent; | ||
19 | var $success = true; | ||
20 | var $headers = array(); | ||
21 | var $body; | ||
22 | var $status_code; | ||
23 | var $redirects = 0; | ||
24 | var $error; | ||
25 | var $method = SIMPLEPIE_FILE_SOURCE_NONE; | ||
26 | |||
27 | public static function set_agent(HumbleHttpAgent $agent) { | ||
28 | self::$agent = $agent; | ||
29 | } | ||
30 | |||
31 | public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) { | ||
32 | if (class_exists('idna_convert')) | ||
33 | { | ||
34 | $idn = new idna_convert(); | ||
35 | $parsed = SimplePie_Misc::parse_url($url); | ||
36 | $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); | ||
37 | } | ||
38 | $this->url = $url; | ||
39 | $this->useragent = $useragent; | ||
40 | if (preg_match('/^http(s)?:\/\//i', $url)) | ||
41 | { | ||
42 | if (!is_array($headers)) | ||
43 | { | ||
44 | $headers = array(); | ||
45 | } | ||
46 | $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; | ||
47 | $headers2 = array(); | ||
48 | foreach ($headers as $key => $value) { | ||
49 | $headers2[] = "$key: $value"; | ||
50 | } | ||
51 | //TODO: allow for HTTP headers | ||
52 | // curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); | ||
53 | |||
54 | $response = self::$agent->get($url); | ||
55 | |||
56 | if ($response === false || !isset($response['status_code'])) { | ||
57 | $this->error = 'failed to fetch URL'; | ||
58 | $this->success = false; | ||
59 | } else { | ||
60 | // The extra lines at the end are there to satisfy SimplePie's HTTP parser. | ||
61 | // The class expects a full HTTP message, whereas we're giving it only | ||
62 | // headers - the new lines indicate the start of the body. | ||
63 | $parser = new SimplePie_HTTP_Parser($response['headers']."\r\n\r\n"); | ||
64 | if ($parser->parse()) { | ||
65 | $this->headers = $parser->headers; | ||
66 | //$this->body = $parser->body; | ||
67 | $this->body = $response['body']; | ||
68 | $this->status_code = $parser->status_code; | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | else | ||
73 | { | ||
74 | $this->error = 'invalid URL'; | ||
75 | $this->success = false; | ||
76 | } | ||
77 | } | ||
78 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/language-detect/LanguageDetect.php b/inc/3rdparty/libraries/language-detect/LanguageDetect.php deleted file mode 100644 index 382d869c..00000000 --- a/inc/3rdparty/libraries/language-detect/LanguageDetect.php +++ /dev/null | |||
@@ -1,1693 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Detects the language of a given piece of text. | ||
5 | * | ||
6 | * Attempts to detect the language of a sample of text by correlating ranked | ||
7 | * 3-gram frequencies to a table of 3-gram frequencies of known languages. | ||
8 | * | ||
9 | * Implements a version of a technique originally proposed by Cavnar & Trenkle | ||
10 | * (1994): "N-Gram-Based Text Categorization" | ||
11 | * | ||
12 | * PHP version 5 | ||
13 | * | ||
14 | * @category Text | ||
15 | * @package Text_LanguageDetect | ||
16 | * @author Nicholas Pisarro <infinityminusnine+pear@gmail.com> | ||
17 | * @copyright 2005-2006 Nicholas Pisarro | ||
18 | * @license http://www.debian.org/misc/bsd.license BSD | ||
19 | * @version SVN: $Id: LanguageDetect.php 322353 2012-01-16 08:41:43Z cweiske $ | ||
20 | * @link http://pear.php.net/package/Text_LanguageDetect/ | ||
21 | * @link http://langdetect.blogspot.com/ | ||
22 | */ | ||
23 | |||
24 | require_once 'LanguageDetect/Exception.php'; | ||
25 | require_once 'LanguageDetect/Parser.php'; | ||
26 | require_once 'LanguageDetect/ISO639.php'; | ||
27 | |||
28 | /** | ||
29 | * Language detection class | ||
30 | * | ||
31 | * Requires the langauge model database (lang.dat) that should have | ||
32 | * accompanied this class definition in order to be instantiated. | ||
33 | * | ||
34 | * Example usage: | ||
35 | * | ||
36 | * <code> | ||
37 | * require_once 'Text/LanguageDetect.php'; | ||
38 | * | ||
39 | * $l = new Text_LanguageDetect; | ||
40 | * | ||
41 | * $stdin = fopen('php://stdin', 'r'); | ||
42 | * | ||
43 | * echo "Supported languages:\n"; | ||
44 | * | ||
45 | * try { | ||
46 | * $langs = $l->getLanguages(); | ||
47 | * } catch (Text_LanguageDetect_Exception $e) { | ||
48 | * die($e->getMessage()); | ||
49 | * } | ||
50 | * | ||
51 | * sort($langs); | ||
52 | * echo join(', ', $langs); | ||
53 | * | ||
54 | * while ($line = fgets($stdin)) { | ||
55 | * print_r($l->detect($line, 4)); | ||
56 | * } | ||
57 | * </code> | ||
58 | * | ||
59 | * @category Text | ||
60 | * @package Text_LanguageDetect | ||
61 | * @author Nicholas Pisarro <infinityminusnine+pear@gmail.com> | ||
62 | * @copyright 2005 Nicholas Pisarro | ||
63 | * @license http://www.debian.org/misc/bsd.license BSD | ||
64 | * @version Release: @package_version@ | ||
65 | * @link http://pear.php.net/package/Text_LanguageDetect/ | ||
66 | * @todo allow users to generate their own language models | ||
67 | */ | ||
68 | class Text_LanguageDetect | ||
69 | { | ||
70 | /** | ||
71 | * The filename that stores the trigram data for the detector | ||
72 | * | ||
73 | * If this value starts with a slash (/) or a dot (.) the value of | ||
74 | * $this->_data_dir will be ignored | ||
75 | * | ||
76 | * @var string | ||
77 | * @access private | ||
78 | */ | ||
79 | var $_db_filename = 'lang.dat'; | ||
80 | |||
81 | /** | ||
82 | * The filename that stores the unicode block definitions | ||
83 | * | ||
84 | * If this value starts with a slash (/) or a dot (.) the value of | ||
85 | * $this->_data_dir will be ignored | ||
86 | * | ||
87 | * @var string | ||
88 | * @access private | ||
89 | */ | ||
90 | var $_unicode_db_filename = 'unicode_blocks.dat'; | ||
91 | |||
92 | /** | ||
93 | * The data directory | ||
94 | * | ||
95 | * Should be set by PEAR installer | ||
96 | * | ||
97 | * @var string | ||
98 | * @access private | ||
99 | */ | ||
100 | var $_data_dir = '@data_dir@'; | ||
101 | |||
102 | /** | ||
103 | * The trigram data for comparison | ||
104 | * | ||
105 | * Will be loaded on start from $this->_db_filename | ||
106 | * | ||
107 | * @var array | ||
108 | * @access private | ||
109 | */ | ||
110 | var $_lang_db = array(); | ||
111 | |||
112 | /** | ||
113 | * stores the map of the trigram data to unicode characters | ||
114 | * | ||
115 | * @access private | ||
116 | * @var array | ||
117 | */ | ||
118 | var $_unicode_map; | ||
119 | |||
120 | /** | ||
121 | * The size of the trigram data arrays | ||
122 | * | ||
123 | * @var int | ||
124 | * @access private | ||
125 | */ | ||
126 | var $_threshold = 300; | ||
127 | |||
128 | /** | ||
129 | * the maximum possible score. | ||
130 | * | ||
131 | * needed for score normalization. Different depending on the | ||
132 | * perl compatibility setting | ||
133 | * | ||
134 | * @access private | ||
135 | * @var int | ||
136 | * @see setPerlCompatible() | ||
137 | */ | ||
138 | var $_max_score = 0; | ||
139 | |||
140 | /** | ||
141 | * Whether or not to simulate perl's Language::Guess exactly | ||
142 | * | ||
143 | * @access private | ||
144 | * @var bool | ||
145 | * @see setPerlCompatible() | ||
146 | */ | ||
147 | var $_perl_compatible = false; | ||
148 | |||
149 | /** | ||
150 | * Whether to use the unicode block detection to speed up processing | ||
151 | * | ||
152 | * @access private | ||
153 | * @var bool | ||
154 | */ | ||
155 | var $_use_unicode_narrowing = true; | ||
156 | |||
157 | /** | ||
158 | * stores the result of the clustering operation | ||
159 | * | ||
160 | * @access private | ||
161 | * @var array | ||
162 | * @see clusterLanguages() | ||
163 | */ | ||
164 | var $_clusters; | ||
165 | |||
166 | /** | ||
167 | * Which type of "language names" are accepted and returned: | ||
168 | * | ||
169 | * 0 - language name ("english") | ||
170 | * 2 - 2-letter ISO 639-1 code ("en") | ||
171 | * 3 - 3-letter ISO 639-2 code ("eng") | ||
172 | */ | ||
173 | var $_name_mode = 0; | ||
174 | |||
175 | /** | ||
176 | * Constructor | ||
177 | * | ||
178 | * Will attempt to load the language database. If it fails, you will get | ||
179 | * an exception. | ||
180 | */ | ||
181 | function __construct() | ||
182 | { | ||
183 | $data = $this->_readdb($this->_db_filename); | ||
184 | $this->_checkTrigram($data['trigram']); | ||
185 | $this->_lang_db = $data['trigram']; | ||
186 | |||
187 | if (isset($data['trigram-unicodemap'])) { | ||
188 | $this->_unicode_map = $data['trigram-unicodemap']; | ||
189 | } | ||
190 | |||
191 | // Not yet implemented: | ||
192 | if (isset($data['trigram-clusters'])) { | ||
193 | $this->_clusters = $data['trigram-clusters']; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Returns the path to the location of the database | ||
199 | * | ||
200 | * @param string $fname File name to load | ||
201 | * | ||
202 | * @return string expected path to the language model database | ||
203 | * @access private | ||
204 | */ | ||
205 | function _get_data_loc($fname) | ||
206 | { | ||
207 | return dirname(__FILE__).'/'.$fname; | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * Loads the language trigram database from filename | ||
212 | * | ||
213 | * Trigram datbase should be a serialize()'d array | ||
214 | * | ||
215 | * @param string $fname the filename where the data is stored | ||
216 | * | ||
217 | * @return array the language model data | ||
218 | * @throws Text_LanguageDetect_Exception | ||
219 | * @access private | ||
220 | */ | ||
221 | function _readdb($fname) | ||
222 | { | ||
223 | // finds the correct data dir | ||
224 | $fname = $this->_get_data_loc($fname); | ||
225 | |||
226 | // input check | ||
227 | if (!file_exists($fname)) { | ||
228 | throw new Text_LanguageDetect_Exception( | ||
229 | 'Language database does not exist: ' . $fname, | ||
230 | Text_LanguageDetect_Exception::DB_NOT_FOUND | ||
231 | ); | ||
232 | } elseif (!is_readable($fname)) { | ||
233 | throw new Text_LanguageDetect_Exception( | ||
234 | 'Language database is not readable: ' . $fname, | ||
235 | Text_LanguageDetect_Exception::DB_NOT_READABLE | ||
236 | ); | ||
237 | } | ||
238 | |||
239 | return unserialize(file_get_contents($fname)); | ||
240 | } | ||
241 | |||
242 | |||
243 | /** | ||
244 | * Checks if this object is ready to detect languages | ||
245 | * | ||
246 | * @param array $trigram Trigram data from database | ||
247 | * | ||
248 | * @return void | ||
249 | * @access private | ||
250 | */ | ||
251 | function _checkTrigram($trigram) | ||
252 | { | ||
253 | if (!is_array($trigram)) { | ||
254 | if (ini_get('magic_quotes_runtime')) { | ||
255 | throw new Text_LanguageDetect_Exception( | ||
256 | 'Error loading database. Try turning magic_quotes_runtime off.', | ||
257 | Text_LanguageDetect_Exception::MAGIC_QUOTES | ||
258 | ); | ||
259 | } | ||
260 | throw new Text_LanguageDetect_Exception( | ||
261 | 'Language database is not an array.', | ||
262 | Text_LanguageDetect_Exception::DB_NOT_ARRAY | ||
263 | ); | ||
264 | } elseif (empty($trigram)) { | ||
265 | throw new Text_LanguageDetect_Exception( | ||
266 | 'Language database has no elements.', | ||
267 | Text_LanguageDetect_Exception::DB_EMPTY | ||
268 | ); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Omits languages | ||
274 | * | ||
275 | * Pass this function the name of or an array of names of | ||
276 | * languages that you don't want considered | ||
277 | * | ||
278 | * If you're only expecting a limited set of languages, this can greatly | ||
279 | * speed up processing | ||
280 | * | ||
281 | * @param mixed $omit_list language name or array of names to omit | ||
282 | * @param bool $include_only if true will include (rather than | ||
283 | * exclude) only those in the list | ||
284 | * | ||
285 | * @return int number of languages successfully deleted | ||
286 | * @throws Text_LanguageDetect_Exception | ||
287 | */ | ||
288 | public function omitLanguages($omit_list, $include_only = false) | ||
289 | { | ||
290 | $deleted = 0; | ||
291 | |||
292 | $omit_list = $this->_convertFromNameMode($omit_list); | ||
293 | |||
294 | if (!$include_only) { | ||
295 | // deleting the given languages | ||
296 | if (!is_array($omit_list)) { | ||
297 | $omit_list = strtolower($omit_list); // case desensitize | ||
298 | if (isset($this->_lang_db[$omit_list])) { | ||
299 | unset($this->_lang_db[$omit_list]); | ||
300 | $deleted++; | ||
301 | } | ||
302 | } else { | ||
303 | foreach ($omit_list as $omit_lang) { | ||
304 | if (isset($this->_lang_db[$omit_lang])) { | ||
305 | unset($this->_lang_db[$omit_lang]); | ||
306 | $deleted++; | ||
307 | } | ||
308 | } | ||
309 | } | ||
310 | |||
311 | } else { | ||
312 | // deleting all except the given languages | ||
313 | if (!is_array($omit_list)) { | ||
314 | $omit_list = array($omit_list); | ||
315 | } | ||
316 | |||
317 | // case desensitize | ||
318 | foreach ($omit_list as $key => $omit_lang) { | ||
319 | $omit_list[$key] = strtolower($omit_lang); | ||
320 | } | ||
321 | |||
322 | foreach (array_keys($this->_lang_db) as $lang) { | ||
323 | if (!in_array($lang, $omit_list)) { | ||
324 | unset($this->_lang_db[$lang]); | ||
325 | $deleted++; | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | |||
330 | // reset the cluster cache if the number of languages changes | ||
331 | // this will then have to be recalculated | ||
332 | if (isset($this->_clusters) && $deleted > 0) { | ||
333 | $this->_clusters = null; | ||
334 | } | ||
335 | |||
336 | return $deleted; | ||
337 | } | ||
338 | |||
339 | |||
340 | /** | ||
341 | * Returns the number of languages that this object can detect | ||
342 | * | ||
343 | * @access public | ||
344 | * @return int the number of languages | ||
345 | * @throws Text_LanguageDetect_Exception | ||
346 | */ | ||
347 | function getLanguageCount() | ||
348 | { | ||
349 | return count($this->_lang_db); | ||
350 | } | ||
351 | |||
352 | /** | ||
353 | * Checks if the language with the given name exists in the database | ||
354 | * | ||
355 | * @param mixed $lang Language name or array of language names | ||
356 | * | ||
357 | * @return bool true if language model exists | ||
358 | */ | ||
359 | public function languageExists($lang) | ||
360 | { | ||
361 | $lang = $this->_convertFromNameMode($lang); | ||
362 | |||
363 | if (is_string($lang)) { | ||
364 | return isset($this->_lang_db[strtolower($lang)]); | ||
365 | |||
366 | } elseif (is_array($lang)) { | ||
367 | foreach ($lang as $test_lang) { | ||
368 | if (!isset($this->_lang_db[strtolower($test_lang)])) { | ||
369 | return false; | ||
370 | } | ||
371 | } | ||
372 | return true; | ||
373 | |||
374 | } else { | ||
375 | throw new Text_LanguageDetect_Exception( | ||
376 | 'Unsupported parameter type passed to languageExists()', | ||
377 | Text_LanguageDetect_Exception::PARAM_TYPE | ||
378 | ); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * Returns the list of detectable languages | ||
384 | * | ||
385 | * @access public | ||
386 | * @return array the names of the languages known to this object<<<<<<< | ||
387 | * @throws Text_LanguageDetect_Exception | ||
388 | */ | ||
389 | function getLanguages() | ||
390 | { | ||
391 | return $this->_convertToNameMode( | ||
392 | array_keys($this->_lang_db) | ||
393 | ); | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * Make this object behave like Language::Guess | ||
398 | * | ||
399 | * @param bool $setting false to turn off perl compatibility | ||
400 | * | ||
401 | * @return void | ||
402 | */ | ||
403 | public function setPerlCompatible($setting = true) | ||
404 | { | ||
405 | if (is_bool($setting)) { // input check | ||
406 | $this->_perl_compatible = $setting; | ||
407 | |||
408 | if ($setting == true) { | ||
409 | $this->_max_score = $this->_threshold; | ||
410 | } else { | ||
411 | $this->_max_score = 0; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | } | ||
416 | |||
417 | /** | ||
418 | * Sets the way how language names are accepted and returned. | ||
419 | * | ||
420 | * @param integer $name_mode One of the following modes: | ||
421 | * 0 - language name ("english") | ||
422 | * 2 - 2-letter ISO 639-1 code ("en") | ||
423 | * 3 - 3-letter ISO 639-2 code ("eng") | ||
424 | * | ||
425 | * @return void | ||
426 | */ | ||
427 | function setNameMode($name_mode) | ||
428 | { | ||
429 | $this->_name_mode = $name_mode; | ||
430 | } | ||
431 | |||
432 | /** | ||
433 | * Whether to use unicode block ranges in detection | ||
434 | * | ||
435 | * Should speed up most detections if turned on (detault is on). In some | ||
436 | * circumstances it may be slower, such as for large text samples (> 10K) | ||
437 | * in languages that use latin scripts. In other cases it should speed up | ||
438 | * detection noticeably. | ||
439 | * | ||
440 | * @param bool $setting false to turn off | ||
441 | * | ||
442 | * @return void | ||
443 | */ | ||
444 | public function useUnicodeBlocks($setting = true) | ||
445 | { | ||
446 | if (is_bool($setting)) { | ||
447 | $this->_use_unicode_narrowing = $setting; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | /** | ||
452 | * Converts a piece of text into trigrams | ||
453 | * | ||
454 | * @param string $text text to convert | ||
455 | * | ||
456 | * @return array array of trigram frequencies | ||
457 | * @access private | ||
458 | * @deprecated Superceded by the Text_LanguageDetect_Parser class | ||
459 | */ | ||
460 | function _trigram($text) | ||
461 | { | ||
462 | $s = new Text_LanguageDetect_Parser($text); | ||
463 | $s->prepareTrigram(); | ||
464 | $s->prepareUnicode(false); | ||
465 | $s->setPadStart(!$this->_perl_compatible); | ||
466 | $s->analyze(); | ||
467 | return $s->getTrigramFreqs(); | ||
468 | } | ||
469 | |||
470 | /** | ||
471 | * Converts a set of trigrams from frequencies to ranks | ||
472 | * | ||
473 | * Thresholds (cuts off) the list at $this->_threshold | ||
474 | * | ||
475 | * @param array $arr array of trigram | ||
476 | * | ||
477 | * @return array ranks of trigrams | ||
478 | * @access protected | ||
479 | */ | ||
480 | function _arr_rank($arr) | ||
481 | { | ||
482 | |||
483 | // sorts alphabetically first as a standard way of breaking rank ties | ||
484 | $this->_bub_sort($arr); | ||
485 | |||
486 | // below might also work, but seemed to introduce errors in testing | ||
487 | //ksort($arr); | ||
488 | //asort($arr); | ||
489 | |||
490 | $rank = array(); | ||
491 | |||
492 | $i = 0; | ||
493 | foreach ($arr as $key => $value) { | ||
494 | $rank[$key] = $i++; | ||
495 | |||
496 | // cut off at a standard threshold | ||
497 | if ($i >= $this->_threshold) { | ||
498 | break; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | return $rank; | ||
503 | } | ||
504 | |||
505 | /** | ||
506 | * Sorts an array by value breaking ties alphabetically | ||
507 | * | ||
508 | * @param array &$arr the array to sort | ||
509 | * | ||
510 | * @return void | ||
511 | * @access private | ||
512 | */ | ||
513 | function _bub_sort(&$arr) | ||
514 | { | ||
515 | // should do the same as this perl statement: | ||
516 | // sort { $trigrams{$b} == $trigrams{$a} | ||
517 | // ? $a cmp $b : $trigrams{$b} <=> $trigrams{$a} } | ||
518 | |||
519 | // needs to sort by both key and value at once | ||
520 | // using the key to break ties for the value | ||
521 | |||
522 | // converts array into an array of arrays of each key and value | ||
523 | // may be a better way of doing this | ||
524 | $combined = array(); | ||
525 | |||
526 | foreach ($arr as $key => $value) { | ||
527 | $combined[] = array($key, $value); | ||
528 | } | ||
529 | |||
530 | usort($combined, array($this, '_sort_func')); | ||
531 | |||
532 | $replacement = array(); | ||
533 | foreach ($combined as $key => $value) { | ||
534 | list($new_key, $new_value) = $value; | ||
535 | $replacement[$new_key] = $new_value; | ||
536 | } | ||
537 | |||
538 | $arr = $replacement; | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * Sort function used by bubble sort | ||
543 | * | ||
544 | * Callback function for usort(). | ||
545 | * | ||
546 | * @param array $a first param passed by usort() | ||
547 | * @param array $b second param passed by usort() | ||
548 | * | ||
549 | * @return int 1 if $a is greater, -1 if not | ||
550 | * @see _bub_sort() | ||
551 | * @access private | ||
552 | */ | ||
553 | function _sort_func($a, $b) | ||
554 | { | ||
555 | // each is actually a key/value pair, so that it can compare using both | ||
556 | list($a_key, $a_value) = $a; | ||
557 | list($b_key, $b_value) = $b; | ||
558 | |||
559 | if ($a_value == $b_value) { | ||
560 | // if the values are the same, break ties using the key | ||
561 | return strcmp($a_key, $b_key); | ||
562 | |||
563 | } else { | ||
564 | // if not, just sort normally | ||
565 | if ($a_value > $b_value) { | ||
566 | return -1; | ||
567 | } else { | ||
568 | return 1; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | // 0 should not be possible because keys must be unique | ||
573 | } | ||
574 | |||
575 | /** | ||
576 | * Calculates a linear rank-order distance statistic between two sets of | ||
577 | * ranked trigrams | ||
578 | * | ||
579 | * Sums the differences in rank for each trigram. If the trigram does not | ||
580 | * appear in both, consider it a difference of $this->_threshold. | ||
581 | * | ||
582 | * This distance measure was proposed by Cavnar & Trenkle (1994). Despite | ||
583 | * its simplicity it has been shown to be highly accurate for language | ||
584 | * identification tasks. | ||
585 | * | ||
586 | * @param array $arr1 the reference set of trigram ranks | ||
587 | * @param array $arr2 the target set of trigram ranks | ||
588 | * | ||
589 | * @return int the sum of the differences between the ranks of | ||
590 | * the two trigram sets | ||
591 | * @access private | ||
592 | */ | ||
593 | function _distance($arr1, $arr2) | ||
594 | { | ||
595 | $sumdist = 0; | ||
596 | |||
597 | foreach ($arr2 as $key => $value) { | ||
598 | if (isset($arr1[$key])) { | ||
599 | $distance = abs($value - $arr1[$key]); | ||
600 | } else { | ||
601 | // $this->_threshold sets the maximum possible distance value | ||
602 | // for any one pair of trigrams | ||
603 | $distance = $this->_threshold; | ||
604 | } | ||
605 | $sumdist += $distance; | ||
606 | } | ||
607 | |||
608 | return $sumdist; | ||
609 | |||
610 | // todo: there are other distance statistics to try, e.g. relative | ||
611 | // entropy, but they're probably more costly to compute | ||
612 | } | ||
613 | |||
614 | /** | ||
615 | * Normalizes the score returned by _distance() | ||
616 | * | ||
617 | * Different if perl compatible or not | ||
618 | * | ||
619 | * @param int $score the score from _distance() | ||
620 | * @param int $base_count the number of trigrams being considered | ||
621 | * | ||
622 | * @return float the normalized score | ||
623 | * @see _distance() | ||
624 | * @access private | ||
625 | */ | ||
626 | function _normalize_score($score, $base_count = null) | ||
627 | { | ||
628 | if ($base_count === null) { | ||
629 | $base_count = $this->_threshold; | ||
630 | } | ||
631 | |||
632 | if (!$this->_perl_compatible) { | ||
633 | return 1 - ($score / $base_count / $this->_threshold); | ||
634 | } else { | ||
635 | return floor($score / $base_count); | ||
636 | } | ||
637 | } | ||
638 | |||
639 | |||
640 | /** | ||
641 | * Detects the closeness of a sample of text to the known languages | ||
642 | * | ||
643 | * Calculates the statistical difference between the text and | ||
644 | * the trigrams for each language, normalizes the score then | ||
645 | * returns results for all languages in sorted order | ||
646 | * | ||
647 | * If perl compatible, the score is 300-0, 0 being most similar. | ||
648 | * Otherwise, it's 0-1 with 1 being most similar. | ||
649 | * | ||
650 | * The $sample text should be at least a few sentences in length; | ||
651 | * should be ascii-7 or utf8 encoded, if another and the mbstring extension | ||
652 | * is present it will try to detect and convert. However, experience has | ||
653 | * shown that mb_detect_encoding() *does not work very well* with at least | ||
654 | * some types of encoding. | ||
655 | * | ||
656 | * @param string $sample a sample of text to compare. | ||
657 | * @param int $limit if specified, return an array of the most likely | ||
658 | * $limit languages and their scores. | ||
659 | * | ||
660 | * @return mixed sorted array of language scores, blank array if no | ||
661 | * useable text was found | ||
662 | * @see _distance() | ||
663 | * @throws Text_LanguageDetect_Exception | ||
664 | */ | ||
665 | public function detect($sample, $limit = 0) | ||
666 | { | ||
667 | // input check | ||
668 | if (!Text_LanguageDetect_Parser::validateString($sample)) { | ||
669 | return array(); | ||
670 | } | ||
671 | |||
672 | // check char encoding | ||
673 | // (only if mbstring extension is compiled and PHP > 4.0.6) | ||
674 | if (function_exists('mb_detect_encoding') | ||
675 | && function_exists('mb_convert_encoding') | ||
676 | ) { | ||
677 | // mb_detect_encoding isn't very reliable, to say the least | ||
678 | // detection should still work with a sufficient sample | ||
679 | // of ascii characters | ||
680 | $encoding = mb_detect_encoding($sample); | ||
681 | |||
682 | // mb_detect_encoding() will return FALSE if detection fails | ||
683 | // don't attempt conversion if that's the case | ||
684 | if ($encoding != 'ASCII' && $encoding != 'UTF-8' | ||
685 | && $encoding !== false | ||
686 | ) { | ||
687 | // verify the encoding exists in mb_list_encodings | ||
688 | if (in_array($encoding, mb_list_encodings())) { | ||
689 | $sample = mb_convert_encoding($sample, 'UTF-8', $encoding); | ||
690 | } | ||
691 | } | ||
692 | } | ||
693 | |||
694 | $sample_obj = new Text_LanguageDetect_Parser($sample); | ||
695 | $sample_obj->prepareTrigram(); | ||
696 | if ($this->_use_unicode_narrowing) { | ||
697 | $sample_obj->prepareUnicode(); | ||
698 | } | ||
699 | $sample_obj->setPadStart(!$this->_perl_compatible); | ||
700 | $sample_obj->analyze(); | ||
701 | |||
702 | $trigram_freqs =& $sample_obj->getTrigramRanks(); | ||
703 | $trigram_count = count($trigram_freqs); | ||
704 | |||
705 | if ($trigram_count == 0) { | ||
706 | return array(); | ||
707 | } | ||
708 | |||
709 | $scores = array(); | ||
710 | |||
711 | // use unicode block detection to narrow down the possibilities | ||
712 | if ($this->_use_unicode_narrowing) { | ||
713 | $blocks =& $sample_obj->getUnicodeBlocks(); | ||
714 | |||
715 | if (is_array($blocks)) { | ||
716 | $present_blocks = array_keys($blocks); | ||
717 | } else { | ||
718 | throw new Text_LanguageDetect_Exception( | ||
719 | 'Error during block detection', | ||
720 | Text_LanguageDetect_Exception::BLOCK_DETECTION | ||
721 | ); | ||
722 | } | ||
723 | |||
724 | $possible_langs = array(); | ||
725 | |||
726 | foreach ($present_blocks as $blockname) { | ||
727 | if (isset($this->_unicode_map[$blockname])) { | ||
728 | |||
729 | $possible_langs = array_merge( | ||
730 | $possible_langs, | ||
731 | array_keys($this->_unicode_map[$blockname]) | ||
732 | ); | ||
733 | |||
734 | // todo: faster way to do this? | ||
735 | } | ||
736 | } | ||
737 | |||
738 | // could also try an intersect operation rather than a union | ||
739 | // in other words, choose languages whose trigrams contain | ||
740 | // ALL of the unicode blocks found in this sample | ||
741 | // would improve speed but would be completely thrown off by an | ||
742 | // unexpected character, like an umlaut appearing in english text | ||
743 | |||
744 | $possible_langs = array_intersect( | ||
745 | array_keys($this->_lang_db), | ||
746 | array_unique($possible_langs) | ||
747 | ); | ||
748 | |||
749 | // needs to intersect it with the keys of _lang_db in case | ||
750 | // languages have been omitted | ||
751 | |||
752 | } else { | ||
753 | // or just try 'em all | ||
754 | $possible_langs = array_keys($this->_lang_db); | ||
755 | } | ||
756 | |||
757 | |||
758 | foreach ($possible_langs as $lang) { | ||
759 | $scores[$lang] = $this->_normalize_score( | ||
760 | $this->_distance($this->_lang_db[$lang], $trigram_freqs), | ||
761 | $trigram_count | ||
762 | ); | ||
763 | } | ||
764 | |||
765 | unset($sample_obj); | ||
766 | |||
767 | if ($this->_perl_compatible) { | ||
768 | asort($scores); | ||
769 | } else { | ||
770 | arsort($scores); | ||
771 | } | ||
772 | |||
773 | // todo: drop languages with a score of $this->_max_score? | ||
774 | |||
775 | // limit the number of returned scores | ||
776 | if ($limit && is_numeric($limit)) { | ||
777 | $limited_scores = array(); | ||
778 | |||
779 | $i = 0; | ||
780 | foreach ($scores as $key => $value) { | ||
781 | if ($i++ >= $limit) { | ||
782 | break; | ||
783 | } | ||
784 | |||
785 | $limited_scores[$key] = $value; | ||
786 | } | ||
787 | |||
788 | return $this->_convertToNameMode($limited_scores, true); | ||
789 | } else { | ||
790 | return $this->_convertToNameMode($scores, true); | ||
791 | } | ||
792 | } | ||
793 | |||
794 | /** | ||
795 | * Returns only the most similar language to the text sample | ||
796 | * | ||
797 | * Calls $this->detect() and returns only the top result | ||
798 | * | ||
799 | * @param string $sample text to detect the language of | ||
800 | * | ||
801 | * @return string the name of the most likely language | ||
802 | * or null if no language is similar | ||
803 | * @see detect() | ||
804 | * @throws Text_LanguageDetect_Exception | ||
805 | */ | ||
806 | public function detectSimple($sample) | ||
807 | { | ||
808 | $scores = $this->detect($sample, 1); | ||
809 | |||
810 | // if top language has the maximum possible score, | ||
811 | // then the top score will have been picked at random | ||
812 | if (!is_array($scores) || empty($scores) | ||
813 | || current($scores) == $this->_max_score | ||
814 | ) { | ||
815 | return null; | ||
816 | } else { | ||
817 | return key($scores); | ||
818 | } | ||
819 | } | ||
820 | |||
821 | /** | ||
822 | * Returns an array containing the most similar language and a confidence | ||
823 | * rating | ||
824 | * | ||
825 | * Confidence is a simple measure calculated from the similarity score | ||
826 | * minus the similarity score from the next most similar language | ||
827 | * divided by the highest possible score. Languages that have closely | ||
828 | * related cousins (e.g. Norwegian and Danish) should generally have lower | ||
829 | * confidence scores. | ||
830 | * | ||
831 | * The similarity score answers the question "How likely is the text the | ||
832 | * returned language regardless of the other languages considered?" The | ||
833 | * confidence score is one way of answering the question "how likely is the | ||
834 | * text the detected language relative to the rest of the language model | ||
835 | * set?" | ||
836 | * | ||
837 | * To see how similar languages are a priori, see languageSimilarity() | ||
838 | * | ||
839 | * @param string $sample text for which language will be detected | ||
840 | * | ||
841 | * @return array most similar language, score and confidence rating | ||
842 | * or null if no language is similar | ||
843 | * @see detect() | ||
844 | * @throws Text_LanguageDetect_Exception | ||
845 | */ | ||
846 | public function detectConfidence($sample) | ||
847 | { | ||
848 | $scores = $this->detect($sample, 2); | ||
849 | |||
850 | // if most similar language has the max score, it | ||
851 | // will have been picked at random | ||
852 | if (!is_array($scores) || empty($scores) | ||
853 | || current($scores) == $this->_max_score | ||
854 | ) { | ||
855 | return null; | ||
856 | } | ||
857 | |||
858 | $arr['language'] = key($scores); | ||
859 | $arr['similarity'] = current($scores); | ||
860 | if (next($scores) !== false) { // if false then no next element | ||
861 | // the goal is to return a higher value if the distance between | ||
862 | // the similarity of the first score and the second score is high | ||
863 | |||
864 | if ($this->_perl_compatible) { | ||
865 | $arr['confidence'] = (current($scores) - $arr['similarity']) | ||
866 | / $this->_max_score; | ||
867 | |||
868 | } else { | ||
869 | $arr['confidence'] = $arr['similarity'] - current($scores); | ||
870 | |||
871 | } | ||
872 | |||
873 | } else { | ||
874 | $arr['confidence'] = null; | ||
875 | } | ||
876 | |||
877 | return $arr; | ||
878 | } | ||
879 | |||
880 | /** | ||
881 | * Returns the distribution of unicode blocks in a given utf8 string | ||
882 | * | ||
883 | * For the block name of a single char, use unicodeBlockName() | ||
884 | * | ||
885 | * @param string $str input string. Must be ascii or utf8 | ||
886 | * @param bool $skip_symbols if true, skip ascii digits, symbols and | ||
887 | * non-printing characters. Includes spaces, | ||
888 | * newlines and common punctutation characters. | ||
889 | * | ||
890 | * @return array | ||
891 | * @throws Text_LanguageDetect_Exception | ||
892 | */ | ||
893 | public function detectUnicodeBlocks($str, $skip_symbols) | ||
894 | { | ||
895 | $skip_symbols = (bool)$skip_symbols; | ||
896 | $str = (string)$str; | ||
897 | |||
898 | $sample_obj = new Text_LanguageDetect_Parser($str); | ||
899 | $sample_obj->prepareUnicode(); | ||
900 | $sample_obj->prepareTrigram(false); | ||
901 | $sample_obj->setUnicodeSkipSymbols($skip_symbols); | ||
902 | $sample_obj->analyze(); | ||
903 | $blocks = $sample_obj->getUnicodeBlocks(); | ||
904 | unset($sample_obj); | ||
905 | return $blocks; | ||
906 | } | ||
907 | |||
908 | /** | ||
909 | * Returns the block name for a given unicode value | ||
910 | * | ||
911 | * If passed a string, will assume it is being passed a UTF8-formatted | ||
912 | * character and will automatically convert. Otherwise it will assume it | ||
913 | * is being passed a numeric unicode value. | ||
914 | * | ||
915 | * Make sure input is of the correct type! | ||
916 | * | ||
917 | * @param mixed $unicode unicode value or utf8 char | ||
918 | * | ||
919 | * @return mixed the block name string or false if not found | ||
920 | * @throws Text_LanguageDetect_Exception | ||
921 | */ | ||
922 | public function unicodeBlockName($unicode) | ||
923 | { | ||
924 | if (is_string($unicode)) { | ||
925 | // assume it is being passed a utf8 char, so convert it | ||
926 | if (self::utf8strlen($unicode) > 1) { | ||
927 | throw new Text_LanguageDetect_Exception( | ||
928 | 'Pass a single char only to this method', | ||
929 | Text_LanguageDetect_Exception::PARAM_TYPE | ||
930 | ); | ||
931 | } | ||
932 | $unicode = $this->_utf8char2unicode($unicode); | ||
933 | |||
934 | } elseif (!is_int($unicode)) { | ||
935 | throw new Text_LanguageDetect_Exception( | ||
936 | 'Input must be of type string or int.', | ||
937 | Text_LanguageDetect_Exception::PARAM_TYPE | ||
938 | ); | ||
939 | } | ||
940 | |||
941 | $blocks = $this->_read_unicode_block_db(); | ||
942 | |||
943 | $result = $this->_unicode_block_name($unicode, $blocks); | ||
944 | |||
945 | if ($result == -1) { | ||
946 | return false; | ||
947 | } else { | ||
948 | return $result[2]; | ||
949 | } | ||
950 | } | ||
951 | |||
952 | /** | ||
953 | * Searches the unicode block database | ||
954 | * | ||
955 | * Returns the block name for a given unicode value. unicodeBlockName() is | ||
956 | * the public interface for this function, which does input checks which | ||
957 | * this function omits for speed. | ||
958 | * | ||
959 | * @param int $unicode the unicode value | ||
960 | * @param array $blocks the block database | ||
961 | * @param int $block_count the number of defined blocks in the database | ||
962 | * | ||
963 | * @return mixed Block name, -1 if it failed | ||
964 | * @see unicodeBlockName() | ||
965 | * @access protected | ||
966 | */ | ||
967 | function _unicode_block_name($unicode, $blocks, $block_count = -1) | ||
968 | { | ||
969 | // for a reference, see | ||
970 | // http://www.unicode.org/Public/UNIDATA/Blocks.txt | ||
971 | |||
972 | // assume that ascii characters are the most common | ||
973 | // so try it first for efficiency | ||
974 | if ($unicode <= $blocks[0][1]) { | ||
975 | return $blocks[0]; | ||
976 | } | ||
977 | |||
978 | // the optional $block_count param is for efficiency | ||
979 | // so we this function doesn't have to run count() every time | ||
980 | if ($block_count != -1) { | ||
981 | $high = $block_count - 1; | ||
982 | } else { | ||
983 | $high = count($blocks) - 1; | ||
984 | } | ||
985 | |||
986 | $low = 1; // start with 1 because ascii was 0 | ||
987 | |||
988 | // your average binary search algorithm | ||
989 | while ($low <= $high) { | ||
990 | $mid = floor(($low + $high) / 2); | ||
991 | |||
992 | if ($unicode < $blocks[$mid][0]) { | ||
993 | // if it's lower than the lower bound | ||
994 | $high = $mid - 1; | ||
995 | |||
996 | } elseif ($unicode > $blocks[$mid][1]) { | ||
997 | // if it's higher than the upper bound | ||
998 | $low = $mid + 1; | ||
999 | |||
1000 | } else { | ||
1001 | // found it | ||
1002 | return $blocks[$mid]; | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | // failed to find the block | ||
1007 | return -1; | ||
1008 | |||
1009 | // todo: differentiate when it's out of range or when it falls | ||
1010 | // into an unassigned range? | ||
1011 | } | ||
1012 | |||
1013 | /** | ||
1014 | * Brings up the unicode block database | ||
1015 | * | ||
1016 | * @return array the database of unicode block definitions | ||
1017 | * @throws Text_LanguageDetect_Exception | ||
1018 | * @access protected | ||
1019 | */ | ||
1020 | function _read_unicode_block_db() | ||
1021 | { | ||
1022 | // since the unicode definitions are always going to be the same, | ||
1023 | // might as well share the memory for the db with all other instances | ||
1024 | // of this class | ||
1025 | static $data; | ||
1026 | |||
1027 | if (!isset($data)) { | ||
1028 | $data = $this->_readdb($this->_unicode_db_filename); | ||
1029 | } | ||
1030 | |||
1031 | return $data; | ||
1032 | } | ||
1033 | |||
1034 | /** | ||
1035 | * Calculate the similarities between the language models | ||
1036 | * | ||
1037 | * Use this function to see how similar languages are to each other. | ||
1038 | * | ||
1039 | * If passed 2 language names, will return just those languages compared. | ||
1040 | * If passed 1 language name, will return that language compared to | ||
1041 | * all others. | ||
1042 | * If passed none, will return an array of every language model compared | ||
1043 | * to every other one. | ||
1044 | * | ||
1045 | * @param string $lang1 the name of the first language to be compared | ||
1046 | * @param string $lang2 the name of the second language to be compared | ||
1047 | * | ||
1048 | * @return array scores of every language compared | ||
1049 | * or the score of just the provided languages | ||
1050 | * or null if one of the supplied languages does not exist | ||
1051 | * @throws Text_LanguageDetect_Exception | ||
1052 | */ | ||
1053 | public function languageSimilarity($lang1 = null, $lang2 = null) | ||
1054 | { | ||
1055 | $lang1 = $this->_convertFromNameMode($lang1); | ||
1056 | $lang2 = $this->_convertFromNameMode($lang2); | ||
1057 | if ($lang1 != null) { | ||
1058 | $lang1 = strtolower($lang1); | ||
1059 | |||
1060 | // check if language model exists | ||
1061 | if (!isset($this->_lang_db[$lang1])) { | ||
1062 | return null; | ||
1063 | } | ||
1064 | |||
1065 | if ($lang2 != null) { | ||
1066 | if (!isset($this->_lang_db[$lang2])) { | ||
1067 | // check if language model exists | ||
1068 | return null; | ||
1069 | } | ||
1070 | |||
1071 | $lang2 = strtolower($lang2); | ||
1072 | |||
1073 | // compare just these two languages | ||
1074 | return $this->_normalize_score( | ||
1075 | $this->_distance( | ||
1076 | $this->_lang_db[$lang1], | ||
1077 | $this->_lang_db[$lang2] | ||
1078 | ) | ||
1079 | ); | ||
1080 | |||
1081 | } else { | ||
1082 | // compare just $lang1 to all languages | ||
1083 | $return_arr = array(); | ||
1084 | foreach ($this->_lang_db as $key => $value) { | ||
1085 | if ($key != $lang1) { | ||
1086 | // don't compare a language to itself | ||
1087 | $return_arr[$key] = $this->_normalize_score( | ||
1088 | $this->_distance($this->_lang_db[$lang1], $value) | ||
1089 | ); | ||
1090 | } | ||
1091 | } | ||
1092 | asort($return_arr); | ||
1093 | |||
1094 | return $return_arr; | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | } else { | ||
1099 | // compare all languages to each other | ||
1100 | $return_arr = array(); | ||
1101 | foreach (array_keys($this->_lang_db) as $lang1) { | ||
1102 | foreach (array_keys($this->_lang_db) as $lang2) { | ||
1103 | // skip comparing languages to themselves | ||
1104 | if ($lang1 != $lang2) { | ||
1105 | |||
1106 | if (isset($return_arr[$lang2][$lang1])) { | ||
1107 | // don't re-calculate what's already been done | ||
1108 | $return_arr[$lang1][$lang2] | ||
1109 | = $return_arr[$lang2][$lang1]; | ||
1110 | |||
1111 | } else { | ||
1112 | // calculate | ||
1113 | $return_arr[$lang1][$lang2] | ||
1114 | = $this->_normalize_score( | ||
1115 | $this->_distance( | ||
1116 | $this->_lang_db[$lang1], | ||
1117 | $this->_lang_db[$lang2] | ||
1118 | ) | ||
1119 | ); | ||
1120 | |||
1121 | } | ||
1122 | } | ||
1123 | } | ||
1124 | } | ||
1125 | return $return_arr; | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1129 | /** | ||
1130 | * Cluster known languages according to languageSimilarity() | ||
1131 | * | ||
1132 | * WARNING: this method is EXPERIMENTAL. It is not recommended for common | ||
1133 | * use, and it may disappear or its functionality may change in future | ||
1134 | * releases without notice. | ||
1135 | * | ||
1136 | * Uses a nearest neighbor technique to generate the maximum possible | ||
1137 | * number of dendograms from the similarity data. | ||
1138 | * | ||
1139 | * @access public | ||
1140 | * @return array language cluster data | ||
1141 | * @throws Text_LanguageDetect_Exception | ||
1142 | * @see languageSimilarity() | ||
1143 | * @deprecated this function will eventually be removed and placed into | ||
1144 | * the model generation class | ||
1145 | */ | ||
1146 | function clusterLanguages() | ||
1147 | { | ||
1148 | // todo: set the maximum number of clusters | ||
1149 | // return cached result, if any | ||
1150 | if (isset($this->_clusters)) { | ||
1151 | return $this->_clusters; | ||
1152 | } | ||
1153 | |||
1154 | $langs = array_keys($this->_lang_db); | ||
1155 | |||
1156 | $arr = $this->languageSimilarity(); | ||
1157 | |||
1158 | sort($langs); | ||
1159 | |||
1160 | foreach ($langs as $lang) { | ||
1161 | if (!isset($this->_lang_db[$lang])) { | ||
1162 | throw new Text_LanguageDetect_Exception( | ||
1163 | "missing $lang!", | ||
1164 | Text_LanguageDetect_Exception::UNKNOWN_LANGUAGE | ||
1165 | ); | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | // http://www.psychstat.missouristate.edu/multibook/mlt04m.html | ||
1170 | foreach ($langs as $old_key => $lang1) { | ||
1171 | $langs[$lang1] = $lang1; | ||
1172 | unset($langs[$old_key]); | ||
1173 | } | ||
1174 | |||
1175 | $result_data = $really_map = array(); | ||
1176 | |||
1177 | $i = 0; | ||
1178 | while (count($langs) > 2 && $i++ < 200) { | ||
1179 | $highest_score = -1; | ||
1180 | $highest_key1 = ''; | ||
1181 | $highest_key2 = ''; | ||
1182 | foreach ($langs as $lang1) { | ||
1183 | foreach ($langs as $lang2) { | ||
1184 | if ($lang1 != $lang2 | ||
1185 | && $arr[$lang1][$lang2] > $highest_score | ||
1186 | ) { | ||
1187 | $highest_score = $arr[$lang1][$lang2]; | ||
1188 | $highest_key1 = $lang1; | ||
1189 | $highest_key2 = $lang2; | ||
1190 | } | ||
1191 | } | ||
1192 | } | ||
1193 | |||
1194 | if (!$highest_key1) { | ||
1195 | // should not ever happen | ||
1196 | throw new Text_LanguageDetect_Exception( | ||
1197 | "no highest key? (step: $i)", | ||
1198 | Text_LanguageDetect_Exception::NO_HIGHEST_KEY | ||
1199 | ); | ||
1200 | } | ||
1201 | |||
1202 | if ($highest_score == 0) { | ||
1203 | // languages are perfectly dissimilar | ||
1204 | break; | ||
1205 | } | ||
1206 | |||
1207 | // $highest_key1 and $highest_key2 are most similar | ||
1208 | $sum1 = array_sum($arr[$highest_key1]); | ||
1209 | $sum2 = array_sum($arr[$highest_key2]); | ||
1210 | |||
1211 | // use the score for the one that is most similar to the rest of | ||
1212 | // the field as the score for the group | ||
1213 | // todo: could try averaging or "centroid" method instead | ||
1214 | // seems like that might make more sense | ||
1215 | // actually nearest neighbor may be better for binary searching | ||
1216 | |||
1217 | |||
1218 | // for "Complete Linkage"/"furthest neighbor" | ||
1219 | // sign should be < | ||
1220 | // for "Single Linkage"/"nearest neighbor" method | ||
1221 | // should should be > | ||
1222 | // results seem to be pretty much the same with either method | ||
1223 | |||
1224 | // figure out which to delete and which to replace | ||
1225 | if ($sum1 > $sum2) { | ||
1226 | $replaceme = $highest_key1; | ||
1227 | $deleteme = $highest_key2; | ||
1228 | } else { | ||
1229 | $replaceme = $highest_key2; | ||
1230 | $deleteme = $highest_key1; | ||
1231 | } | ||
1232 | |||
1233 | $newkey = $replaceme . ':' . $deleteme; | ||
1234 | |||
1235 | // $replaceme is most similar to remaining languages | ||
1236 | // replace $replaceme with '$newkey', deleting $deleteme | ||
1237 | |||
1238 | // keep a record of which fork is really which language | ||
1239 | $really_lang = $replaceme; | ||
1240 | while (isset($really_map[$really_lang])) { | ||
1241 | $really_lang = $really_map[$really_lang]; | ||
1242 | } | ||
1243 | $really_map[$newkey] = $really_lang; | ||
1244 | |||
1245 | |||
1246 | // replace the best fitting key, delete the other | ||
1247 | foreach ($arr as $key1 => $arr2) { | ||
1248 | foreach ($arr2 as $key2 => $value2) { | ||
1249 | if ($key2 == $replaceme) { | ||
1250 | $arr[$key1][$newkey] = $arr[$key1][$key2]; | ||
1251 | unset($arr[$key1][$key2]); | ||
1252 | // replacing $arr[$key1][$key2] with $arr[$key1][$newkey] | ||
1253 | } | ||
1254 | |||
1255 | if ($key1 == $replaceme) { | ||
1256 | $arr[$newkey][$key2] = $arr[$key1][$key2]; | ||
1257 | unset($arr[$key1][$key2]); | ||
1258 | // replacing $arr[$key1][$key2] with $arr[$newkey][$key2] | ||
1259 | } | ||
1260 | |||
1261 | if ($key1 == $deleteme || $key2 == $deleteme) { | ||
1262 | // deleting $arr[$key1][$key2] | ||
1263 | unset($arr[$key1][$key2]); | ||
1264 | } | ||
1265 | } | ||
1266 | } | ||
1267 | |||
1268 | |||
1269 | unset($langs[$highest_key1]); | ||
1270 | unset($langs[$highest_key2]); | ||
1271 | $langs[$newkey] = $newkey; | ||
1272 | |||
1273 | |||
1274 | // some of these may be overkill | ||
1275 | $result_data[$newkey] = array( | ||
1276 | 'newkey' => $newkey, | ||
1277 | 'count' => $i, | ||
1278 | 'diff' => abs($sum1 - $sum2), | ||
1279 | 'score' => $highest_score, | ||
1280 | 'bestfit' => $replaceme, | ||
1281 | 'otherfit' => $deleteme, | ||
1282 | 'really' => $really_lang, | ||
1283 | ); | ||
1284 | } | ||
1285 | |||
1286 | $return_val = array( | ||
1287 | 'open_forks' => $langs, | ||
1288 | // the top level of clusters | ||
1289 | // clusters that are mutually exclusive | ||
1290 | // or specified by a specific maximum | ||
1291 | |||
1292 | 'fork_data' => $result_data, | ||
1293 | // data for each split | ||
1294 | |||
1295 | 'name_map' => $really_map, | ||
1296 | // which cluster is really which language | ||
1297 | // using the nearest neighbor technique, the cluster | ||
1298 | // inherits all of the properties of its most-similar member | ||
1299 | // this keeps track | ||
1300 | ); | ||
1301 | |||
1302 | |||
1303 | // saves the result in the object | ||
1304 | $this->_clusters = $return_val; | ||
1305 | |||
1306 | return $return_val; | ||
1307 | } | ||
1308 | |||
1309 | |||
1310 | /** | ||
1311 | * Perform an intelligent detection based on clusterLanguages() | ||
1312 | * | ||
1313 | * WARNING: this method is EXPERIMENTAL. It is not recommended for common | ||
1314 | * use, and it may disappear or its functionality may change in future | ||
1315 | * releases without notice. | ||
1316 | * | ||
1317 | * This compares the sample text to top the top level of clusters. If the | ||
1318 | * sample is similar to the cluster it will drop down and compare it to the | ||
1319 | * languages in the cluster, and so on until it hits a leaf node. | ||
1320 | * | ||
1321 | * this should find the language in considerably fewer compares | ||
1322 | * (the equivalent of a binary search), however clusterLanguages() is costly | ||
1323 | * and the loss of accuracy from this technique is significant. | ||
1324 | * | ||
1325 | * This method may need to be 'fuzzier' in order to become more accurate. | ||
1326 | * | ||
1327 | * This function could be more useful if the universe of possible languages | ||
1328 | * was very large, however in such cases some method of Bayesian inference | ||
1329 | * might be more helpful. | ||
1330 | * | ||
1331 | * @param string $str input string | ||
1332 | * | ||
1333 | * @return array language scores (only those compared) | ||
1334 | * @throws Text_LanguageDetect_Exception | ||
1335 | * @see clusterLanguages() | ||
1336 | */ | ||
1337 | public function clusteredSearch($str) | ||
1338 | { | ||
1339 | // input check | ||
1340 | if (!Text_LanguageDetect_Parser::validateString($str)) { | ||
1341 | return array(); | ||
1342 | } | ||
1343 | |||
1344 | // clusterLanguages() will return a cached result if possible | ||
1345 | // so it's safe to call it every time | ||
1346 | $result = $this->clusterLanguages(); | ||
1347 | |||
1348 | $dendogram_start = $result['open_forks']; | ||
1349 | $dendogram_data = $result['fork_data']; | ||
1350 | $dendogram_alias = $result['name_map']; | ||
1351 | |||
1352 | $sample_obj = new Text_LanguageDetect_Parser($str); | ||
1353 | $sample_obj->prepareTrigram(); | ||
1354 | $sample_obj->setPadStart(!$this->_perl_compatible); | ||
1355 | $sample_obj->analyze(); | ||
1356 | $sample_result = $sample_obj->getTrigramRanks(); | ||
1357 | $sample_count = count($sample_result); | ||
1358 | |||
1359 | // input check | ||
1360 | if ($sample_count == 0) { | ||
1361 | return array(); | ||
1362 | } | ||
1363 | |||
1364 | $i = 0; // counts the number of steps | ||
1365 | |||
1366 | foreach ($dendogram_start as $lang) { | ||
1367 | if (isset($dendogram_alias[$lang])) { | ||
1368 | $lang_key = $dendogram_alias[$lang]; | ||
1369 | } else { | ||
1370 | $lang_key = $lang; | ||
1371 | } | ||
1372 | |||
1373 | $scores[$lang] = $this->_normalize_score( | ||
1374 | $this->_distance($this->_lang_db[$lang_key], $sample_result), | ||
1375 | $sample_count | ||
1376 | ); | ||
1377 | |||
1378 | $i++; | ||
1379 | } | ||
1380 | |||
1381 | if ($this->_perl_compatible) { | ||
1382 | asort($scores); | ||
1383 | } else { | ||
1384 | arsort($scores); | ||
1385 | } | ||
1386 | |||
1387 | $top_score = current($scores); | ||
1388 | $top_key = key($scores); | ||
1389 | |||
1390 | // of starting forks, $top_key is the most similar to the sample | ||
1391 | |||
1392 | $cur_key = $top_key; | ||
1393 | while (isset($dendogram_data[$cur_key])) { | ||
1394 | $lang1 = $dendogram_data[$cur_key]['bestfit']; | ||
1395 | $lang2 = $dendogram_data[$cur_key]['otherfit']; | ||
1396 | foreach (array($lang1, $lang2) as $lang) { | ||
1397 | if (isset($dendogram_alias[$lang])) { | ||
1398 | $lang_key = $dendogram_alias[$lang]; | ||
1399 | } else { | ||
1400 | $lang_key = $lang; | ||
1401 | } | ||
1402 | |||
1403 | $scores[$lang] = $this->_normalize_score( | ||
1404 | $this->_distance($this->_lang_db[$lang_key], $sample_result), | ||
1405 | $sample_count | ||
1406 | ); | ||
1407 | |||
1408 | //todo: does not need to do same comparison again | ||
1409 | } | ||
1410 | |||
1411 | $i++; | ||
1412 | |||
1413 | if ($scores[$lang1] > $scores[$lang2]) { | ||
1414 | $cur_key = $lang1; | ||
1415 | $loser_key = $lang2; | ||
1416 | } else { | ||
1417 | $cur_key = $lang2; | ||
1418 | $loser_key = $lang1; | ||
1419 | } | ||
1420 | |||
1421 | $diff = $scores[$cur_key] - $scores[$loser_key]; | ||
1422 | |||
1423 | // $cur_key ({$dendogram_alias[$cur_key]}) wins | ||
1424 | // over $loser_key ({$dendogram_alias[$loser_key]}) | ||
1425 | // with a difference of $diff | ||
1426 | } | ||
1427 | |||
1428 | // found result in $i compares | ||
1429 | |||
1430 | // rather than sorting the result, preserve it so that you can see | ||
1431 | // which paths the algorithm decided to take along the tree | ||
1432 | |||
1433 | // but sometimes the last item is only the second highest | ||
1434 | if (($this->_perl_compatible && (end($scores) > prev($scores))) | ||
1435 | || (!$this->_perl_compatible && (end($scores) < prev($scores))) | ||
1436 | ) { | ||
1437 | $real_last_score = current($scores); | ||
1438 | $real_last_key = key($scores); | ||
1439 | |||
1440 | // swaps the 2nd-to-last item for the last item | ||
1441 | unset($scores[$real_last_key]); | ||
1442 | $scores[$real_last_key] = $real_last_score; | ||
1443 | } | ||
1444 | |||
1445 | |||
1446 | if (!$this->_perl_compatible) { | ||
1447 | $scores = array_reverse($scores, true); | ||
1448 | // second param requires php > 4.0.3 | ||
1449 | } | ||
1450 | |||
1451 | return $scores; | ||
1452 | } | ||
1453 | |||
1454 | /** | ||
1455 | * ut8-safe strlen() | ||
1456 | * | ||
1457 | * Returns the numbers of characters (not bytes) in a utf8 string | ||
1458 | * | ||
1459 | * @param string $str string to get the length of | ||
1460 | * | ||
1461 | * @return int number of chars | ||
1462 | */ | ||
1463 | public static function utf8strlen($str) | ||
1464 | { | ||
1465 | // utf8_decode() will convert unknown chars to '?', which is actually | ||
1466 | // ideal for counting. | ||
1467 | |||
1468 | return strlen(utf8_decode($str)); | ||
1469 | |||
1470 | // idea stolen from dokuwiki | ||
1471 | } | ||
1472 | |||
1473 | /** | ||
1474 | * Returns the unicode value of a utf8 char | ||
1475 | * | ||
1476 | * @param string $char a utf8 (possibly multi-byte) char | ||
1477 | * | ||
1478 | * @return int unicode value | ||
1479 | * @access protected | ||
1480 | * @link http://en.wikipedia.org/wiki/UTF-8 | ||
1481 | */ | ||
1482 | function _utf8char2unicode($char) | ||
1483 | { | ||
1484 | // strlen() here will actually get the binary length of a single char | ||
1485 | switch (strlen($char)) { | ||
1486 | case 1: | ||
1487 | // normal ASCII-7 byte | ||
1488 | // 0xxxxxxx --> 0xxxxxxx | ||
1489 | return ord($char{0}); | ||
1490 | |||
1491 | case 2: | ||
1492 | // 2 byte unicode | ||
1493 | // 110zzzzx 10xxxxxx --> 00000zzz zxxxxxxx | ||
1494 | $z = (ord($char{0}) & 0x000001F) << 6; | ||
1495 | $x = (ord($char{1}) & 0x0000003F); | ||
1496 | return ($z | $x); | ||
1497 | |||
1498 | case 3: | ||
1499 | // 3 byte unicode | ||
1500 | // 1110zzzz 10zxxxxx 10xxxxxx --> zzzzzxxx xxxxxxxx | ||
1501 | $z = (ord($char{0}) & 0x0000000F) << 12; | ||
1502 | $x1 = (ord($char{1}) & 0x0000003F) << 6; | ||
1503 | $x2 = (ord($char{2}) & 0x0000003F); | ||
1504 | return ($z | $x1 | $x2); | ||
1505 | |||
1506 | case 4: | ||
1507 | // 4 byte unicode | ||
1508 | // 11110zzz 10zzxxxx 10xxxxxx 10xxxxxx --> | ||
1509 | // 000zzzzz xxxxxxxx xxxxxxxx | ||
1510 | $z1 = (ord($char{0}) & 0x00000007) << 18; | ||
1511 | $z2 = (ord($char{1}) & 0x0000003F) << 12; | ||
1512 | $x1 = (ord($char{2}) & 0x0000003F) << 6; | ||
1513 | $x2 = (ord($char{3}) & 0x0000003F); | ||
1514 | return ($z1 | $z2 | $x1 | $x2); | ||
1515 | } | ||
1516 | } | ||
1517 | |||
1518 | /** | ||
1519 | * utf8-safe fast character iterator | ||
1520 | * | ||
1521 | * Will get the next character starting from $counter, which will then be | ||
1522 | * incremented. If a multi-byte char the bytes will be concatenated and | ||
1523 | * $counter will be incremeted by the number of bytes in the char. | ||
1524 | * | ||
1525 | * @param string $str the string being iterated over | ||
1526 | * @param int &$counter the iterator, will increment by reference | ||
1527 | * @param bool $special_convert whether to do special conversions | ||
1528 | * | ||
1529 | * @return char the next (possibly multi-byte) char from $counter | ||
1530 | * @access private | ||
1531 | */ | ||
1532 | static function _next_char($str, &$counter, $special_convert = false) | ||
1533 | { | ||
1534 | $char = $str{$counter++}; | ||
1535 | $ord = ord($char); | ||
1536 | |||
1537 | // for a description of the utf8 system see | ||
1538 | // http://www.phpclasses.org/browse/file/5131.html | ||
1539 | |||
1540 | // normal ascii one byte char | ||
1541 | if ($ord <= 127) { | ||
1542 | // special conversions needed for this package | ||
1543 | // (that only apply to regular ascii characters) | ||
1544 | // lower case, and convert all non-alphanumeric characters | ||
1545 | // other than "'" to space | ||
1546 | if ($special_convert && $char != ' ' && $char != "'") { | ||
1547 | if ($ord >= 65 && $ord <= 90) { // A-Z | ||
1548 | $char = chr($ord + 32); // lower case | ||
1549 | } elseif ($ord < 97 || $ord > 122) { // NOT a-z | ||
1550 | $char = ' '; // convert to space | ||
1551 | } | ||
1552 | } | ||
1553 | |||
1554 | return $char; | ||
1555 | |||
1556 | } elseif ($ord >> 5 == 6) { // two-byte char | ||
1557 | // multi-byte chars | ||
1558 | $nextchar = $str{$counter++}; // get next byte | ||
1559 | |||
1560 | // lower-casing of non-ascii characters is still incomplete | ||
1561 | |||
1562 | if ($special_convert) { | ||
1563 | // lower case latin accented characters | ||
1564 | if ($ord == 195) { | ||
1565 | $nextord = ord($nextchar); | ||
1566 | $nextord_adj = $nextord + 64; | ||
1567 | // for a reference, see | ||
1568 | // http://www.ramsch.org/martin/uni/fmi-hp/iso8859-1.html | ||
1569 | |||
1570 | // À - Þ but not × | ||
1571 | if ($nextord_adj >= 192 | ||
1572 | && $nextord_adj <= 222 | ||
1573 | && $nextord_adj != 215 | ||
1574 | ) { | ||
1575 | $nextchar = chr($nextord + 32); | ||
1576 | } | ||
1577 | |||
1578 | } elseif ($ord == 208) { | ||
1579 | // lower case cyrillic alphabet | ||
1580 | $nextord = ord($nextchar); | ||
1581 | // if A - Pe | ||
1582 | if ($nextord >= 144 && $nextord <= 159) { | ||
1583 | // lower case | ||
1584 | $nextchar = chr($nextord + 32); | ||
1585 | |||
1586 | } elseif ($nextord >= 160 && $nextord <= 175) { | ||
1587 | // if Er - Ya | ||
1588 | // lower case | ||
1589 | $char = chr(209); // == $ord++ | ||
1590 | $nextchar = chr($nextord - 32); | ||
1591 | } | ||
1592 | } | ||
1593 | } | ||
1594 | |||
1595 | // tag on next byte | ||
1596 | return $char . $nextchar; | ||
1597 | } elseif ($ord >> 4 == 14) { // three-byte char | ||
1598 | |||
1599 | // tag on next 2 bytes | ||
1600 | return $char . $str{$counter++} . $str{$counter++}; | ||
1601 | |||
1602 | } elseif ($ord >> 3 == 30) { // four-byte char | ||
1603 | |||
1604 | // tag on next 3 bytes | ||
1605 | return $char . $str{$counter++} . $str{$counter++} . $str{$counter++}; | ||
1606 | |||
1607 | } else { | ||
1608 | // error? | ||
1609 | } | ||
1610 | } | ||
1611 | |||
1612 | /** | ||
1613 | * Converts an $language input parameter from the configured mode | ||
1614 | * to the language name that is used internally. | ||
1615 | * | ||
1616 | * Works for strings and arrays. | ||
1617 | * | ||
1618 | * @param string|array $lang A language description ("english"/"en"/"eng") | ||
1619 | * @param boolean $convertKey If $lang is an array, setting $key | ||
1620 | * converts the keys to the language name. | ||
1621 | * | ||
1622 | * @return string|array Language name | ||
1623 | */ | ||
1624 | function _convertFromNameMode($lang, $convertKey = false) | ||
1625 | { | ||
1626 | if ($this->_name_mode == 0) { | ||
1627 | return $lang; | ||
1628 | } | ||
1629 | |||
1630 | if ($this->_name_mode == 2) { | ||
1631 | $method = 'code2ToName'; | ||
1632 | } else { | ||
1633 | $method = 'code3ToName'; | ||
1634 | } | ||
1635 | |||
1636 | if (is_string($lang)) { | ||
1637 | return (string)Text_LanguageDetect_ISO639::$method($lang); | ||
1638 | } | ||
1639 | |||
1640 | $newlang = array(); | ||
1641 | foreach ($lang as $key => $val) { | ||
1642 | if ($convertKey) { | ||
1643 | $newkey = (string)Text_LanguageDetect_ISO639::$method($key); | ||
1644 | $newlang[$newkey] = $val; | ||
1645 | } else { | ||
1646 | $newlang[$key] = (string)Text_LanguageDetect_ISO639::$method($val); | ||
1647 | } | ||
1648 | } | ||
1649 | return $newlang; | ||
1650 | } | ||
1651 | |||
1652 | /** | ||
1653 | * Converts an $language output parameter from the language name that is | ||
1654 | * used internally to the configured mode. | ||
1655 | * | ||
1656 | * Works for strings and arrays. | ||
1657 | * | ||
1658 | * @param string|array $lang A language description ("english"/"en"/"eng") | ||
1659 | * @param boolean $convertKey If $lang is an array, setting $key | ||
1660 | * converts the keys to the language name. | ||
1661 | * | ||
1662 | * @return string|array Language name | ||
1663 | */ | ||
1664 | function _convertToNameMode($lang, $convertKey = false) | ||
1665 | { | ||
1666 | if ($this->_name_mode == 0) { | ||
1667 | return $lang; | ||
1668 | } | ||
1669 | |||
1670 | if ($this->_name_mode == 2) { | ||
1671 | $method = 'nameToCode2'; | ||
1672 | } else { | ||
1673 | $method = 'nameToCode3'; | ||
1674 | } | ||
1675 | |||
1676 | if (is_string($lang)) { | ||
1677 | return Text_LanguageDetect_ISO639::$method($lang); | ||
1678 | } | ||
1679 | |||
1680 | $newlang = array(); | ||
1681 | foreach ($lang as $key => $val) { | ||
1682 | if ($convertKey) { | ||
1683 | $newkey = Text_LanguageDetect_ISO639::$method($key); | ||
1684 | $newlang[$newkey] = $val; | ||
1685 | } else { | ||
1686 | $newlang[$key] = Text_LanguageDetect_ISO639::$method($val); | ||
1687 | } | ||
1688 | } | ||
1689 | return $newlang; | ||
1690 | } | ||
1691 | } | ||
1692 | |||
1693 | /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/language-detect/LanguageDetect/Exception.php b/inc/3rdparty/libraries/language-detect/LanguageDetect/Exception.php deleted file mode 100644 index 196d994f..00000000 --- a/inc/3rdparty/libraries/language-detect/LanguageDetect/Exception.php +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | <?php | ||
2 | class Text_LanguageDetect_Exception extends Exception | ||
3 | { | ||
4 | /** | ||
5 | * Database file could not be found | ||
6 | */ | ||
7 | const DB_NOT_FOUND = 10; | ||
8 | |||
9 | /** | ||
10 | * Database file found, but not readable | ||
11 | */ | ||
12 | const DB_NOT_READABLE = 11; | ||
13 | |||
14 | /** | ||
15 | * Database file is empty | ||
16 | */ | ||
17 | const DB_EMPTY = 12; | ||
18 | |||
19 | /** | ||
20 | * Database contents is not a PHP array | ||
21 | */ | ||
22 | const DB_NOT_ARRAY = 13; | ||
23 | |||
24 | /** | ||
25 | * Magic quotes are activated | ||
26 | */ | ||
27 | const MAGIC_QUOTES = 14; | ||
28 | |||
29 | |||
30 | /** | ||
31 | * Parameter of invalid type passed to method | ||
32 | */ | ||
33 | const PARAM_TYPE = 20; | ||
34 | |||
35 | /** | ||
36 | * Character in parameter is invalid | ||
37 | */ | ||
38 | const INVALID_CHAR = 21; | ||
39 | |||
40 | |||
41 | /** | ||
42 | * Language is not in the database | ||
43 | */ | ||
44 | const UNKNOWN_LANGUAGE = 30; | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Error during block detection | ||
49 | */ | ||
50 | const BLOCK_DETECTION = 40; | ||
51 | |||
52 | |||
53 | /** | ||
54 | * Error while clustering languages | ||
55 | */ | ||
56 | const NO_HIGHEST_KEY = 50; | ||
57 | } | ||
diff --git a/inc/3rdparty/libraries/language-detect/LanguageDetect/ISO639.php b/inc/3rdparty/libraries/language-detect/LanguageDetect/ISO639.php deleted file mode 100644 index 05b0590d..00000000 --- a/inc/3rdparty/libraries/language-detect/LanguageDetect/ISO639.php +++ /dev/null | |||
@@ -1,339 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Part of Text_LanguageDetect | ||
4 | * | ||
5 | * PHP version 5 | ||
6 | * | ||
7 | * @category Text | ||
8 | * @package Text_LanguageDetect | ||
9 | * @author Christian Weiske <cweiske@php.net> | ||
10 | * @copyright 2011 Christian Weiske <cweiske@php.net> | ||
11 | * @license http://www.debian.org/misc/bsd.license BSD | ||
12 | * @version SVN: $Id$ | ||
13 | * @link http://pear.php.net/package/Text_LanguageDetect/ | ||
14 | */ | ||
15 | |||
16 | /** | ||
17 | * Provides a mapping between the languages from lang.dat and the | ||
18 | * ISO 639-1 and ISO-639-2 codes. | ||
19 | * | ||
20 | * Note that this class contains only languages that exist in lang.dat. | ||
21 | * | ||
22 | * @category Text | ||
23 | * @package Text_LanguageDetect | ||
24 | * @author Christian Weiske <cweiske@php.net> | ||
25 | * @copyright 2011 Christian Weiske <cweiske@php.net> | ||
26 | * @license http://www.debian.org/misc/bsd.license BSD | ||
27 | * @link http://www.loc.gov/standards/iso639-2/php/code_list.php | ||
28 | */ | ||
29 | class Text_LanguageDetect_ISO639 | ||
30 | { | ||
31 | /** | ||
32 | * Maps all language names from the language database to the | ||
33 | * ISO 639-1 2-letter language code. | ||
34 | * | ||
35 | * NULL indicates that there is no 2-letter code. | ||
36 | * | ||
37 | * @var array | ||
38 | */ | ||
39 | public static $nameToCode2 = array( | ||
40 | 'albanian' => 'sq', | ||
41 | 'arabic' => 'ar', | ||
42 | 'azeri' => 'az', | ||
43 | 'bengali' => 'bn', | ||
44 | 'bulgarian' => 'bg', | ||
45 | 'cebuano' => null, | ||
46 | 'croatian' => 'hr', | ||
47 | 'czech' => 'cs', | ||
48 | 'danish' => 'da', | ||
49 | 'dutch' => 'nl', | ||
50 | 'english' => 'en', | ||
51 | 'estonian' => 'et', | ||
52 | 'farsi' => 'fa', | ||
53 | 'finnish' => 'fi', | ||
54 | 'french' => 'fr', | ||
55 | 'german' => 'de', | ||
56 | 'hausa' => 'ha', | ||
57 | 'hawaiian' => null, | ||
58 | 'hindi' => 'hi', | ||
59 | 'hungarian' => 'hu', | ||
60 | 'icelandic' => 'is', | ||
61 | 'indonesian' => 'id', | ||
62 | 'italian' => 'it', | ||
63 | 'kazakh' => 'kk', | ||
64 | 'kyrgyz' => 'ky', | ||
65 | 'latin' => 'la', | ||
66 | 'latvian' => 'lv', | ||
67 | 'lithuanian' => 'lt', | ||
68 | 'macedonian' => 'mk', | ||
69 | 'mongolian' => 'mn', | ||
70 | 'nepali' => 'ne', | ||
71 | 'norwegian' => 'no', | ||
72 | 'pashto' => 'ps', | ||
73 | 'pidgin' => null, | ||
74 | 'polish' => 'pl', | ||
75 | 'portuguese' => 'pt', | ||
76 | 'romanian' => 'ro', | ||
77 | 'russian' => 'ru', | ||
78 | 'serbian' => 'sr', | ||
79 | 'slovak' => 'sk', | ||
80 | 'slovene' => 'sl', | ||
81 | 'somali' => 'so', | ||
82 | 'spanish' => 'es', | ||
83 | 'swahili' => 'sw', | ||
84 | 'swedish' => 'sv', | ||
85 | 'tagalog' => 'tl', | ||
86 | 'turkish' => 'tr', | ||
87 | 'ukrainian' => 'uk', | ||
88 | 'urdu' => 'ur', | ||
89 | 'uzbek' => 'uz', | ||
90 | 'vietnamese' => 'vi', | ||
91 | 'welsh' => 'cy', | ||
92 | ); | ||
93 | |||
94 | /** | ||
95 | * Maps all language names from the language database to the | ||
96 | * ISO 639-2 3-letter language code. | ||
97 | * | ||
98 | * @var array | ||
99 | */ | ||
100 | public static $nameToCode3 = array( | ||
101 | 'albanian' => 'sqi', | ||
102 | 'arabic' => 'ara', | ||
103 | 'azeri' => 'aze', | ||
104 | 'bengali' => 'ben', | ||
105 | 'bulgarian' => 'bul', | ||
106 | 'cebuano' => 'ceb', | ||
107 | 'croatian' => 'hrv', | ||
108 | 'czech' => 'ces', | ||
109 | 'danish' => 'dan', | ||
110 | 'dutch' => 'nld', | ||
111 | 'english' => 'eng', | ||
112 | 'estonian' => 'est', | ||
113 | 'farsi' => 'fas', | ||
114 | 'finnish' => 'fin', | ||
115 | 'french' => 'fra', | ||
116 | 'german' => 'deu', | ||
117 | 'hausa' => 'hau', | ||
118 | 'hawaiian' => 'haw', | ||
119 | 'hindi' => 'hin', | ||
120 | 'hungarian' => 'hun', | ||
121 | 'icelandic' => 'isl', | ||
122 | 'indonesian' => 'ind', | ||
123 | 'italian' => 'ita', | ||
124 | 'kazakh' => 'kaz', | ||
125 | 'kyrgyz' => 'kir', | ||
126 | 'latin' => 'lat', | ||
127 | 'latvian' => 'lav', | ||
128 | 'lithuanian' => 'lit', | ||
129 | 'macedonian' => 'mkd', | ||
130 | 'mongolian' => 'mon', | ||
131 | 'nepali' => 'nep', | ||
132 | 'norwegian' => 'nor', | ||
133 | 'pashto' => 'pus', | ||
134 | 'pidgin' => 'crp', | ||
135 | 'polish' => 'pol', | ||
136 | 'portuguese' => 'por', | ||
137 | 'romanian' => 'ron', | ||
138 | 'russian' => 'rus', | ||
139 | 'serbian' => 'srp', | ||
140 | 'slovak' => 'slk', | ||
141 | 'slovene' => 'slv', | ||
142 | 'somali' => 'som', | ||
143 | 'spanish' => 'spa', | ||
144 | 'swahili' => 'swa', | ||
145 | 'swedish' => 'swe', | ||
146 | 'tagalog' => 'tgl', | ||
147 | 'turkish' => 'tur', | ||
148 | 'ukrainian' => 'ukr', | ||
149 | 'urdu' => 'urd', | ||
150 | 'uzbek' => 'uzb', | ||
151 | 'vietnamese' => 'vie', | ||
152 | 'welsh' => 'cym', | ||
153 | ); | ||
154 | |||
155 | /** | ||
156 | * Maps ISO 639-1 2-letter language codes to the language names | ||
157 | * in the language database | ||
158 | * | ||
159 | * Not all languages have a 2 letter code, so some are missing | ||
160 | * | ||
161 | * @var array | ||
162 | */ | ||
163 | public static $code2ToName = array( | ||
164 | 'ar' => 'arabic', | ||
165 | 'az' => 'azeri', | ||
166 | 'bg' => 'bulgarian', | ||
167 | 'bn' => 'bengali', | ||
168 | 'cs' => 'czech', | ||
169 | 'cy' => 'welsh', | ||
170 | 'da' => 'danish', | ||
171 | 'de' => 'german', | ||
172 | 'en' => 'english', | ||
173 | 'es' => 'spanish', | ||
174 | 'et' => 'estonian', | ||
175 | 'fa' => 'farsi', | ||
176 | 'fi' => 'finnish', | ||
177 | 'fr' => 'french', | ||
178 | 'ha' => 'hausa', | ||
179 | 'hi' => 'hindi', | ||
180 | 'hr' => 'croatian', | ||
181 | 'hu' => 'hungarian', | ||
182 | 'id' => 'indonesian', | ||
183 | 'is' => 'icelandic', | ||
184 | 'it' => 'italian', | ||
185 | 'kk' => 'kazakh', | ||
186 | 'ky' => 'kyrgyz', | ||
187 | 'la' => 'latin', | ||
188 | 'lt' => 'lithuanian', | ||
189 | 'lv' => 'latvian', | ||
190 | 'mk' => 'macedonian', | ||
191 | 'mn' => 'mongolian', | ||
192 | 'ne' => 'nepali', | ||
193 | 'nl' => 'dutch', | ||
194 | 'no' => 'norwegian', | ||
195 | 'pl' => 'polish', | ||
196 | 'ps' => 'pashto', | ||
197 | 'pt' => 'portuguese', | ||
198 | 'ro' => 'romanian', | ||
199 | 'ru' => 'russian', | ||
200 | 'sk' => 'slovak', | ||
201 | 'sl' => 'slovene', | ||
202 | 'so' => 'somali', | ||
203 | 'sq' => 'albanian', | ||
204 | 'sr' => 'serbian', | ||
205 | 'sv' => 'swedish', | ||
206 | 'sw' => 'swahili', | ||
207 | 'tl' => 'tagalog', | ||
208 | 'tr' => 'turkish', | ||
209 | 'uk' => 'ukrainian', | ||
210 | 'ur' => 'urdu', | ||
211 | 'uz' => 'uzbek', | ||
212 | 'vi' => 'vietnamese', | ||
213 | ); | ||
214 | |||
215 | /** | ||
216 | * Maps ISO 639-2 3-letter language codes to the language names | ||
217 | * in the language database. | ||
218 | * | ||
219 | * @var array | ||
220 | */ | ||
221 | public static $code3ToName = array( | ||
222 | 'ara' => 'arabic', | ||
223 | 'aze' => 'azeri', | ||
224 | 'ben' => 'bengali', | ||
225 | 'bul' => 'bulgarian', | ||
226 | 'ceb' => 'cebuano', | ||
227 | 'ces' => 'czech', | ||
228 | 'crp' => 'pidgin', | ||
229 | 'cym' => 'welsh', | ||
230 | 'dan' => 'danish', | ||
231 | 'deu' => 'german', | ||
232 | 'eng' => 'english', | ||
233 | 'est' => 'estonian', | ||
234 | 'fas' => 'farsi', | ||
235 | 'fin' => 'finnish', | ||
236 | 'fra' => 'french', | ||
237 | 'hau' => 'hausa', | ||
238 | 'haw' => 'hawaiian', | ||
239 | 'hin' => 'hindi', | ||
240 | 'hrv' => 'croatian', | ||
241 | 'hun' => 'hungarian', | ||
242 | 'ind' => 'indonesian', | ||
243 | 'isl' => 'icelandic', | ||
244 | 'ita' => 'italian', | ||
245 | 'kaz' => 'kazakh', | ||
246 | 'kir' => 'kyrgyz', | ||
247 | 'lat' => 'latin', | ||
248 | 'lav' => 'latvian', | ||
249 | 'lit' => 'lithuanian', | ||
250 | 'mkd' => 'macedonian', | ||
251 | 'mon' => 'mongolian', | ||
252 | 'nep' => 'nepali', | ||
253 | 'nld' => 'dutch', | ||
254 | 'nor' => 'norwegian', | ||
255 | 'pol' => 'polish', | ||
256 | 'por' => 'portuguese', | ||
257 | 'pus' => 'pashto', | ||
258 | 'rom' => 'romanian', | ||
259 | 'rus' => 'russian', | ||
260 | 'slk' => 'slovak', | ||
261 | 'slv' => 'slovene', | ||
262 | 'som' => 'somali', | ||
263 | 'spa' => 'spanish', | ||
264 | 'sqi' => 'albanian', | ||
265 | 'srp' => 'serbian', | ||
266 | 'swa' => 'swahili', | ||
267 | 'swe' => 'swedish', | ||
268 | 'tgl' => 'tagalog', | ||
269 | 'tur' => 'turkish', | ||
270 | 'ukr' => 'ukrainian', | ||
271 | 'urd' => 'urdu', | ||
272 | 'uzb' => 'uzbek', | ||
273 | 'vie' => 'vietnamese', | ||
274 | ); | ||
275 | |||
276 | /** | ||
277 | * Returns the 2-letter ISO 639-1 code for the given language name. | ||
278 | * | ||
279 | * @param string $lang English language name like "swedish" | ||
280 | * | ||
281 | * @return string Two-letter language code (e.g. "sv") or NULL if not found | ||
282 | */ | ||
283 | public static function nameToCode2($lang) | ||
284 | { | ||
285 | $lang = strtolower($lang); | ||
286 | if (!isset(self::$nameToCode2[$lang])) { | ||
287 | return null; | ||
288 | } | ||
289 | return self::$nameToCode2[$lang]; | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * Returns the 3-letter ISO 639-2 code for the given language name. | ||
294 | * | ||
295 | * @param string $lang English language name like "swedish" | ||
296 | * | ||
297 | * @return string Three-letter language code (e.g. "swe") or NULL if not found | ||
298 | */ | ||
299 | public static function nameToCode3($lang) | ||
300 | { | ||
301 | $lang = strtolower($lang); | ||
302 | if (!isset(self::$nameToCode3[$lang])) { | ||
303 | return null; | ||
304 | } | ||
305 | return self::$nameToCode3[$lang]; | ||
306 | } | ||
307 | |||
308 | /** | ||
309 | * Returns the language name for the given 2-letter ISO 639-1 code. | ||
310 | * | ||
311 | * @param string $code Two-letter language code (e.g. "sv") | ||
312 | * | ||
313 | * @return string English language name like "swedish" | ||
314 | */ | ||
315 | public static function code2ToName($code) | ||
316 | { | ||
317 | $lang = strtolower($code); | ||
318 | if (!isset(self::$code2ToName[$code])) { | ||
319 | return null; | ||
320 | } | ||
321 | return self::$code2ToName[$code]; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Returns the language name for the given 3-letter ISO 639-2 code. | ||
326 | * | ||
327 | * @param string $code Three-letter language code (e.g. "swe") | ||
328 | * | ||
329 | * @return string English language name like "swedish" | ||
330 | */ | ||
331 | public static function code3ToName($code) | ||
332 | { | ||
333 | $lang = strtolower($code); | ||
334 | if (!isset(self::$code3ToName[$code])) { | ||
335 | return null; | ||
336 | } | ||
337 | return self::$code3ToName[$code]; | ||
338 | } | ||
339 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/language-detect/LanguageDetect/Parser.php b/inc/3rdparty/libraries/language-detect/LanguageDetect/Parser.php deleted file mode 100644 index fb0e1e20..00000000 --- a/inc/3rdparty/libraries/language-detect/LanguageDetect/Parser.php +++ /dev/null | |||
@@ -1,347 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * This class represents a text sample to be parsed. | ||
5 | * | ||
6 | * @category Text | ||
7 | * @package Text_LanguageDetect | ||
8 | * @author Nicholas Pisarro | ||
9 | * @copyright 2006 | ||
10 | * @license BSD | ||
11 | * @version CVS: $Id: Parser.php 322327 2012-01-15 17:55:59Z cweiske $ | ||
12 | * @link http://pear.php.net/package/Text_LanguageDetect/ | ||
13 | * @link http://langdetect.blogspot.com/ | ||
14 | */ | ||
15 | |||
16 | /** | ||
17 | * This class represents a text sample to be parsed. | ||
18 | * | ||
19 | * This separates the analysis of a text sample from the primary LanguageDetect | ||
20 | * class. After a new profile has been built, the data can be retrieved using | ||
21 | * the accessor functions. | ||
22 | * | ||
23 | * This class is intended to be used by the Text_LanguageDetect class, not | ||
24 | * end-users. | ||
25 | * | ||
26 | * @category Text | ||
27 | * @package Text_LanguageDetect | ||
28 | * @author Nicholas Pisarro | ||
29 | * @copyright 2006 | ||
30 | * @license BSD | ||
31 | * @version release: 0.3.0 | ||
32 | */ | ||
33 | class Text_LanguageDetect_Parser extends Text_LanguageDetect | ||
34 | { | ||
35 | /** | ||
36 | * the piece of text being parsed | ||
37 | * | ||
38 | * @access private | ||
39 | * @var string | ||
40 | */ | ||
41 | var $_string; | ||
42 | |||
43 | /** | ||
44 | * stores the trigram frequencies of the sample | ||
45 | * | ||
46 | * @access private | ||
47 | * @var string | ||
48 | */ | ||
49 | var $_trigrams = array(); | ||
50 | |||
51 | /** | ||
52 | * stores the trigram ranks of the sample | ||
53 | * | ||
54 | * @access private | ||
55 | * @var array | ||
56 | */ | ||
57 | var $_trigram_ranks = array(); | ||
58 | |||
59 | /** | ||
60 | * stores the unicode blocks of the sample | ||
61 | * | ||
62 | * @access private | ||
63 | * @var array | ||
64 | */ | ||
65 | var $_unicode_blocks = array(); | ||
66 | |||
67 | /** | ||
68 | * Whether the parser should compile the unicode ranges | ||
69 | * | ||
70 | * @access private | ||
71 | * @var bool | ||
72 | */ | ||
73 | var $_compile_unicode = false; | ||
74 | |||
75 | /** | ||
76 | * Whether the parser should compile trigrams | ||
77 | * | ||
78 | * @access private | ||
79 | * @var bool | ||
80 | */ | ||
81 | var $_compile_trigram = false; | ||
82 | |||
83 | /** | ||
84 | * Whether the trigram parser should pad the beginning of the string | ||
85 | * | ||
86 | * @access private | ||
87 | * @var bool | ||
88 | */ | ||
89 | var $_trigram_pad_start = false; | ||
90 | |||
91 | /** | ||
92 | * Whether the unicode parser should skip non-alphabetical ascii chars | ||
93 | * | ||
94 | * @access private | ||
95 | * @var bool | ||
96 | */ | ||
97 | var $_unicode_skip_symbols = true; | ||
98 | |||
99 | /** | ||
100 | * Constructor | ||
101 | * | ||
102 | * @access private | ||
103 | * @param string $string string to be parsed | ||
104 | */ | ||
105 | function Text_LanguageDetect_Parser($string) { | ||
106 | $this->_string = $string; | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * Returns true if a string is suitable for parsing | ||
111 | * | ||
112 | * @param string $str input string to test | ||
113 | * @return bool true if acceptable, false if not | ||
114 | */ | ||
115 | public static function validateString($str) { | ||
116 | if (!empty($str) && strlen($str) > 3 && preg_match('/\S/', $str)) { | ||
117 | return true; | ||
118 | } else { | ||
119 | return false; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * turn on/off trigram counting | ||
125 | * | ||
126 | * @access public | ||
127 | * @param bool $bool true for on, false for off | ||
128 | */ | ||
129 | function prepareTrigram($bool = true) | ||
130 | { | ||
131 | $this->_compile_trigram = $bool; | ||
132 | } | ||
133 | |||
134 | /** | ||
135 | * turn on/off unicode block counting | ||
136 | * | ||
137 | * @access public | ||
138 | * @param bool $bool true for on, false for off | ||
139 | */ | ||
140 | function prepareUnicode($bool = true) | ||
141 | { | ||
142 | $this->_compile_unicode = $bool; | ||
143 | } | ||
144 | |||
145 | /** | ||
146 | * turn on/off padding the beginning of the sample string | ||
147 | * | ||
148 | * @access public | ||
149 | * @param bool $bool true for on, false for off | ||
150 | */ | ||
151 | function setPadStart($bool = true) | ||
152 | { | ||
153 | $this->_trigram_pad_start = $bool; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * Should the unicode block counter skip non-alphabetical ascii chars? | ||
158 | * | ||
159 | * @access public | ||
160 | * @param bool $bool true for on, false for off | ||
161 | */ | ||
162 | function setUnicodeSkipSymbols($bool = true) | ||
163 | { | ||
164 | $this->_unicode_skip_symbols = $bool; | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Returns the trigram ranks for the text sample | ||
169 | * | ||
170 | * @access public | ||
171 | * @return array trigram ranks in the text sample | ||
172 | */ | ||
173 | function &getTrigramRanks() | ||
174 | { | ||
175 | return $this->_trigram_ranks; | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * Return the trigram freqency table | ||
180 | * | ||
181 | * only used in testing to make sure the parser is working | ||
182 | * | ||
183 | * @access public | ||
184 | * @return array trigram freqencies in the text sample | ||
185 | */ | ||
186 | function &getTrigramFreqs() | ||
187 | { | ||
188 | return $this->_trigram; | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * returns the array of unicode blocks | ||
193 | * | ||
194 | * @access public | ||
195 | * @return array unicode blocks in the text sample | ||
196 | */ | ||
197 | function &getUnicodeBlocks() | ||
198 | { | ||
199 | return $this->_unicode_blocks; | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * Executes the parsing operation | ||
204 | * | ||
205 | * Be sure to call the set*() functions to set options and the | ||
206 | * prepare*() functions first to tell it what kind of data to compute | ||
207 | * | ||
208 | * Afterwards the get*() functions can be used to access the compiled | ||
209 | * information. | ||
210 | * | ||
211 | * @access public | ||
212 | */ | ||
213 | function analyze() | ||
214 | { | ||
215 | $len = strlen($this->_string); | ||
216 | $byte_counter = 0; | ||
217 | |||
218 | |||
219 | // unicode startup | ||
220 | if ($this->_compile_unicode) { | ||
221 | $blocks = $this->_read_unicode_block_db(); | ||
222 | $block_count = count($blocks); | ||
223 | |||
224 | $skipped_count = 0; | ||
225 | $unicode_chars = array(); | ||
226 | } | ||
227 | |||
228 | // trigram startup | ||
229 | if ($this->_compile_trigram) { | ||
230 | // initialize them as blank so the parser will skip the first two | ||
231 | // (since it skips trigrams with more than 2 contiguous spaces) | ||
232 | $a = ' '; | ||
233 | $b = ' '; | ||
234 | |||
235 | // kludge | ||
236 | // if it finds a valid trigram to start and the start pad option is | ||
237 | // off, then set a variable that will be used to reduce this | ||
238 | // trigram after parsing has finished | ||
239 | if (!$this->_trigram_pad_start) { | ||
240 | $a = $this->_next_char($this->_string, $byte_counter, true); | ||
241 | |||
242 | if ($a != ' ') { | ||
243 | $b = $this->_next_char($this->_string, $byte_counter, true); | ||
244 | $dropone = " $a$b"; | ||
245 | } | ||
246 | |||
247 | $byte_counter = 0; | ||
248 | $a = ' '; | ||
249 | $b = ' '; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | while ($byte_counter < $len) { | ||
254 | $char = $this->_next_char($this->_string, $byte_counter, true); | ||
255 | |||
256 | |||
257 | // language trigram detection | ||
258 | if ($this->_compile_trigram) { | ||
259 | if (!($b == ' ' && ($a == ' ' || $char == ' '))) { | ||
260 | if (!isset($this->_trigram[$a . $b . $char])) { | ||
261 | $this->_trigram[$a . $b . $char] = 1; | ||
262 | } else { | ||
263 | $this->_trigram[$a . $b . $char]++; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | $a = $b; | ||
268 | $b = $char; | ||
269 | } | ||
270 | |||
271 | // unicode block detection | ||
272 | if ($this->_compile_unicode) { | ||
273 | if ($this->_unicode_skip_symbols | ||
274 | && strlen($char) == 1 | ||
275 | && ($char < 'A' || $char > 'z' | ||
276 | || ($char > 'Z' && $char < 'a')) | ||
277 | && $char != "'") { // does not skip the apostrophe | ||
278 | // since it's included in the language | ||
279 | // models | ||
280 | |||
281 | $skipped_count++; | ||
282 | continue; | ||
283 | } | ||
284 | |||
285 | // build an array of all the characters | ||
286 | if (isset($unicode_chars[$char])) { | ||
287 | $unicode_chars[$char]++; | ||
288 | } else { | ||
289 | $unicode_chars[$char] = 1; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | // todo: add byte detection here | ||
294 | } | ||
295 | |||
296 | // unicode cleanup | ||
297 | if ($this->_compile_unicode) { | ||
298 | foreach ($unicode_chars as $utf8_char => $count) { | ||
299 | $search_result = $this->_unicode_block_name( | ||
300 | $this->_utf8char2unicode($utf8_char), $blocks, $block_count); | ||
301 | |||
302 | if ($search_result != -1) { | ||
303 | $block_name = $search_result[2]; | ||
304 | } else { | ||
305 | $block_name = '[Malformatted]'; | ||
306 | } | ||
307 | |||
308 | if (isset($this->_unicode_blocks[$block_name])) { | ||
309 | $this->_unicode_blocks[$block_name] += $count; | ||
310 | } else { | ||
311 | $this->_unicode_blocks[$block_name] = $count; | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | |||
317 | // trigram cleanup | ||
318 | if ($this->_compile_trigram) { | ||
319 | // pad the end | ||
320 | if ($b != ' ') { | ||
321 | if (!isset($this->_trigram["$a$b "])) { | ||
322 | $this->_trigram["$a$b "] = 1; | ||
323 | } else { | ||
324 | $this->_trigram["$a$b "]++; | ||
325 | } | ||
326 | } | ||
327 | |||
328 | // perl compatibility; Language::Guess does not pad the beginning | ||
329 | // kludge | ||
330 | if (isset($dropone)) { | ||
331 | if ($this->_trigram[$dropone] == 1) { | ||
332 | unset($this->_trigram[$dropone]); | ||
333 | } else { | ||
334 | $this->_trigram[$dropone]--; | ||
335 | } | ||
336 | } | ||
337 | |||
338 | if (!empty($this->_trigram)) { | ||
339 | $this->_trigram_ranks = $this->_arr_rank($this->_trigram); | ||
340 | } else { | ||
341 | $this->_trigram_ranks = array(); | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | |||
347 | /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/language-detect/lang.dat b/inc/3rdparty/libraries/language-detect/lang.dat deleted file mode 100644 index c2a44f56..00000000 --- a/inc/3rdparty/libraries/language-detect/lang.dat +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | a:2:{s:7:"trigram";a:52:{s:8:"albanian";a:300:{s:4:"të ";s:1:"0";s:4:" të";s:1:"1";s:4:"në ";s:1:"2";s:4:"për";s:1:"3";s:4:" pë";s:1:"4";s:3:" e ";s:1:"5";s:3:"sht";s:1:"6";s:4:" në";s:1:"7";s:3:" sh";s:1:"8";s:3:"se ";s:1:"9";s:3:"et ";s:2:"10";s:4:"ë s";s:2:"11";s:4:"ë t";s:2:"12";s:3:" se";s:2:"13";s:3:"he ";s:2:"14";s:4:"jë ";s:2:"15";s:4:"ër ";s:2:"16";s:3:"dhe";s:2:"17";s:3:" pa";s:2:"18";s:4:"ë n";s:2:"19";s:4:"ë p";s:2:"20";s:4:" që";s:2:"21";s:3:" dh";s:2:"22";s:4:"një";s:2:"23";s:4:"ë m";s:2:"24";s:3:" nj";s:2:"25";s:4:"ësh";s:2:"26";s:3:"in ";s:2:"27";s:3:" me";s:2:"28";s:4:"që ";s:2:"29";s:3:" po";s:2:"30";s:3:"e n";s:2:"31";s:3:"e t";s:2:"32";s:3:"ish";s:2:"33";s:4:"më ";s:2:"34";s:4:"së ";s:2:"35";s:3:"me ";s:2:"36";s:4:"htë";s:2:"37";s:3:" ka";s:2:"38";s:3:" si";s:2:"39";s:3:"e k";s:2:"40";s:3:"e p";s:2:"41";s:3:" i ";s:2:"42";s:4:"anë";s:2:"43";s:3:"ar ";s:2:"44";s:3:" nu";s:2:"45";s:3:"und";s:2:"46";s:3:"ve ";s:2:"47";s:4:" ës";s:2:"48";s:3:"e s";s:2:"49";s:4:" më";s:2:"50";s:3:"nuk";s:2:"51";s:3:"par";s:2:"52";s:3:"uar";s:2:"53";s:3:"uk ";s:2:"54";s:3:"jo ";s:2:"55";s:4:"rë ";s:2:"56";s:3:"ta ";s:2:"57";s:4:"ë f";s:2:"58";s:3:"en ";s:2:"59";s:3:"it ";s:2:"60";s:3:"min";s:2:"61";s:3:"het";s:2:"62";s:3:"n e";s:2:"63";s:3:"ri ";s:2:"64";s:3:"shq";s:2:"65";s:4:"ë d";s:2:"66";s:3:" do";s:2:"67";s:3:" nd";s:2:"68";s:3:"sh ";s:2:"69";s:4:"ën ";s:2:"70";s:4:"atë";s:2:"71";s:3:"hqi";s:2:"72";s:3:"ist";s:2:"73";s:4:"ë q";s:2:"74";s:3:" gj";s:2:"75";s:3:" ng";s:2:"76";s:3:" th";s:2:"77";s:3:"a n";s:2:"78";s:3:"do ";s:2:"79";s:3:"end";s:2:"80";s:3:"imi";s:2:"81";s:3:"ndi";s:2:"82";s:3:"r t";s:2:"83";s:3:"rat";s:2:"84";s:4:"ë b";s:2:"85";s:4:"ëri";s:2:"86";s:3:" mu";s:2:"87";s:3:"art";s:2:"88";s:3:"ash";s:2:"89";s:3:"qip";s:2:"90";s:3:" ko";s:2:"91";s:3:"e m";s:2:"92";s:3:"edh";s:2:"93";s:3:"eri";s:2:"94";s:3:"je ";s:2:"95";s:3:"ka ";s:2:"96";s:3:"nga";s:2:"97";s:3:"si ";s:2:"98";s:3:"te ";s:2:"99";s:4:"ë k";s:3:"100";s:4:"ësi";s:3:"101";s:3:" ma";s:3:"102";s:3:" ti";s:3:"103";s:3:"eve";s:3:"104";s:3:"hje";s:3:"105";s:3:"ira";s:3:"106";s:3:"mun";s:3:"107";s:3:"on ";s:3:"108";s:3:"po ";s:3:"109";s:3:"re ";s:3:"110";s:3:" pr";s:3:"111";s:3:"im ";s:3:"112";s:3:"lit";s:3:"113";s:3:"o t";s:3:"114";s:3:"ur ";s:3:"115";s:4:"ë e";s:3:"116";s:4:"ë v";s:3:"117";s:4:"ët ";s:3:"118";s:3:" ku";s:3:"119";s:4:" së";s:3:"120";s:3:"e d";s:3:"121";s:3:"es ";s:3:"122";s:3:"ga ";s:3:"123";s:3:"iti";s:3:"124";s:3:"jet";s:3:"125";s:4:"ndë";s:3:"126";s:3:"oli";s:3:"127";s:3:"shi";s:3:"128";s:3:"tje";s:3:"129";s:4:" bë";s:3:"130";s:3:" z ";s:3:"131";s:3:"gje";s:3:"132";s:3:"kan";s:3:"133";s:3:"shk";s:3:"134";s:4:"ënd";s:3:"135";s:4:"ës ";s:3:"136";s:3:" de";s:3:"137";s:3:" kj";s:3:"138";s:3:" ru";s:3:"139";s:3:" vi";s:3:"140";s:3:"ara";s:3:"141";s:3:"gov";s:3:"142";s:3:"kjo";s:3:"143";s:3:"or ";s:3:"144";s:3:"r p";s:3:"145";s:3:"rto";s:3:"146";s:3:"rug";s:3:"147";s:3:"tet";s:3:"148";s:3:"ugo";s:3:"149";s:3:"ali";s:3:"150";s:3:"arr";s:3:"151";s:3:"at ";s:3:"152";s:3:"d t";s:3:"153";s:3:"ht ";s:3:"154";s:3:"i p";s:3:"155";s:4:"ipë";s:3:"156";s:3:"izi";s:3:"157";s:4:"jnë";s:3:"158";s:3:"n n";s:3:"159";s:3:"ohe";s:3:"160";s:3:"shu";s:3:"161";s:4:"shë";s:3:"162";s:3:"t e";s:3:"163";s:3:"tik";s:3:"164";s:3:"a e";s:3:"165";s:4:"arë";s:3:"166";s:4:"etë";s:3:"167";s:3:"hum";s:3:"168";s:3:"nd ";s:3:"169";s:3:"ndr";s:3:"170";s:3:"osh";s:3:"171";s:3:"ova";s:3:"172";s:3:"rim";s:3:"173";s:3:"tos";s:3:"174";s:3:"va ";s:3:"175";s:3:" fa";s:3:"176";s:3:" fi";s:3:"177";s:3:"a s";s:3:"178";s:3:"hen";s:3:"179";s:3:"i n";s:3:"180";s:3:"mar";s:3:"181";s:3:"ndo";s:3:"182";s:3:"por";s:3:"183";s:3:"ris";s:3:"184";s:3:"sa ";s:3:"185";s:3:"sis";s:3:"186";s:4:"tës";s:3:"187";s:4:"umë";s:3:"188";s:3:"viz";s:3:"189";s:3:"zit";s:3:"190";s:3:" di";s:3:"191";s:3:" mb";s:3:"192";s:3:"aj ";s:3:"193";s:3:"ana";s:3:"194";s:3:"ata";s:3:"195";s:4:"dër";s:3:"196";s:3:"e a";s:3:"197";s:3:"esh";s:3:"198";s:3:"ime";s:3:"199";s:3:"jes";s:3:"200";s:3:"lar";s:3:"201";s:3:"n s";s:3:"202";s:3:"nte";s:3:"203";s:3:"pol";s:3:"204";s:3:"r n";s:3:"205";s:3:"ran";s:3:"206";s:3:"res";s:3:"207";s:4:"rrë";s:3:"208";s:3:"tar";s:3:"209";s:4:"ë a";s:3:"210";s:4:"ë i";s:3:"211";s:3:" at";s:3:"212";s:3:" jo";s:3:"213";s:4:" kë";s:3:"214";s:3:" re";s:3:"215";s:3:"a k";s:3:"216";s:3:"ai ";s:3:"217";s:3:"akt";s:3:"218";s:4:"hë ";s:3:"219";s:4:"hën";s:3:"220";s:3:"i i";s:3:"221";s:3:"i m";s:3:"222";s:3:"ia ";s:3:"223";s:3:"men";s:3:"224";s:3:"nis";s:3:"225";s:3:"shm";s:3:"226";s:3:"str";s:3:"227";s:3:"t k";s:3:"228";s:3:"t n";s:3:"229";s:3:"t s";s:3:"230";s:4:"ë g";s:3:"231";s:4:"ërk";s:3:"232";s:4:"ëve";s:3:"233";s:3:" ai";s:3:"234";s:3:" ci";s:3:"235";s:3:" ed";s:3:"236";s:3:" ja";s:3:"237";s:3:" kr";s:3:"238";s:3:" qe";s:3:"239";s:3:" ta";s:3:"240";s:3:" ve";s:3:"241";s:3:"a p";s:3:"242";s:3:"cil";s:3:"243";s:3:"el ";s:3:"244";s:4:"erë";s:3:"245";s:3:"gji";s:3:"246";s:3:"hte";s:3:"247";s:3:"i t";s:3:"248";s:3:"jen";s:3:"249";s:3:"jit";s:3:"250";s:3:"k d";s:3:"251";s:4:"mën";s:3:"252";s:3:"n t";s:3:"253";s:3:"nyr";s:3:"254";s:3:"ori";s:3:"255";s:3:"pas";s:3:"256";s:3:"ra ";s:3:"257";s:3:"rie";s:3:"258";s:4:"rës";s:3:"259";s:3:"tor";s:3:"260";s:3:"uaj";s:3:"261";s:3:"yre";s:3:"262";s:4:"ëm ";s:3:"263";s:4:"ëny";s:3:"264";s:3:" ar";s:3:"265";s:3:" du";s:3:"266";s:3:" ga";s:3:"267";s:3:" je";s:3:"268";s:4:"dës";s:3:"269";s:3:"e e";s:3:"270";s:3:"e z";s:3:"271";s:3:"ha ";s:3:"272";s:3:"hme";s:3:"273";s:3:"ika";s:3:"274";s:3:"ini";s:3:"275";s:3:"ite";s:3:"276";s:3:"ith";s:3:"277";s:3:"koh";s:3:"278";s:3:"kra";s:3:"279";s:3:"ku ";s:3:"280";s:3:"lim";s:3:"281";s:3:"lis";s:3:"282";s:4:"qën";s:3:"283";s:4:"rën";s:3:"284";s:3:"s s";s:3:"285";s:3:"t d";s:3:"286";s:3:"t t";s:3:"287";s:3:"tir";s:3:"288";s:4:"tën";s:3:"289";s:3:"ver";s:3:"290";s:4:"ë j";s:3:"291";s:3:" ba";s:3:"292";s:3:" in";s:3:"293";s:3:" tr";s:3:"294";s:3:" zg";s:3:"295";s:3:"a a";s:3:"296";s:3:"a m";s:3:"297";s:3:"a t";s:3:"298";s:3:"abr";s:3:"299";}s:6:"arabic";a:300:{s:5:" ال";s:1:"0";s:6:"الع";s:1:"1";s:6:"لعر";s:1:"2";s:6:"عرا";s:1:"3";s:6:"راق";s:1:"4";s:5:" في";s:1:"5";s:5:"في ";s:1:"6";s:5:"ين ";s:1:"7";s:5:"ية ";s:1:"8";s:5:"ن ا";s:1:"9";s:6:"الم";s:2:"10";s:5:"ات ";s:2:"11";s:5:"من ";s:2:"12";s:5:"ي ا";s:2:"13";s:5:" من";s:2:"14";s:6:"الأ";s:2:"15";s:5:"ة ا";s:2:"16";s:5:"اق ";s:2:"17";s:5:" وا";s:2:"18";s:5:"اء ";s:2:"19";s:6:"الإ";s:2:"20";s:5:" أن";s:2:"21";s:6:"وال";s:2:"22";s:5:"ما ";s:2:"23";s:5:" عل";s:2:"24";s:5:"لى ";s:2:"25";s:5:"ت ا";s:2:"26";s:5:"ون ";s:2:"27";s:5:"هم ";s:2:"28";s:6:"اقي";s:2:"29";s:5:"ام ";s:2:"30";s:5:"ل ا";s:2:"31";s:5:"أن ";s:2:"32";s:5:"م ا";s:2:"33";s:6:"الت";s:2:"34";s:5:"لا ";s:2:"35";s:6:"الا";s:2:"36";s:5:"ان ";s:2:"37";s:5:"ها ";s:2:"38";s:5:"ال ";s:2:"39";s:5:"ة و";s:2:"40";s:5:"ا ا";s:2:"41";s:6:"رها";s:2:"42";s:6:"لام";s:2:"43";s:6:"يين";s:2:"44";s:5:" ول";s:2:"45";s:6:"لأم";s:2:"46";s:5:"نا ";s:2:"47";s:6:"على";s:2:"48";s:5:"ن ي";s:2:"49";s:6:"الب";s:2:"50";s:5:"اد ";s:2:"51";s:6:"الق";s:2:"52";s:5:"د ا";s:2:"53";s:5:"ذا ";s:2:"54";s:5:"ه ا";s:2:"55";s:5:" با";s:2:"56";s:6:"الد";s:2:"57";s:5:"ب ا";s:2:"58";s:6:"مري";s:2:"59";s:5:"لم ";s:2:"60";s:5:" إن";s:2:"61";s:5:" لل";s:2:"62";s:6:"سلا";s:2:"63";s:6:"أمر";s:2:"64";s:6:"ريك";s:2:"65";s:5:"مة ";s:2:"66";s:5:"ى ا";s:2:"67";s:5:"ا ي";s:2:"68";s:5:" عن";s:2:"69";s:5:" هذ";s:2:"70";s:5:"ء ا";s:2:"71";s:5:"ر ا";s:2:"72";s:6:"كان";s:2:"73";s:6:"قتل";s:2:"74";s:6:"إسل";s:2:"75";s:6:"الح";s:2:"76";s:5:"وا ";s:2:"77";s:5:" إل";s:2:"78";s:5:"ا أ";s:2:"79";s:6:"بال";s:2:"80";s:5:"ن م";s:2:"81";s:6:"الس";s:2:"82";s:5:"رة ";s:2:"83";s:6:"لإس";s:2:"84";s:5:"ن و";s:2:"85";s:6:"هاب";s:2:"86";s:5:"ي و";s:2:"87";s:5:"ير ";s:2:"88";s:5:" كا";s:2:"89";s:5:"لة ";s:2:"90";s:6:"يات";s:2:"91";s:5:" لا";s:2:"92";s:6:"انت";s:2:"93";s:5:"ن أ";s:2:"94";s:6:"يكي";s:2:"95";s:6:"الر";s:2:"96";s:6:"الو";s:2:"97";s:5:"ة ف";s:2:"98";s:5:"دة ";s:2:"99";s:6:"الج";s:3:"100";s:5:"قي ";s:3:"101";s:5:"وي ";s:3:"102";s:6:"الذ";s:3:"103";s:6:"الش";s:3:"104";s:6:"امي";s:3:"105";s:6:"اني";s:3:"106";s:5:"ذه ";s:3:"107";s:5:"عن ";s:3:"108";s:6:"لما";s:3:"109";s:6:"هذه";s:3:"110";s:5:"ول ";s:3:"111";s:5:"اف ";s:3:"112";s:6:"اوي";s:3:"113";s:6:"بري";s:3:"114";s:5:"ة ل";s:3:"115";s:5:" أم";s:3:"116";s:5:" لم";s:3:"117";s:5:" ما";s:3:"118";s:5:"يد ";s:3:"119";s:5:" أي";s:3:"120";s:6:"إره";s:3:"121";s:5:"ع ا";s:3:"122";s:6:"عمل";s:3:"123";s:6:"ولا";s:3:"124";s:6:"إلى";s:3:"125";s:6:"ابي";s:3:"126";s:5:"ن ف";s:3:"127";s:6:"ختط";s:3:"128";s:5:"لك ";s:3:"129";s:5:"نه ";s:3:"130";s:5:"ني ";s:3:"131";s:5:"إن ";s:3:"132";s:6:"دين";s:3:"133";s:5:"ف ا";s:3:"134";s:6:"لذي";s:3:"135";s:5:"ي أ";s:3:"136";s:5:"ي ب";s:3:"137";s:5:" وأ";s:3:"138";s:5:"ا ع";s:3:"139";s:6:"الخ";s:3:"140";s:5:"تل ";s:3:"141";s:5:"تي ";s:3:"142";s:5:"قد ";s:3:"143";s:6:"لدي";s:3:"144";s:5:" كل";s:3:"145";s:5:" مع";s:3:"146";s:5:"اب ";s:3:"147";s:6:"اخت";s:3:"148";s:5:"ار ";s:3:"149";s:6:"الن";s:3:"150";s:6:"علا";s:3:"151";s:5:"م و";s:3:"152";s:5:"مع ";s:3:"153";s:5:"س ا";s:3:"154";s:5:"كل ";s:3:"155";s:6:"لاء";s:3:"156";s:5:"ن ب";s:3:"157";s:5:"ن ت";s:3:"158";s:5:"ي م";s:3:"159";s:6:"عرب";s:3:"160";s:5:"م ب";s:3:"161";s:5:" وق";s:3:"162";s:5:" يق";s:3:"163";s:5:"ا ل";s:3:"164";s:5:"ا م";s:3:"165";s:6:"الف";s:3:"166";s:6:"تطا";s:3:"167";s:6:"داد";s:3:"168";s:6:"لمس";s:3:"169";s:5:"له ";s:3:"170";s:6:"هذا";s:3:"171";s:5:" مح";s:3:"172";s:6:"ؤلا";s:3:"173";s:5:"بي ";s:3:"174";s:5:"ة م";s:3:"175";s:5:"ن ل";s:3:"176";s:6:"هؤل";s:3:"177";s:5:"كن ";s:3:"178";s:6:"لإر";s:3:"179";s:6:"لتي";s:3:"180";s:5:" أو";s:3:"181";s:5:" ان";s:3:"182";s:5:" عم";s:3:"183";s:5:"ا ف";s:3:"184";s:5:"ة أ";s:3:"185";s:6:"طاف";s:3:"186";s:5:"عب ";s:3:"187";s:5:"ل م";s:3:"188";s:5:"ن ع";s:3:"189";s:5:"ور ";s:3:"190";s:5:"يا ";s:3:"191";s:5:" يس";s:3:"192";s:5:"ا ت";s:3:"193";s:5:"ة ب";s:3:"194";s:6:"راء";s:3:"195";s:6:"عال";s:3:"196";s:6:"قوا";s:3:"197";s:6:"قية";s:3:"198";s:6:"لعا";s:3:"199";s:5:"م ي";s:3:"200";s:5:"مي ";s:3:"201";s:6:"مية";s:3:"202";s:6:"نية";s:3:"203";s:5:"أي ";s:3:"204";s:6:"ابا";s:3:"205";s:6:"بغد";s:3:"206";s:5:"بل ";s:3:"207";s:5:"رب ";s:3:"208";s:6:"عما";s:3:"209";s:6:"غدا";s:3:"210";s:6:"مال";s:3:"211";s:6:"ملي";s:3:"212";s:5:"يس ";s:3:"213";s:5:" بأ";s:3:"214";s:5:" بع";s:3:"215";s:5:" بغ";s:3:"216";s:5:" وم";s:3:"217";s:6:"بات";s:3:"218";s:6:"بية";s:3:"219";s:6:"ذلك";s:3:"220";s:5:"عة ";s:3:"221";s:6:"قاو";s:3:"222";s:6:"قيي";s:3:"223";s:5:"كي ";s:3:"224";s:5:"م م";s:3:"225";s:5:"ي ع";s:3:"226";s:5:" عر";s:3:"227";s:5:" قا";s:3:"228";s:5:"ا و";s:3:"229";s:5:"رى ";s:3:"230";s:5:"ق ا";s:3:"231";s:6:"وات";s:3:"232";s:5:"وم ";s:3:"233";s:5:" هؤ";s:3:"234";s:5:"ا ب";s:3:"235";s:6:"دام";s:3:"236";s:5:"دي ";s:3:"237";s:6:"رات";s:3:"238";s:6:"شعب";s:3:"239";s:6:"لان";s:3:"240";s:6:"لشع";s:3:"241";s:6:"لقو";s:3:"242";s:6:"ليا";s:3:"243";s:5:"ن ه";s:3:"244";s:5:"ي ت";s:3:"245";s:5:"ي ي";s:3:"246";s:5:" وه";s:3:"247";s:5:" يح";s:3:"248";s:6:"جرا";s:3:"249";s:6:"جما";s:3:"250";s:6:"حمد";s:3:"251";s:5:"دم ";s:3:"252";s:5:"كم ";s:3:"253";s:6:"لاو";s:3:"254";s:6:"لره";s:3:"255";s:6:"ماع";s:3:"256";s:5:"ن ق";s:3:"257";s:5:"نة ";s:3:"258";s:5:"هي ";s:3:"259";s:5:" بل";s:3:"260";s:5:" به";s:3:"261";s:5:" له";s:3:"262";s:5:" وي";s:3:"263";s:5:"ا ك";s:3:"264";s:6:"اذا";s:3:"265";s:5:"اع ";s:3:"266";s:5:"ت م";s:3:"267";s:6:"تخا";s:3:"268";s:6:"خاب";s:3:"269";s:5:"ر م";s:3:"270";s:6:"لمت";s:3:"271";s:6:"مسل";s:3:"272";s:5:"ى أ";s:3:"273";s:6:"يست";s:3:"274";s:6:"يطا";s:3:"275";s:5:" لأ";s:3:"276";s:5:" لي";s:3:"277";s:6:"أمن";s:3:"278";s:6:"است";s:3:"279";s:6:"بعض";s:3:"280";s:5:"ة ت";s:3:"281";s:5:"ري ";s:3:"282";s:6:"صدا";s:3:"283";s:5:"ق و";s:3:"284";s:6:"قول";s:3:"285";s:5:"مد ";s:3:"286";s:6:"نتخ";s:3:"287";s:6:"نفس";s:3:"288";s:6:"نها";s:3:"289";s:6:"هنا";s:3:"290";s:6:"أعم";s:3:"291";s:6:"أنه";s:3:"292";s:6:"ائن";s:3:"293";s:6:"الآ";s:3:"294";s:6:"الك";s:3:"295";s:5:"حة ";s:3:"296";s:5:"د م";s:3:"297";s:5:"ر ع";s:3:"298";s:6:"ربي";s:3:"299";}s:5:"azeri";a:300:{s:4:"lər";s:1:"0";s:3:"in ";s:1:"1";s:4:"ın ";s:1:"2";s:3:"lar";s:1:"3";s:3:"da ";s:1:"4";s:3:"an ";s:1:"5";s:3:"ir ";s:1:"6";s:4:"də ";s:1:"7";s:3:"ki ";s:1:"8";s:3:" bi";s:1:"9";s:4:"ən ";s:2:"10";s:4:"əri";s:2:"11";s:4:"arı";s:2:"12";s:4:"ər ";s:2:"13";s:3:"dir";s:2:"14";s:3:"nda";s:2:"15";s:3:" ki";s:2:"16";s:3:"rin";s:2:"17";s:4:"nın";s:2:"18";s:4:"əsi";s:2:"19";s:3:"ini";s:2:"20";s:3:" ed";s:2:"21";s:3:" qa";s:2:"22";s:4:" tə";s:2:"23";s:3:" ba";s:2:"24";s:3:" ol";s:2:"25";s:4:"ası";s:2:"26";s:4:"ilə";s:2:"27";s:4:"rın";s:2:"28";s:3:" ya";s:2:"29";s:4:"anı";s:2:"30";s:4:" və";s:2:"31";s:4:"ndə";s:2:"32";s:3:"ni ";s:2:"33";s:3:"ara";s:2:"34";s:5:"ını";s:2:"35";s:4:"ınd";s:2:"36";s:3:" bu";s:2:"37";s:3:"si ";s:2:"38";s:3:"ib ";s:2:"39";s:3:"aq ";s:2:"40";s:4:"dən";s:2:"41";s:3:"iya";s:2:"42";s:4:"nə ";s:2:"43";s:4:"rə ";s:2:"44";s:3:"n b";s:2:"45";s:4:"sın";s:2:"46";s:4:"və ";s:2:"47";s:3:"iri";s:2:"48";s:4:"lə ";s:2:"49";s:3:"nin";s:2:"50";s:4:"əli";s:2:"51";s:3:" de";s:2:"52";s:4:" mü";s:2:"53";s:3:"bir";s:2:"54";s:3:"n s";s:2:"55";s:3:"ri ";s:2:"56";s:4:"ək ";s:2:"57";s:3:" az";s:2:"58";s:4:" sə";s:2:"59";s:3:"ar ";s:2:"60";s:3:"bil";s:2:"61";s:4:"zər";s:2:"62";s:3:"bu ";s:2:"63";s:3:"dan";s:2:"64";s:3:"edi";s:2:"65";s:3:"ind";s:2:"66";s:3:"man";s:2:"67";s:3:"un ";s:2:"68";s:5:"ərə";s:2:"69";s:3:" ha";s:2:"70";s:3:"lan";s:2:"71";s:4:"yyə";s:2:"72";s:3:"iyy";s:2:"73";s:3:" il";s:2:"74";s:3:" ne";s:2:"75";s:3:"r k";s:2:"76";s:4:"ə b";s:2:"77";s:3:" is";s:2:"78";s:3:"na ";s:2:"79";s:3:"nun";s:2:"80";s:4:"ır ";s:2:"81";s:3:" da";s:2:"82";s:4:" hə";s:2:"83";s:3:"a b";s:2:"84";s:4:"inə";s:2:"85";s:3:"sin";s:2:"86";s:3:"yan";s:2:"87";s:4:"ərb";s:2:"88";s:4:" də";s:2:"89";s:4:" mə";s:2:"90";s:4:" qə";s:2:"91";s:4:"dır";s:2:"92";s:3:"li ";s:2:"93";s:3:"ola";s:2:"94";s:3:"rba";s:2:"95";s:4:"azə";s:2:"96";s:3:"can";s:2:"97";s:4:"lı ";s:2:"98";s:3:"nla";s:2:"99";s:3:" et";s:3:"100";s:4:" gö";s:3:"101";s:4:"alı";s:3:"102";s:3:"ayc";s:3:"103";s:3:"bay";s:3:"104";s:3:"eft";s:3:"105";s:3:"ist";s:3:"106";s:3:"n i";s:3:"107";s:3:"nef";s:3:"108";s:4:"tlə";s:3:"109";s:3:"yca";s:3:"110";s:4:"yət";s:3:"111";s:5:"əcə";s:3:"112";s:3:" la";s:3:"113";s:3:"ild";s:3:"114";s:4:"nı ";s:3:"115";s:3:"tin";s:3:"116";s:3:"ldi";s:3:"117";s:3:"lik";s:3:"118";s:3:"n h";s:3:"119";s:3:"n m";s:3:"120";s:3:"oyu";s:3:"121";s:3:"raq";s:3:"122";s:3:"ya ";s:3:"123";s:4:"əti";s:3:"124";s:3:" ar";s:3:"125";s:3:"ada";s:3:"126";s:4:"edə";s:3:"127";s:3:"mas";s:3:"128";s:4:"sı ";s:3:"129";s:4:"ına";s:3:"130";s:4:"ə d";s:3:"131";s:5:"ələ";s:3:"132";s:4:"ayı";s:3:"133";s:3:"iyi";s:3:"134";s:3:"lma";s:3:"135";s:4:"mək";s:3:"136";s:3:"n d";s:3:"137";s:3:"ti ";s:3:"138";s:3:"yin";s:3:"139";s:3:"yun";s:3:"140";s:4:"ət ";s:3:"141";s:4:"azı";s:3:"142";s:3:"ft ";s:3:"143";s:3:"i t";s:3:"144";s:3:"lli";s:3:"145";s:3:"n a";s:3:"146";s:3:"ra ";s:3:"147";s:4:" cə";s:3:"148";s:4:" gə";s:3:"149";s:3:" ko";s:3:"150";s:4:" nə";s:3:"151";s:3:" oy";s:3:"152";s:3:"a d";s:3:"153";s:3:"ana";s:3:"154";s:4:"cək";s:3:"155";s:3:"eyi";s:3:"156";s:3:"ilm";s:3:"157";s:3:"irl";s:3:"158";s:3:"lay";s:3:"159";s:3:"liy";s:3:"160";s:3:"lub";s:3:"161";s:4:"n ə";s:3:"162";s:3:"ril";s:3:"163";s:4:"rlə";s:3:"164";s:3:"unu";s:3:"165";s:3:"ver";s:3:"166";s:4:"ün ";s:3:"167";s:4:"ə o";s:3:"168";s:4:"əni";s:3:"169";s:3:" he";s:3:"170";s:3:" ma";s:3:"171";s:3:" on";s:3:"172";s:3:" pa";s:3:"173";s:3:"ala";s:3:"174";s:3:"dey";s:3:"175";s:3:"i m";s:3:"176";s:3:"ima";s:3:"177";s:4:"lmə";s:3:"178";s:4:"mət";s:3:"179";s:3:"par";s:3:"180";s:4:"yə ";s:3:"181";s:4:"ətl";s:3:"182";s:3:" al";s:3:"183";s:3:" mi";s:3:"184";s:3:" sa";s:3:"185";s:4:" əl";s:3:"186";s:4:"adı";s:3:"187";s:4:"akı";s:3:"188";s:3:"and";s:3:"189";s:3:"ard";s:3:"190";s:3:"art";s:3:"191";s:3:"ayi";s:3:"192";s:3:"i a";s:3:"193";s:3:"i q";s:3:"194";s:3:"i y";s:3:"195";s:3:"ili";s:3:"196";s:3:"ill";s:3:"197";s:4:"isə";s:3:"198";s:3:"n o";s:3:"199";s:3:"n q";s:3:"200";s:3:"olu";s:3:"201";s:3:"rla";s:3:"202";s:4:"stə";s:3:"203";s:4:"sə ";s:3:"204";s:3:"tan";s:3:"205";s:3:"tel";s:3:"206";s:3:"yar";s:3:"207";s:5:"ədə";s:3:"208";s:3:" me";s:3:"209";s:4:" rə";s:3:"210";s:3:" ve";s:3:"211";s:3:" ye";s:3:"212";s:3:"a k";s:3:"213";s:3:"at ";s:3:"214";s:4:"baş";s:3:"215";s:3:"diy";s:3:"216";s:3:"ent";s:3:"217";s:3:"eti";s:3:"218";s:4:"həs";s:3:"219";s:3:"i i";s:3:"220";s:3:"ik ";s:3:"221";s:3:"la ";s:3:"222";s:4:"miş";s:3:"223";s:3:"n n";s:3:"224";s:3:"nu ";s:3:"225";s:3:"qar";s:3:"226";s:3:"ran";s:3:"227";s:4:"tər";s:3:"228";s:3:"xan";s:3:"229";s:4:"ə a";s:3:"230";s:4:"ə g";s:3:"231";s:4:"ə t";s:3:"232";s:4:" dü";s:3:"233";s:3:"ama";s:3:"234";s:3:"b k";s:3:"235";s:3:"dil";s:3:"236";s:3:"era";s:3:"237";s:3:"etm";s:3:"238";s:3:"i b";s:3:"239";s:3:"kil";s:3:"240";s:3:"mil";s:3:"241";s:3:"n r";s:3:"242";s:3:"qla";s:3:"243";s:3:"r s";s:3:"244";s:3:"ras";s:3:"245";s:3:"siy";s:3:"246";s:3:"son";s:3:"247";s:3:"tim";s:3:"248";s:3:"yer";s:3:"249";s:4:"ə k";s:3:"250";s:4:" gü";s:3:"251";s:3:" so";s:3:"252";s:4:" sö";s:3:"253";s:3:" te";s:3:"254";s:3:" xa";s:3:"255";s:3:"ai ";s:3:"256";s:3:"bar";s:3:"257";s:3:"cti";s:3:"258";s:3:"di ";s:3:"259";s:3:"eri";s:3:"260";s:4:"gör";s:3:"261";s:4:"gün";s:3:"262";s:4:"gəl";s:3:"263";s:4:"hbə";s:3:"264";s:4:"ihə";s:3:"265";s:3:"iki";s:3:"266";s:3:"isi";s:3:"267";s:3:"lin";s:3:"268";s:3:"mai";s:3:"269";s:3:"maq";s:3:"270";s:3:"n k";s:3:"271";s:3:"n t";s:3:"272";s:3:"n v";s:3:"273";s:3:"onu";s:3:"274";s:3:"qan";s:3:"275";s:4:"qəz";s:3:"276";s:4:"tə ";s:3:"277";s:3:"xal";s:3:"278";s:3:"yib";s:3:"279";s:3:"yih";s:3:"280";s:3:"zet";s:3:"281";s:4:"zır";s:3:"282";s:4:"ıb ";s:3:"283";s:4:"ə m";s:3:"284";s:4:"əze";s:3:"285";s:3:" br";s:3:"286";s:3:" in";s:3:"287";s:4:" i̇";s:3:"288";s:3:" pr";s:3:"289";s:3:" ta";s:3:"290";s:3:" to";s:3:"291";s:5:" üç";s:3:"292";s:3:"a o";s:3:"293";s:3:"ali";s:3:"294";s:3:"ani";s:3:"295";s:3:"anl";s:3:"296";s:3:"aql";s:3:"297";s:3:"azi";s:3:"298";s:3:"bri";s:3:"299";}s:7:"bengali";a:300:{s:7:"ার ";s:1:"0";s:7:"য় ";s:1:"1";s:9:"েয়";s:1:"2";s:9:"য়া";s:1:"3";s:7:" কর";s:1:"4";s:7:"েত ";s:1:"5";s:7:" কা";s:1:"6";s:7:" পা";s:1:"7";s:7:" তা";s:1:"8";s:7:"না ";s:1:"9";s:9:"ায়";s:2:"10";s:7:"ের ";s:2:"11";s:9:"য়ে";s:2:"12";s:7:" বা";s:2:"13";s:7:"েব ";s:2:"14";s:7:" যা";s:2:"15";s:7:" হে";s:2:"16";s:7:" সা";s:2:"17";s:7:"ান ";s:2:"18";s:7:"েছ ";s:2:"19";s:7:" িন";s:2:"20";s:7:"েল ";s:2:"21";s:7:" িদ";s:2:"22";s:7:" না";s:2:"23";s:7:" িব";s:2:"24";s:7:"েক ";s:2:"25";s:7:"লা ";s:2:"26";s:7:"তা ";s:2:"27";s:7:" বઘ";s:2:"28";s:7:" িক";s:2:"29";s:9:"করে";s:2:"30";s:7:" পચ";s:2:"31";s:9:"াের";s:2:"32";s:9:"িনে";s:2:"33";s:7:"রা ";s:2:"34";s:7:" োব";s:2:"35";s:7:"কা ";s:2:"36";s:7:" কে";s:2:"37";s:7:" টা";s:2:"38";s:7:"র ক";s:2:"39";s:9:"েলা";s:2:"40";s:7:" োক";s:2:"41";s:7:" মা";s:2:"42";s:7:" োদ";s:2:"43";s:7:" োম";s:2:"44";s:7:"দর ";s:2:"45";s:7:"়া ";s:2:"46";s:9:"িদে";s:2:"47";s:9:"াকা";s:2:"48";s:9:"়েছ";s:2:"49";s:9:"েদর";s:2:"50";s:7:" আে";s:2:"51";s:5:" ও ";s:2:"52";s:7:"াল ";s:2:"53";s:7:"িট ";s:2:"54";s:7:" মু";s:2:"55";s:9:"কের";s:2:"56";s:9:"হয়";s:2:"57";s:9:"করা";s:2:"58";s:7:"পর ";s:2:"59";s:9:"পাে";s:2:"60";s:7:" এক";s:2:"61";s:7:" পদ";s:2:"62";s:9:"টাক";s:2:"63";s:7:"ড় ";s:2:"64";s:9:"কান";s:2:"65";s:7:"টা ";s:2:"66";s:9:"দગা";s:2:"67";s:9:"পদગ";s:2:"68";s:9:"াড়";s:2:"69";s:9:"োকা";s:2:"70";s:9:"ওয়";s:2:"71";s:9:"কাপ";s:2:"72";s:9:"হেয";s:2:"73";s:9:"েনর";s:2:"74";s:7:" হয";s:2:"75";s:9:"দেয";s:2:"76";s:7:"নর ";s:2:"77";s:9:"ানা";s:2:"78";s:9:"ােল";s:2:"79";s:7:" আর";s:2:"80";s:5:" ় ";s:2:"81";s:9:"বઘব";s:2:"82";s:9:"িয়";s:2:"83";s:7:" দা";s:2:"84";s:7:" সম";s:2:"85";s:9:"কার";s:2:"86";s:9:"হার";s:2:"87";s:7:"াই ";s:2:"88";s:9:"ড়া";s:2:"89";s:9:"িবি";s:2:"90";s:7:" রা";s:2:"91";s:7:" লা";s:2:"92";s:9:"নার";s:2:"93";s:9:"বহা";s:2:"94";s:7:"বা ";s:2:"95";s:9:"যায";s:2:"96";s:7:"েন ";s:2:"97";s:9:"ઘবহ";s:2:"98";s:7:" ভা";s:2:"99";s:7:" সে";s:3:"100";s:7:" োয";s:3:"101";s:7:"রর ";s:3:"102";s:9:"়ার";s:3:"103";s:9:"়াল";s:3:"104";s:7:"ગা ";s:3:"105";s:9:"থেক";s:3:"106";s:9:"ভাে";s:3:"107";s:7:"়ে ";s:3:"108";s:9:"েরর";s:3:"109";s:7:" ধর";s:3:"110";s:7:" হা";s:3:"111";s:7:"নઘ ";s:3:"112";s:9:"রেন";s:3:"113";s:9:"ােব";s:3:"114";s:9:"িড়";s:3:"115";s:7:"ির ";s:3:"116";s:7:" োথ";s:3:"117";s:9:"তার";s:3:"118";s:9:"বিভ";s:3:"119";s:9:"রেত";s:3:"120";s:9:"সাে";s:3:"121";s:9:"াকে";s:3:"122";s:9:"ােত";s:3:"123";s:9:"িভਭ";s:3:"124";s:7:"ে ব";s:3:"125";s:9:"োথে";s:3:"126";s:7:" োপ";s:3:"127";s:7:" োস";s:3:"128";s:9:"বার";s:3:"129";s:7:"ভਭ ";s:3:"130";s:7:"রন ";s:3:"131";s:7:"াম ";s:3:"132";s:7:" এখ";s:3:"133";s:7:"আর ";s:3:"134";s:9:"কাে";s:3:"135";s:7:"দন ";s:3:"136";s:9:"সাজ";s:3:"137";s:9:"ােক";s:3:"138";s:9:"ােন";s:3:"139";s:9:"েনা";s:3:"140";s:7:" ঘে";s:3:"141";s:7:" তে";s:3:"142";s:7:" রে";s:3:"143";s:9:"তেব";s:3:"144";s:7:"বন ";s:3:"145";s:9:"বઘা";s:3:"146";s:9:"েড়";s:3:"147";s:9:"েবন";s:3:"148";s:7:" খু";s:3:"149";s:7:" চা";s:3:"150";s:7:" সু";s:3:"151";s:7:"কে ";s:3:"152";s:9:"ধরে";s:3:"153";s:7:"র ো";s:3:"154";s:7:"় ি";s:3:"155";s:7:"া ি";s:3:"156";s:9:"ােথ";s:3:"157";s:9:"াਠা";s:3:"158";s:7:"িদ ";s:3:"159";s:7:"িন ";s:3:"160";s:7:" অন";s:3:"161";s:7:" আপ";s:3:"162";s:7:" আম";s:3:"163";s:7:" থা";s:3:"164";s:7:" বચ";s:3:"165";s:7:" োফ";s:3:"166";s:7:" ৌত";s:3:"167";s:9:"ঘের";s:3:"168";s:7:"তে ";s:3:"169";s:9:"ময়";s:3:"170";s:9:"যাਠ";s:3:"171";s:7:"র স";s:3:"172";s:9:"রাখ";s:3:"173";s:7:"া ব";s:3:"174";s:7:"া ো";s:3:"175";s:9:"ালা";s:3:"176";s:7:"িক ";s:3:"177";s:7:"িশ ";s:3:"178";s:7:"েখ ";s:3:"179";s:7:" এর";s:3:"180";s:7:" চઓ";s:3:"181";s:7:" িড";s:3:"182";s:7:"খন ";s:3:"183";s:9:"ড়ে";s:3:"184";s:7:"র ব";s:3:"185";s:7:"়র ";s:3:"186";s:9:"াইে";s:3:"187";s:9:"ােদ";s:3:"188";s:9:"িদন";s:3:"189";s:9:"েরন";s:3:"190";s:7:" তੴ";s:3:"191";s:9:"ছাড";s:3:"192";s:9:"জনઘ";s:3:"193";s:9:"তাই";s:3:"194";s:7:"মা ";s:3:"195";s:9:"মাে";s:3:"196";s:9:"লার";s:3:"197";s:7:"াজ ";s:3:"198";s:9:"াতা";s:3:"199";s:9:"ামা";s:3:"200";s:9:"ਊেল";s:3:"201";s:9:"ગার";s:3:"202";s:7:" সব";s:3:"203";s:9:"আপন";s:3:"204";s:9:"একট";s:3:"205";s:9:"কাি";s:3:"206";s:9:"জাই";s:3:"207";s:7:"টর ";s:3:"208";s:9:"ডজা";s:3:"209";s:9:"দেখ";s:3:"210";s:9:"পনা";s:3:"211";s:7:"রও ";s:3:"212";s:7:"লে ";s:3:"213";s:9:"হেব";s:3:"214";s:9:"াজা";s:3:"215";s:9:"ািট";s:3:"216";s:9:"িডজ";s:3:"217";s:7:"েথ ";s:3:"218";s:7:" এব";s:3:"219";s:7:" জন";s:3:"220";s:7:" জা";s:3:"221";s:9:"আমা";s:3:"222";s:9:"গেল";s:3:"223";s:9:"জান";s:3:"224";s:9:"নেত";s:3:"225";s:9:"বিশ";s:3:"226";s:9:"মুে";s:3:"227";s:9:"মেয";s:3:"228";s:7:"র প";s:3:"229";s:7:"সে ";s:3:"230";s:9:"হেল";s:3:"231";s:7:"় ো";s:3:"232";s:7:"া হ";s:3:"233";s:9:"াওয";s:3:"234";s:9:"োমক";s:3:"235";s:9:"ઘাি";s:3:"236";s:7:" অে";s:3:"237";s:5:" ট ";s:3:"238";s:7:" োগ";s:3:"239";s:7:" োন";s:3:"240";s:7:"জর ";s:3:"241";s:9:"তির";s:3:"242";s:9:"দাম";s:3:"243";s:9:"পড়";s:3:"244";s:9:"পার";s:3:"245";s:9:"বাঘ";s:3:"246";s:9:"মকা";s:3:"247";s:9:"মাম";s:3:"248";s:9:"য়র";s:3:"249";s:9:"যাে";s:3:"250";s:7:"র ম";s:3:"251";s:7:"রে ";s:3:"252";s:7:"লর ";s:3:"253";s:7:"া ক";s:3:"254";s:7:"াগ ";s:3:"255";s:9:"াবা";s:3:"256";s:9:"ারা";s:3:"257";s:9:"ািন";s:3:"258";s:7:"ে গ";s:3:"259";s:7:"েগ ";s:3:"260";s:9:"েলর";s:3:"261";s:9:"োদখ";s:3:"262";s:9:"োবি";s:3:"263";s:7:"ઓল ";s:3:"264";s:7:" দে";s:3:"265";s:7:" পু";s:3:"266";s:7:" বে";s:3:"267";s:9:"অেন";s:3:"268";s:9:"এখন";s:3:"269";s:9:"কছু";s:3:"270";s:9:"কাল";s:3:"271";s:9:"গেয";s:3:"272";s:7:"ছন ";s:3:"273";s:7:"ত প";s:3:"274";s:9:"নেয";s:3:"275";s:9:"পাি";s:3:"276";s:7:"মন ";s:3:"277";s:7:"র আ";s:3:"278";s:9:"রার";s:3:"279";s:7:"াও ";s:3:"280";s:7:"াপ ";s:3:"281";s:9:"িকছ";s:3:"282";s:9:"িগে";s:3:"283";s:9:"েছন";s:3:"284";s:9:"েজর";s:3:"285";s:9:"োমা";s:3:"286";s:9:"োমে";s:3:"287";s:9:"ৌতি";s:3:"288";s:9:"ઘাে";s:3:"289";s:3:" ' ";s:3:"290";s:7:" এছ";s:3:"291";s:7:" ছা";s:3:"292";s:7:" বল";s:3:"293";s:7:" যি";s:3:"294";s:7:" শি";s:3:"295";s:7:" িম";s:3:"296";s:7:" োল";s:3:"297";s:9:"এছা";s:3:"298";s:7:"খা ";s:3:"299";}s:9:"bulgarian";a:300:{s:5:"на ";s:1:"0";s:5:" на";s:1:"1";s:5:"то ";s:1:"2";s:5:" пр";s:1:"3";s:5:" за";s:1:"4";s:5:"та ";s:1:"5";s:5:" по";s:1:"6";s:6:"ите";s:1:"7";s:5:"те ";s:1:"8";s:5:"а п";s:1:"9";s:5:"а с";s:2:"10";s:5:" от";s:2:"11";s:5:"за ";s:2:"12";s:6:"ата";s:2:"13";s:5:"ия ";s:2:"14";s:4:" в ";s:2:"15";s:5:"е н";s:2:"16";s:5:" да";s:2:"17";s:5:"а н";s:2:"18";s:5:" се";s:2:"19";s:5:" ко";s:2:"20";s:5:"да ";s:2:"21";s:5:"от ";s:2:"22";s:6:"ани";s:2:"23";s:6:"пре";s:2:"24";s:5:"не ";s:2:"25";s:6:"ени";s:2:"26";s:5:"о н";s:2:"27";s:5:"ни ";s:2:"28";s:5:"се ";s:2:"29";s:4:" и ";s:2:"30";s:5:"но ";s:2:"31";s:6:"ане";s:2:"32";s:6:"ето";s:2:"33";s:5:"а в";s:2:"34";s:5:"ва ";s:2:"35";s:6:"ван";s:2:"36";s:5:"е п";s:2:"37";s:5:"а о";s:2:"38";s:6:"ото";s:2:"39";s:6:"ран";s:2:"40";s:5:"ат ";s:2:"41";s:6:"ред";s:2:"42";s:5:" не";s:2:"43";s:5:"а д";s:2:"44";s:5:"и п";s:2:"45";s:5:" до";s:2:"46";s:6:"про";s:2:"47";s:5:" съ";s:2:"48";s:5:"ли ";s:2:"49";s:6:"при";s:2:"50";s:6:"ния";s:2:"51";s:6:"ски";s:2:"52";s:6:"тел";s:2:"53";s:5:"а и";s:2:"54";s:5:"по ";s:2:"55";s:5:"ри ";s:2:"56";s:4:" е ";s:2:"57";s:5:" ка";s:2:"58";s:6:"ира";s:2:"59";s:6:"кат";s:2:"60";s:6:"ние";s:2:"61";s:6:"нит";s:2:"62";s:5:"е з";s:2:"63";s:5:"и с";s:2:"64";s:5:"о с";s:2:"65";s:6:"ост";s:2:"66";s:5:"че ";s:2:"67";s:5:" ра";s:2:"68";s:6:"ист";s:2:"69";s:5:"о п";s:2:"70";s:5:" из";s:2:"71";s:5:" са";s:2:"72";s:5:"е д";s:2:"73";s:6:"ини";s:2:"74";s:5:"ки ";s:2:"75";s:6:"мин";s:2:"76";s:5:" ми";s:2:"77";s:5:"а б";s:2:"78";s:6:"ава";s:2:"79";s:5:"е в";s:2:"80";s:5:"ие ";s:2:"81";s:6:"пол";s:2:"82";s:6:"ств";s:2:"83";s:5:"т н";s:2:"84";s:5:" въ";s:2:"85";s:5:" ст";s:2:"86";s:5:" то";s:2:"87";s:6:"аза";s:2:"88";s:5:"е о";s:2:"89";s:5:"ов ";s:2:"90";s:5:"ст ";s:2:"91";s:5:"ът ";s:2:"92";s:5:"и н";s:2:"93";s:6:"ият";s:2:"94";s:6:"нат";s:2:"95";s:5:"ра ";s:2:"96";s:5:" бъ";s:2:"97";s:5:" че";s:2:"98";s:6:"алн";s:2:"99";s:5:"е с";s:3:"100";s:5:"ен ";s:3:"101";s:6:"ест";s:3:"102";s:5:"и д";s:3:"103";s:6:"лен";s:3:"104";s:6:"нис";s:3:"105";s:5:"о о";s:3:"106";s:6:"ови";s:3:"107";s:5:" об";s:3:"108";s:5:" сл";s:3:"109";s:5:"а р";s:3:"110";s:6:"ато";s:3:"111";s:6:"кон";s:3:"112";s:6:"нос";s:3:"113";s:6:"ров";s:3:"114";s:5:"ще ";s:3:"115";s:5:" ре";s:3:"116";s:4:" с ";s:3:"117";s:5:" сп";s:3:"118";s:6:"ват";s:3:"119";s:6:"еше";s:3:"120";s:5:"и в";s:3:"121";s:6:"иет";s:3:"122";s:5:"о в";s:3:"123";s:6:"ове";s:3:"124";s:6:"ста";s:3:"125";s:5:"а к";s:3:"126";s:5:"а т";s:3:"127";s:6:"дат";s:3:"128";s:6:"ент";s:3:"129";s:5:"ка ";s:3:"130";s:6:"лед";s:3:"131";s:6:"нет";s:3:"132";s:6:"ори";s:3:"133";s:6:"стр";s:3:"134";s:6:"стъ";s:3:"135";s:5:"ти ";s:3:"136";s:6:"тър";s:3:"137";s:5:" те";s:3:"138";s:5:"а з";s:3:"139";s:5:"а м";s:3:"140";s:5:"ад ";s:3:"141";s:6:"ана";s:3:"142";s:6:"ено";s:3:"143";s:5:"и о";s:3:"144";s:6:"ина";s:3:"145";s:6:"ити";s:3:"146";s:5:"ма ";s:3:"147";s:6:"ска";s:3:"148";s:6:"сле";s:3:"149";s:6:"тво";s:3:"150";s:6:"тер";s:3:"151";s:6:"ция";s:3:"152";s:5:"ят ";s:3:"153";s:5:" бе";s:3:"154";s:5:" де";s:3:"155";s:5:" па";s:3:"156";s:6:"ате";s:3:"157";s:6:"вен";s:3:"158";s:5:"ви ";s:3:"159";s:6:"вит";s:3:"160";s:5:"и з";s:3:"161";s:5:"и и";s:3:"162";s:6:"нар";s:3:"163";s:6:"нов";s:3:"164";s:6:"ова";s:3:"165";s:6:"пов";s:3:"166";s:6:"рез";s:3:"167";s:6:"рит";s:3:"168";s:5:"са ";s:3:"169";s:6:"ята";s:3:"170";s:5:" го";s:3:"171";s:5:" ще";s:3:"172";s:6:"али";s:3:"173";s:5:"в п";s:3:"174";s:6:"гра";s:3:"175";s:5:"е и";s:3:"176";s:6:"еди";s:3:"177";s:6:"ели";s:3:"178";s:6:"или";s:3:"179";s:6:"каз";s:3:"180";s:6:"кит";s:3:"181";s:6:"лно";s:3:"182";s:6:"мен";s:3:"183";s:6:"оли";s:3:"184";s:6:"раз";s:3:"185";s:5:" ве";s:3:"186";s:5:" гр";s:3:"187";s:5:" им";s:3:"188";s:5:" ме";s:3:"189";s:5:" пъ";s:3:"190";s:6:"ави";s:3:"191";s:6:"ако";s:3:"192";s:6:"ача";s:3:"193";s:6:"вин";s:3:"194";s:5:"во ";s:3:"195";s:6:"гов";s:3:"196";s:6:"дан";s:3:"197";s:5:"ди ";s:3:"198";s:5:"до ";s:3:"199";s:5:"ед ";s:3:"200";s:6:"ери";s:3:"201";s:6:"еро";s:3:"202";s:6:"жда";s:3:"203";s:6:"ито";s:3:"204";s:6:"ков";s:3:"205";s:6:"кол";s:3:"206";s:6:"лни";s:3:"207";s:6:"мер";s:3:"208";s:6:"нач";s:3:"209";s:5:"о з";s:3:"210";s:6:"ола";s:3:"211";s:5:"он ";s:3:"212";s:6:"она";s:3:"213";s:6:"пра";s:3:"214";s:6:"рав";s:3:"215";s:6:"рем";s:3:"216";s:6:"сия";s:3:"217";s:6:"сти";s:3:"218";s:5:"т п";s:3:"219";s:6:"тан";s:3:"220";s:5:"ха ";s:3:"221";s:5:"ше ";s:3:"222";s:6:"шен";s:3:"223";s:6:"ълг";s:3:"224";s:5:" ба";s:3:"225";s:5:" си";s:3:"226";s:6:"аро";s:3:"227";s:6:"бъл";s:3:"228";s:5:"в р";s:3:"229";s:6:"гар";s:3:"230";s:5:"е е";s:3:"231";s:6:"елн";s:3:"232";s:6:"еме";s:3:"233";s:6:"ико";s:3:"234";s:6:"има";s:3:"235";s:5:"ко ";s:3:"236";s:6:"кои";s:3:"237";s:5:"ла ";s:3:"238";s:6:"лга";s:3:"239";s:5:"о д";s:3:"240";s:6:"ози";s:3:"241";s:6:"оит";s:3:"242";s:6:"под";s:3:"243";s:6:"рес";s:3:"244";s:6:"рие";s:3:"245";s:6:"сто";s:3:"246";s:5:"т к";s:3:"247";s:5:"т м";s:3:"248";s:5:"т с";s:3:"249";s:6:"уст";s:3:"250";s:5:" би";s:3:"251";s:5:" дв";s:3:"252";s:5:" дъ";s:3:"253";s:5:" ма";s:3:"254";s:5:" мо";s:3:"255";s:5:" ни";s:3:"256";s:5:" ос";s:3:"257";s:6:"ала";s:3:"258";s:6:"анс";s:3:"259";s:6:"ара";s:3:"260";s:6:"ати";s:3:"261";s:6:"аци";s:3:"262";s:6:"беш";s:3:"263";s:6:"вър";s:3:"264";s:5:"е р";s:3:"265";s:6:"едв";s:3:"266";s:6:"ема";s:3:"267";s:6:"жав";s:3:"268";s:5:"и к";s:3:"269";s:6:"иал";s:3:"270";s:6:"ица";s:3:"271";s:6:"иче";s:3:"272";s:6:"кия";s:3:"273";s:6:"лит";s:3:"274";s:5:"о б";s:3:"275";s:6:"ово";s:3:"276";s:6:"оди";s:3:"277";s:6:"ока";s:3:"278";s:6:"пос";s:3:"279";s:6:"род";s:3:"280";s:6:"сед";s:3:"281";s:6:"слу";s:3:"282";s:5:"т и";s:3:"283";s:6:"тов";s:3:"284";s:6:"ува";s:3:"285";s:6:"циа";s:3:"286";s:6:"чес";s:3:"287";s:5:"я з";s:3:"288";s:5:" во";s:3:"289";s:5:" ил";s:3:"290";s:5:" ск";s:3:"291";s:5:" тр";s:3:"292";s:5:" це";s:3:"293";s:6:"ами";s:3:"294";s:6:"ари";s:3:"295";s:6:"бат";s:3:"296";s:5:"би ";s:3:"297";s:6:"бра";s:3:"298";s:6:"бъд";s:3:"299";}s:7:"cebuano";a:300:{s:3:"ng ";s:1:"0";s:3:"sa ";s:1:"1";s:3:" sa";s:1:"2";s:3:"ang";s:1:"3";s:3:"ga ";s:1:"4";s:3:"nga";s:1:"5";s:3:" ka";s:1:"6";s:3:" ng";s:1:"7";s:3:"an ";s:1:"8";s:3:" an";s:1:"9";s:3:" na";s:2:"10";s:3:" ma";s:2:"11";s:3:" ni";s:2:"12";s:3:"a s";s:2:"13";s:3:"a n";s:2:"14";s:3:"on ";s:2:"15";s:3:" pa";s:2:"16";s:3:" si";s:2:"17";s:3:"a k";s:2:"18";s:3:"a m";s:2:"19";s:3:" ba";s:2:"20";s:3:"ong";s:2:"21";s:3:"a i";s:2:"22";s:3:"ila";s:2:"23";s:3:" mg";s:2:"24";s:3:"mga";s:2:"25";s:3:"a p";s:2:"26";s:3:"iya";s:2:"27";s:3:"a a";s:2:"28";s:3:"ay ";s:2:"29";s:3:"ka ";s:2:"30";s:3:"ala";s:2:"31";s:3:"ing";s:2:"32";s:3:"g m";s:2:"33";s:3:"n s";s:2:"34";s:3:"g n";s:2:"35";s:3:"lan";s:2:"36";s:3:" gi";s:2:"37";s:3:"na ";s:2:"38";s:3:"ni ";s:2:"39";s:3:"o s";s:2:"40";s:3:"g p";s:2:"41";s:3:"n n";s:2:"42";s:3:" da";s:2:"43";s:3:"ag ";s:2:"44";s:3:"pag";s:2:"45";s:3:"g s";s:2:"46";s:3:"yan";s:2:"47";s:3:"ayo";s:2:"48";s:3:"o n";s:2:"49";s:3:"si ";s:2:"50";s:3:" mo";s:2:"51";s:3:"a b";s:2:"52";s:3:"g a";s:2:"53";s:3:"ail";s:2:"54";s:3:"g b";s:2:"55";s:3:"han";s:2:"56";s:3:"a d";s:2:"57";s:3:"asu";s:2:"58";s:3:"nag";s:2:"59";s:3:"ya ";s:2:"60";s:3:"man";s:2:"61";s:3:"ne ";s:2:"62";s:3:"pan";s:2:"63";s:3:"kon";s:2:"64";s:3:" il";s:2:"65";s:3:" la";s:2:"66";s:3:"aka";s:2:"67";s:3:"ako";s:2:"68";s:3:"ana";s:2:"69";s:3:"bas";s:2:"70";s:3:"ko ";s:2:"71";s:3:"od ";s:2:"72";s:3:"yo ";s:2:"73";s:3:" di";s:2:"74";s:3:" ko";s:2:"75";s:3:" ug";s:2:"76";s:3:"a u";s:2:"77";s:3:"g k";s:2:"78";s:3:"kan";s:2:"79";s:3:"la ";s:2:"80";s:3:"len";s:2:"81";s:3:"sur";s:2:"82";s:3:"ug ";s:2:"83";s:3:" ai";s:2:"84";s:3:"apa";s:2:"85";s:3:"aw ";s:2:"86";s:3:"d s";s:2:"87";s:3:"g d";s:2:"88";s:3:"g g";s:2:"89";s:3:"ile";s:2:"90";s:3:"nin";s:2:"91";s:3:" iy";s:2:"92";s:3:" su";s:2:"93";s:3:"ene";s:2:"94";s:3:"og ";s:2:"95";s:3:"ot ";s:2:"96";s:3:"aba";s:2:"97";s:3:"aha";s:2:"98";s:3:"as ";s:2:"99";s:3:"imo";s:3:"100";s:3:" ki";s:3:"101";s:3:"a t";s:3:"102";s:3:"aga";s:3:"103";s:3:"ban";s:3:"104";s:3:"ero";s:3:"105";s:3:"nan";s:3:"106";s:3:"o k";s:3:"107";s:3:"ran";s:3:"108";s:3:"ron";s:3:"109";s:3:"sil";s:3:"110";s:3:"una";s:3:"111";s:3:"usa";s:3:"112";s:3:" us";s:3:"113";s:3:"a g";s:3:"114";s:3:"ahi";s:3:"115";s:3:"ani";s:3:"116";s:3:"er ";s:3:"117";s:3:"ha ";s:3:"118";s:3:"i a";s:3:"119";s:3:"rer";s:3:"120";s:3:"yon";s:3:"121";s:3:" pu";s:3:"122";s:3:"ini";s:3:"123";s:3:"nak";s:3:"124";s:3:"ro ";s:3:"125";s:3:"to ";s:3:"126";s:3:"ure";s:3:"127";s:3:" ed";s:3:"128";s:3:" og";s:3:"129";s:3:" wa";s:3:"130";s:3:"ili";s:3:"131";s:3:"mo ";s:3:"132";s:3:"n a";s:3:"133";s:3:"nd ";s:3:"134";s:3:"o a";s:3:"135";s:3:" ad";s:3:"136";s:3:" du";s:3:"137";s:3:" pr";s:3:"138";s:3:"aro";s:3:"139";s:3:"i s";s:3:"140";s:3:"ma ";s:3:"141";s:3:"n m";s:3:"142";s:3:"ulo";s:3:"143";s:3:"und";s:3:"144";s:3:" ta";s:3:"145";s:3:"ara";s:3:"146";s:3:"asa";s:3:"147";s:3:"ato";s:3:"148";s:3:"awa";s:3:"149";s:3:"dmu";s:3:"150";s:3:"e n";s:3:"151";s:3:"edm";s:3:"152";s:3:"ina";s:3:"153";s:3:"mak";s:3:"154";s:3:"mun";s:3:"155";s:3:"niy";s:3:"156";s:3:"san";s:3:"157";s:3:"wa ";s:3:"158";s:3:" tu";s:3:"159";s:3:" un";s:3:"160";s:3:"a l";s:3:"161";s:3:"bay";s:3:"162";s:3:"iga";s:3:"163";s:3:"ika";s:3:"164";s:3:"ita";s:3:"165";s:3:"kin";s:3:"166";s:3:"lis";s:3:"167";s:3:"may";s:3:"168";s:3:"os ";s:3:"169";s:3:" ar";s:3:"170";s:3:"ad ";s:3:"171";s:3:"ali";s:3:"172";s:3:"ama";s:3:"173";s:3:"ers";s:3:"174";s:3:"ipa";s:3:"175";s:3:"isa";s:3:"176";s:3:"mao";s:3:"177";s:3:"nim";s:3:"178";s:3:"t s";s:3:"179";s:3:"tin";s:3:"180";s:3:" ak";s:3:"181";s:3:" ap";s:3:"182";s:3:" hi";s:3:"183";s:3:"abo";s:3:"184";s:3:"agp";s:3:"185";s:3:"ano";s:3:"186";s:3:"ata";s:3:"187";s:3:"g i";s:3:"188";s:3:"gan";s:3:"189";s:3:"gka";s:3:"190";s:3:"gpa";s:3:"191";s:3:"i m";s:3:"192";s:3:"iha";s:3:"193";s:3:"k s";s:3:"194";s:3:"law";s:3:"195";s:3:"or ";s:3:"196";s:3:"rs ";s:3:"197";s:3:"siy";s:3:"198";s:3:"tag";s:3:"199";s:3:" al";s:3:"200";s:3:" at";s:3:"201";s:3:" ha";s:3:"202";s:3:" hu";s:3:"203";s:3:" im";s:3:"204";s:3:"a h";s:3:"205";s:3:"bu ";s:3:"206";s:3:"e s";s:3:"207";s:3:"gma";s:3:"208";s:3:"kas";s:3:"209";s:3:"lag";s:3:"210";s:3:"mon";s:3:"211";s:3:"nah";s:3:"212";s:3:"ngo";s:3:"213";s:3:"r s";s:3:"214";s:3:"ra ";s:3:"215";s:3:"sab";s:3:"216";s:3:"sam";s:3:"217";s:3:"sul";s:3:"218";s:3:"uba";s:3:"219";s:3:"uha";s:3:"220";s:3:" lo";s:3:"221";s:3:" re";s:3:"222";s:3:"ada";s:3:"223";s:3:"aki";s:3:"224";s:3:"aya";s:3:"225";s:3:"bah";s:3:"226";s:3:"ce ";s:3:"227";s:3:"d n";s:3:"228";s:3:"lab";s:3:"229";s:3:"pa ";s:3:"230";s:3:"pak";s:3:"231";s:3:"s n";s:3:"232";s:3:"s s";s:3:"233";s:3:"tan";s:3:"234";s:3:"taw";s:3:"235";s:3:"te ";s:3:"236";s:3:"uma";s:3:"237";s:3:"ura";s:3:"238";s:3:" in";s:3:"239";s:3:" lu";s:3:"240";s:3:"a c";s:3:"241";s:3:"abi";s:3:"242";s:3:"at ";s:3:"243";s:3:"awo";s:3:"244";s:3:"bat";s:3:"245";s:3:"dal";s:3:"246";s:3:"dla";s:3:"247";s:3:"ele";s:3:"248";s:3:"g t";s:3:"249";s:3:"g u";s:3:"250";s:3:"gay";s:3:"251";s:3:"go ";s:3:"252";s:3:"hab";s:3:"253";s:3:"hin";s:3:"254";s:3:"i e";s:3:"255";s:3:"i n";s:3:"256";s:3:"kab";s:3:"257";s:3:"kap";s:3:"258";s:3:"lay";s:3:"259";s:3:"lin";s:3:"260";s:3:"nil";s:3:"261";s:3:"pam";s:3:"262";s:3:"pas";s:3:"263";s:3:"pro";s:3:"264";s:3:"pul";s:3:"265";s:3:"ta ";s:3:"266";s:3:"ton";s:3:"267";s:3:"uga";s:3:"268";s:3:"ugm";s:3:"269";s:3:"unt";s:3:"270";s:3:" co";s:3:"271";s:3:" gu";s:3:"272";s:3:" mi";s:3:"273";s:3:" pi";s:3:"274";s:3:" ti";s:3:"275";s:3:"a o";s:3:"276";s:3:"abu";s:3:"277";s:3:"adl";s:3:"278";s:3:"ado";s:3:"279";s:3:"agh";s:3:"280";s:3:"agk";s:3:"281";s:3:"ao ";s:3:"282";s:3:"art";s:3:"283";s:3:"bal";s:3:"284";s:3:"cit";s:3:"285";s:3:"di ";s:3:"286";s:3:"dto";s:3:"287";s:3:"dun";s:3:"288";s:3:"ent";s:3:"289";s:3:"g e";s:3:"290";s:3:"gon";s:3:"291";s:3:"gug";s:3:"292";s:3:"ia ";s:3:"293";s:3:"iba";s:3:"294";s:3:"ice";s:3:"295";s:3:"in ";s:3:"296";s:3:"inu";s:3:"297";s:3:"it ";s:3:"298";s:3:"kaa";s:3:"299";}s:8:"croatian";a:300:{s:3:"je ";s:1:"0";s:3:" na";s:1:"1";s:3:" pr";s:1:"2";s:3:" po";s:1:"3";s:3:"na ";s:1:"4";s:3:" je";s:1:"5";s:3:" za";s:1:"6";s:3:"ije";s:1:"7";s:3:"ne ";s:1:"8";s:3:" i ";s:1:"9";s:3:"ti ";s:2:"10";s:3:"da ";s:2:"11";s:3:" ko";s:2:"12";s:3:" ne";s:2:"13";s:3:"li ";s:2:"14";s:3:" bi";s:2:"15";s:3:" da";s:2:"16";s:3:" u ";s:2:"17";s:3:"ma ";s:2:"18";s:3:"mo ";s:2:"19";s:3:"a n";s:2:"20";s:3:"ih ";s:2:"21";s:3:"za ";s:2:"22";s:3:"a s";s:2:"23";s:3:"ko ";s:2:"24";s:3:"i s";s:2:"25";s:3:"a p";s:2:"26";s:3:"koj";s:2:"27";s:3:"pro";s:2:"28";s:3:"ju ";s:2:"29";s:3:"se ";s:2:"30";s:3:" go";s:2:"31";s:3:"ost";s:2:"32";s:3:"to ";s:2:"33";s:3:"va ";s:2:"34";s:3:" do";s:2:"35";s:3:" to";s:2:"36";s:3:"e n";s:2:"37";s:3:"i p";s:2:"38";s:3:" od";s:2:"39";s:3:" ra";s:2:"40";s:3:"no ";s:2:"41";s:3:"ako";s:2:"42";s:3:"ka ";s:2:"43";s:3:"ni ";s:2:"44";s:3:" ka";s:2:"45";s:3:" se";s:2:"46";s:3:" mo";s:2:"47";s:3:" st";s:2:"48";s:3:"i n";s:2:"49";s:3:"ima";s:2:"50";s:3:"ja ";s:2:"51";s:3:"pri";s:2:"52";s:3:"vat";s:2:"53";s:3:"sta";s:2:"54";s:3:" su";s:2:"55";s:3:"ati";s:2:"56";s:3:"e p";s:2:"57";s:3:"ta ";s:2:"58";s:3:"tsk";s:2:"59";s:3:"e i";s:2:"60";s:3:"nij";s:2:"61";s:3:" tr";s:2:"62";s:3:"cij";s:2:"63";s:3:"jen";s:2:"64";s:3:"nos";s:2:"65";s:3:"o s";s:2:"66";s:3:" iz";s:2:"67";s:3:"om ";s:2:"68";s:3:"tro";s:2:"69";s:3:"ili";s:2:"70";s:3:"iti";s:2:"71";s:3:"pos";s:2:"72";s:3:" al";s:2:"73";s:3:"a i";s:2:"74";s:3:"a o";s:2:"75";s:3:"e s";s:2:"76";s:3:"ija";s:2:"77";s:3:"ini";s:2:"78";s:3:"pre";s:2:"79";s:3:"str";s:2:"80";s:3:"la ";s:2:"81";s:3:"og ";s:2:"82";s:3:"ovo";s:2:"83";s:3:" sv";s:2:"84";s:3:"ekt";s:2:"85";s:3:"nje";s:2:"86";s:3:"o p";s:2:"87";s:3:"odi";s:2:"88";s:3:"rva";s:2:"89";s:3:" ni";s:2:"90";s:3:"ali";s:2:"91";s:3:"min";s:2:"92";s:3:"rij";s:2:"93";s:3:"a t";s:2:"94";s:3:"a z";s:2:"95";s:3:"ats";s:2:"96";s:3:"iva";s:2:"97";s:3:"o t";s:2:"98";s:3:"od ";s:2:"99";s:3:"oje";s:3:"100";s:3:"ra ";s:3:"101";s:3:" hr";s:3:"102";s:3:"a m";s:3:"103";s:3:"a u";s:3:"104";s:3:"hrv";s:3:"105";s:3:"im ";s:3:"106";s:3:"ke ";s:3:"107";s:3:"o i";s:3:"108";s:3:"ovi";s:3:"109";s:3:"red";s:3:"110";s:3:"riv";s:3:"111";s:3:"te ";s:3:"112";s:3:"bi ";s:3:"113";s:3:"e o";s:3:"114";s:3:"god";s:3:"115";s:3:"i d";s:3:"116";s:3:"lek";s:3:"117";s:3:"umi";s:3:"118";s:3:"zvo";s:3:"119";s:3:"din";s:3:"120";s:3:"e u";s:3:"121";s:3:"ene";s:3:"122";s:3:"jed";s:3:"123";s:3:"ji ";s:3:"124";s:3:"lje";s:3:"125";s:3:"nog";s:3:"126";s:3:"su ";s:3:"127";s:3:" a ";s:3:"128";s:3:" el";s:3:"129";s:3:" mi";s:3:"130";s:3:" o ";s:3:"131";s:3:"a d";s:3:"132";s:3:"alu";s:3:"133";s:3:"ele";s:3:"134";s:3:"i u";s:3:"135";s:3:"izv";s:3:"136";s:3:"ktr";s:3:"137";s:3:"lum";s:3:"138";s:3:"o d";s:3:"139";s:3:"ori";s:3:"140";s:3:"rad";s:3:"141";s:3:"sto";s:3:"142";s:3:"a k";s:3:"143";s:3:"anj";s:3:"144";s:3:"ava";s:3:"145";s:3:"e k";s:3:"146";s:3:"men";s:3:"147";s:3:"nic";s:3:"148";s:3:"o j";s:3:"149";s:3:"oj ";s:3:"150";s:3:"ove";s:3:"151";s:3:"ski";s:3:"152";s:3:"tvr";s:3:"153";s:3:"una";s:3:"154";s:3:"vor";s:3:"155";s:3:" di";s:3:"156";s:3:" no";s:3:"157";s:3:" s ";s:3:"158";s:3:" ta";s:3:"159";s:3:" tv";s:3:"160";s:3:"i i";s:3:"161";s:3:"i o";s:3:"162";s:3:"kak";s:3:"163";s:4:"roš";s:3:"164";s:3:"sko";s:3:"165";s:3:"vod";s:3:"166";s:3:" sa";s:3:"167";s:4:" će";s:3:"168";s:3:"a b";s:3:"169";s:3:"adi";s:3:"170";s:3:"amo";s:3:"171";s:3:"eni";s:3:"172";s:3:"gov";s:3:"173";s:3:"iju";s:3:"174";s:3:"ku ";s:3:"175";s:3:"o n";s:3:"176";s:3:"ora";s:3:"177";s:3:"rav";s:3:"178";s:3:"ruj";s:3:"179";s:3:"smo";s:3:"180";s:3:"tav";s:3:"181";s:3:"tru";s:3:"182";s:3:"u p";s:3:"183";s:3:"ve ";s:3:"184";s:3:" in";s:3:"185";s:3:" pl";s:3:"186";s:3:"aci";s:3:"187";s:3:"bit";s:3:"188";s:3:"de ";s:3:"189";s:4:"diš";s:3:"190";s:3:"ema";s:3:"191";s:3:"i m";s:3:"192";s:3:"ika";s:3:"193";s:4:"išt";s:3:"194";s:3:"jer";s:3:"195";s:3:"ki ";s:3:"196";s:3:"mog";s:3:"197";s:3:"nik";s:3:"198";s:3:"nov";s:3:"199";s:3:"nu ";s:3:"200";s:3:"oji";s:3:"201";s:3:"oli";s:3:"202";s:3:"pla";s:3:"203";s:3:"pod";s:3:"204";s:3:"st ";s:3:"205";s:3:"sti";s:3:"206";s:3:"tra";s:3:"207";s:3:"tre";s:3:"208";s:3:"vo ";s:3:"209";s:3:" sm";s:3:"210";s:4:" št";s:3:"211";s:3:"dan";s:3:"212";s:3:"e z";s:3:"213";s:3:"i t";s:3:"214";s:3:"io ";s:3:"215";s:3:"ist";s:3:"216";s:3:"kon";s:3:"217";s:3:"lo ";s:3:"218";s:3:"stv";s:3:"219";s:3:"u s";s:3:"220";s:3:"uje";s:3:"221";s:3:"ust";s:3:"222";s:4:"će ";s:3:"223";s:4:"ći ";s:3:"224";s:4:"što";s:3:"225";s:3:" dr";s:3:"226";s:3:" im";s:3:"227";s:3:" li";s:3:"228";s:3:"ada";s:3:"229";s:3:"aft";s:3:"230";s:3:"ani";s:3:"231";s:3:"ao ";s:3:"232";s:3:"ars";s:3:"233";s:3:"ata";s:3:"234";s:3:"e t";s:3:"235";s:3:"emo";s:3:"236";s:3:"i k";s:3:"237";s:3:"ine";s:3:"238";s:3:"jem";s:3:"239";s:3:"kov";s:3:"240";s:3:"lik";s:3:"241";s:3:"lji";s:3:"242";s:3:"mje";s:3:"243";s:3:"naf";s:3:"244";s:3:"ner";s:3:"245";s:3:"nih";s:3:"246";s:3:"nja";s:3:"247";s:3:"ogo";s:3:"248";s:3:"oiz";s:3:"249";s:3:"ome";s:3:"250";s:3:"pot";s:3:"251";s:3:"ran";s:3:"252";s:3:"ri ";s:3:"253";s:3:"roi";s:3:"254";s:3:"rtk";s:3:"255";s:3:"ska";s:3:"256";s:3:"ter";s:3:"257";s:3:"u i";s:3:"258";s:3:"u o";s:3:"259";s:3:"vi ";s:3:"260";s:3:"vrt";s:3:"261";s:3:" me";s:3:"262";s:3:" ug";s:3:"263";s:3:"ak ";s:3:"264";s:3:"ama";s:3:"265";s:4:"drž";s:3:"266";s:3:"e e";s:3:"267";s:3:"e g";s:3:"268";s:3:"e m";s:3:"269";s:3:"em ";s:3:"270";s:3:"eme";s:3:"271";s:3:"enj";s:3:"272";s:3:"ent";s:3:"273";s:3:"er ";s:3:"274";s:3:"ere";s:3:"275";s:3:"erg";s:3:"276";s:3:"eur";s:3:"277";s:3:"go ";s:3:"278";s:3:"i b";s:3:"279";s:3:"i z";s:3:"280";s:3:"jet";s:3:"281";s:3:"ksi";s:3:"282";s:3:"o u";s:3:"283";s:3:"oda";s:3:"284";s:3:"ona";s:3:"285";s:3:"pra";s:3:"286";s:3:"reb";s:3:"287";s:3:"rem";s:3:"288";s:3:"rop";s:3:"289";s:3:"tri";s:3:"290";s:4:"žav";s:3:"291";s:3:" ci";s:3:"292";s:3:" eu";s:3:"293";s:3:" re";s:3:"294";s:3:" te";s:3:"295";s:3:" uv";s:3:"296";s:3:" ve";s:3:"297";s:3:"aju";s:3:"298";s:3:"an ";s:3:"299";}s:5:"czech";a:300:{s:3:" pr";s:1:"0";s:3:" po";s:1:"1";s:4:"ní ";s:1:"2";s:3:"pro";s:1:"3";s:3:" na";s:1:"4";s:3:"na ";s:1:"5";s:4:" př";s:1:"6";s:3:"ch ";s:1:"7";s:3:" je";s:1:"8";s:3:" ne";s:1:"9";s:4:"že ";s:2:"10";s:4:" že";s:2:"11";s:3:" se";s:2:"12";s:3:" do";s:2:"13";s:3:" ro";s:2:"14";s:3:" st";s:2:"15";s:3:" v ";s:2:"16";s:3:" ve";s:2:"17";s:4:"pře";s:2:"18";s:3:"se ";s:2:"19";s:3:"ho ";s:2:"20";s:3:"sta";s:2:"21";s:3:" to";s:2:"22";s:3:" vy";s:2:"23";s:3:" za";s:2:"24";s:3:"ou ";s:2:"25";s:3:" a ";s:2:"26";s:3:"to ";s:2:"27";s:3:" by";s:2:"28";s:3:"la ";s:2:"29";s:3:"ce ";s:2:"30";s:3:"e v";s:2:"31";s:3:"ist";s:2:"32";s:3:"le ";s:2:"33";s:3:"pod";s:2:"34";s:4:"í p";s:2:"35";s:3:" vl";s:2:"36";s:3:"e n";s:2:"37";s:3:"e s";s:2:"38";s:3:"je ";s:2:"39";s:4:"ké ";s:2:"40";s:3:"by ";s:2:"41";s:3:"em ";s:2:"42";s:4:"ých";s:2:"43";s:3:" od";s:2:"44";s:3:"ova";s:2:"45";s:4:"řed";s:2:"46";s:3:"dy ";s:2:"47";s:4:"ení";s:2:"48";s:3:"kon";s:2:"49";s:3:"li ";s:2:"50";s:4:"ně ";s:2:"51";s:3:"str";s:2:"52";s:4:" zá";s:2:"53";s:3:"ve ";s:2:"54";s:3:" ka";s:2:"55";s:3:" sv";s:2:"56";s:3:"e p";s:2:"57";s:3:"it ";s:2:"58";s:4:"lád";s:2:"59";s:3:"oho";s:2:"60";s:3:"rov";s:2:"61";s:3:"roz";s:2:"62";s:3:"ter";s:2:"63";s:4:"vlá";s:2:"64";s:4:"ím ";s:2:"65";s:3:" ko";s:2:"66";s:3:"hod";s:2:"67";s:3:"nis";s:2:"68";s:5:"pří";s:2:"69";s:4:"ský";s:2:"70";s:3:" mi";s:2:"71";s:3:" ob";s:2:"72";s:3:" so";s:2:"73";s:3:"a p";s:2:"74";s:3:"ali";s:2:"75";s:3:"bud";s:2:"76";s:3:"edn";s:2:"77";s:3:"ick";s:2:"78";s:3:"kte";s:2:"79";s:3:"ku ";s:2:"80";s:3:"o s";s:2:"81";s:3:"al ";s:2:"82";s:3:"ci ";s:2:"83";s:3:"e t";s:2:"84";s:3:"il ";s:2:"85";s:3:"ny ";s:2:"86";s:4:"né ";s:2:"87";s:3:"odl";s:2:"88";s:4:"ová";s:2:"89";s:3:"rot";s:2:"90";s:3:"sou";s:2:"91";s:5:"ání";s:2:"92";s:3:" bu";s:2:"93";s:3:" mo";s:2:"94";s:3:" o ";s:2:"95";s:3:"ast";s:2:"96";s:3:"byl";s:2:"97";s:3:"de ";s:2:"98";s:3:"ek ";s:2:"99";s:3:"ost";s:3:"100";s:4:" mí";s:3:"101";s:3:" ta";s:3:"102";s:3:"es ";s:3:"103";s:3:"jed";s:3:"104";s:3:"ky ";s:3:"105";s:3:"las";s:3:"106";s:3:"m p";s:3:"107";s:3:"nes";s:3:"108";s:4:"ním";s:3:"109";s:3:"ran";s:3:"110";s:3:"rem";s:3:"111";s:3:"ros";s:3:"112";s:4:"ého";s:3:"113";s:3:" de";s:3:"114";s:3:" kt";s:3:"115";s:3:" ni";s:3:"116";s:3:" si";s:3:"117";s:4:" vý";s:3:"118";s:3:"at ";s:3:"119";s:4:"jí ";s:3:"120";s:4:"ký ";s:3:"121";s:3:"mi ";s:3:"122";s:3:"pre";s:3:"123";s:3:"tak";s:3:"124";s:3:"tan";s:3:"125";s:3:"y v";s:3:"126";s:4:"řek";s:3:"127";s:3:" ch";s:3:"128";s:3:" li";s:3:"129";s:4:" ná";s:3:"130";s:3:" pa";s:3:"131";s:4:" ře";s:3:"132";s:3:"da ";s:3:"133";s:3:"dle";s:3:"134";s:3:"dne";s:3:"135";s:3:"i p";s:3:"136";s:3:"i v";s:3:"137";s:3:"ly ";s:3:"138";s:3:"min";s:3:"139";s:3:"o n";s:3:"140";s:3:"o v";s:3:"141";s:3:"pol";s:3:"142";s:3:"tra";s:3:"143";s:3:"val";s:3:"144";s:4:"vní";s:3:"145";s:4:"ích";s:3:"146";s:4:"ý p";s:3:"147";s:4:"řej";s:3:"148";s:3:" ce";s:3:"149";s:3:" kd";s:3:"150";s:3:" le";s:3:"151";s:3:"a s";s:3:"152";s:3:"a z";s:3:"153";s:3:"cen";s:3:"154";s:3:"e k";s:3:"155";s:3:"eds";s:3:"156";s:3:"ekl";s:3:"157";s:3:"emi";s:3:"158";s:3:"kl ";s:3:"159";s:3:"lat";s:3:"160";s:3:"lo ";s:3:"161";s:4:"mié";s:3:"162";s:3:"nov";s:3:"163";s:3:"pra";s:3:"164";s:3:"sku";s:3:"165";s:4:"ské";s:3:"166";s:3:"sti";s:3:"167";s:3:"tav";s:3:"168";s:3:"ti ";s:3:"169";s:3:"ty ";s:3:"170";s:4:"ván";s:3:"171";s:4:"vé ";s:3:"172";s:3:"y n";s:3:"173";s:3:"y s";s:3:"174";s:4:"í s";s:3:"175";s:4:"í v";s:3:"176";s:4:"ě p";s:3:"177";s:3:" dn";s:3:"178";s:4:" ně";s:3:"179";s:3:" sp";s:3:"180";s:4:" čs";s:3:"181";s:3:"a n";s:3:"182";s:3:"a t";s:3:"183";s:3:"ak ";s:3:"184";s:4:"dní";s:3:"185";s:3:"doh";s:3:"186";s:3:"e b";s:3:"187";s:3:"e m";s:3:"188";s:3:"ejn";s:3:"189";s:3:"ena";s:3:"190";s:3:"est";s:3:"191";s:3:"ini";s:3:"192";s:3:"m z";s:3:"193";s:3:"nal";s:3:"194";s:3:"nou";s:3:"195";s:4:"ná ";s:3:"196";s:3:"ovi";s:3:"197";s:4:"ové";s:3:"198";s:4:"ový";s:3:"199";s:3:"rsk";s:3:"200";s:4:"stá";s:3:"201";s:4:"tí ";s:3:"202";s:4:"tře";s:3:"203";s:4:"tů ";s:3:"204";s:3:"ude";s:3:"205";s:3:"za ";s:3:"206";s:4:"é p";s:3:"207";s:4:"ém ";s:3:"208";s:4:"í d";s:3:"209";s:3:" ir";s:3:"210";s:3:" zv";s:3:"211";s:3:"ale";s:3:"212";s:4:"aně";s:3:"213";s:3:"ave";s:3:"214";s:4:"cké";s:3:"215";s:3:"den";s:3:"216";s:3:"e z";s:3:"217";s:3:"ech";s:3:"218";s:3:"en ";s:3:"219";s:4:"erý";s:3:"220";s:3:"hla";s:3:"221";s:3:"i s";s:3:"222";s:4:"iér";s:3:"223";s:3:"lov";s:3:"224";s:3:"mu ";s:3:"225";s:3:"neb";s:3:"226";s:3:"nic";s:3:"227";s:3:"o b";s:3:"228";s:3:"o m";s:3:"229";s:3:"pad";s:3:"230";s:3:"pot";s:3:"231";s:3:"rav";s:3:"232";s:3:"rop";s:3:"233";s:4:"rý ";s:3:"234";s:3:"sed";s:3:"235";s:3:"si ";s:3:"236";s:3:"t p";s:3:"237";s:3:"tic";s:3:"238";s:3:"tu ";s:3:"239";s:4:"tě ";s:3:"240";s:3:"u p";s:3:"241";s:3:"u v";s:3:"242";s:4:"vá ";s:3:"243";s:5:"výš";s:3:"244";s:4:"zvý";s:3:"245";s:5:"ční";s:3:"246";s:5:"ří ";s:3:"247";s:4:"ům ";s:3:"248";s:3:" bl";s:3:"249";s:3:" br";s:3:"250";s:3:" ho";s:3:"251";s:3:" ja";s:3:"252";s:3:" re";s:3:"253";s:3:" s ";s:3:"254";s:3:" z ";s:3:"255";s:3:" zd";s:3:"256";s:3:"a v";s:3:"257";s:3:"ani";s:3:"258";s:3:"ato";s:3:"259";s:3:"bla";s:3:"260";s:3:"bri";s:3:"261";s:4:"ečn";s:3:"262";s:4:"eře";s:3:"263";s:3:"h v";s:3:"264";s:3:"i n";s:3:"265";s:3:"ie ";s:3:"266";s:3:"ila";s:3:"267";s:3:"irs";s:3:"268";s:3:"ite";s:3:"269";s:3:"kov";s:3:"270";s:3:"nos";s:3:"271";s:3:"o o";s:3:"272";s:3:"o p";s:3:"273";s:3:"oce";s:3:"274";s:3:"ody";s:3:"275";s:3:"ohl";s:3:"276";s:3:"oli";s:3:"277";s:3:"ovo";s:3:"278";s:3:"pla";s:3:"279";s:4:"poč";s:3:"280";s:4:"prá";s:3:"281";s:3:"ra ";s:3:"282";s:3:"rit";s:3:"283";s:3:"rod";s:3:"284";s:3:"ry ";s:3:"285";s:3:"sd ";s:3:"286";s:3:"sko";s:3:"287";s:3:"ssd";s:3:"288";s:3:"tel";s:3:"289";s:3:"u s";s:3:"290";s:3:"vat";s:3:"291";s:4:"veř";s:3:"292";s:3:"vit";s:3:"293";s:3:"vla";s:3:"294";s:3:"y p";s:3:"295";s:4:"áln";s:3:"296";s:4:"čss";s:3:"297";s:4:"šen";s:3:"298";s:3:" al";s:3:"299";}s:6:"danish";a:300:{s:3:"er ";s:1:"0";s:3:"en ";s:1:"1";s:3:" de";s:1:"2";s:3:"et ";s:1:"3";s:3:"der";s:1:"4";s:3:"de ";s:1:"5";s:3:"for";s:1:"6";s:3:" fo";s:1:"7";s:3:" i ";s:1:"8";s:3:"at ";s:1:"9";s:3:" at";s:2:"10";s:3:"re ";s:2:"11";s:3:"det";s:2:"12";s:3:" ha";s:2:"13";s:3:"nde";s:2:"14";s:3:"ere";s:2:"15";s:3:"ing";s:2:"16";s:3:"den";s:2:"17";s:3:" me";s:2:"18";s:3:" og";s:2:"19";s:3:"ger";s:2:"20";s:3:"ter";s:2:"21";s:3:" er";s:2:"22";s:3:" si";s:2:"23";s:3:"and";s:2:"24";s:3:" af";s:2:"25";s:3:"or ";s:2:"26";s:3:" st";s:2:"27";s:3:" ti";s:2:"28";s:3:" en";s:2:"29";s:3:"og ";s:2:"30";s:3:"ar ";s:2:"31";s:3:"il ";s:2:"32";s:3:"r s";s:2:"33";s:3:"ige";s:2:"34";s:3:"til";s:2:"35";s:3:"ke ";s:2:"36";s:3:"r e";s:2:"37";s:3:"af ";s:2:"38";s:3:"kke";s:2:"39";s:3:" ma";s:2:"40";s:4:" på";s:2:"41";s:3:"om ";s:2:"42";s:4:"på ";s:2:"43";s:3:"ed ";s:2:"44";s:3:"ge ";s:2:"45";s:3:"end";s:2:"46";s:3:"nge";s:2:"47";s:3:"t s";s:2:"48";s:3:"e s";s:2:"49";s:3:"ler";s:2:"50";s:3:" sk";s:2:"51";s:3:"els";s:2:"52";s:3:"ern";s:2:"53";s:3:"sig";s:2:"54";s:3:"ne ";s:2:"55";s:3:"lig";s:2:"56";s:3:"r d";s:2:"57";s:3:"ska";s:2:"58";s:3:" vi";s:2:"59";s:3:"har";s:2:"60";s:3:" be";s:2:"61";s:3:" se";s:2:"62";s:3:"an ";s:2:"63";s:3:"ikk";s:2:"64";s:3:"lle";s:2:"65";s:3:"gen";s:2:"66";s:3:"n f";s:2:"67";s:3:"ste";s:2:"68";s:3:"t a";s:2:"69";s:3:"t d";s:2:"70";s:3:"rin";s:2:"71";s:3:" ik";s:2:"72";s:3:"es ";s:2:"73";s:3:"ng ";s:2:"74";s:3:"ver";s:2:"75";s:3:"r b";s:2:"76";s:3:"sen";s:2:"77";s:3:"ede";s:2:"78";s:3:"men";s:2:"79";s:3:"r i";s:2:"80";s:3:" he";s:2:"81";s:3:" et";s:2:"82";s:3:"ig ";s:2:"83";s:3:"lan";s:2:"84";s:3:"med";s:2:"85";s:3:"nd ";s:2:"86";s:3:"rne";s:2:"87";s:3:" da";s:2:"88";s:3:" in";s:2:"89";s:3:"e t";s:2:"90";s:3:"mme";s:2:"91";s:3:"und";s:2:"92";s:3:" om";s:2:"93";s:3:"e e";s:2:"94";s:3:"e m";s:2:"95";s:3:"her";s:2:"96";s:3:"le ";s:2:"97";s:3:"r f";s:2:"98";s:3:"t f";s:2:"99";s:4:"så ";s:3:"100";s:3:"te ";s:3:"101";s:3:" so";s:3:"102";s:3:"ele";s:3:"103";s:3:"t e";s:3:"104";s:3:" ko";s:3:"105";s:3:"est";s:3:"106";s:3:"ske";s:3:"107";s:3:" bl";s:3:"108";s:3:"e f";s:3:"109";s:3:"ekt";s:3:"110";s:3:"mar";s:3:"111";s:3:"bru";s:3:"112";s:3:"e a";s:3:"113";s:3:"el ";s:3:"114";s:3:"ers";s:3:"115";s:3:"ret";s:3:"116";s:3:"som";s:3:"117";s:3:"tte";s:3:"118";s:3:"ve ";s:3:"119";s:3:" la";s:3:"120";s:3:" ud";s:3:"121";s:3:" ve";s:3:"122";s:3:"age";s:3:"123";s:3:"e d";s:3:"124";s:3:"e h";s:3:"125";s:3:"lse";s:3:"126";s:3:"man";s:3:"127";s:3:"rug";s:3:"128";s:3:"sel";s:3:"129";s:3:"ser";s:3:"130";s:3:" fi";s:3:"131";s:3:" op";s:3:"132";s:3:" pr";s:3:"133";s:3:"dt ";s:3:"134";s:3:"e i";s:3:"135";s:3:"n m";s:3:"136";s:3:"r m";s:3:"137";s:3:" an";s:3:"138";s:3:" re";s:3:"139";s:3:" sa";s:3:"140";s:3:"ion";s:3:"141";s:3:"ner";s:3:"142";s:3:"res";s:3:"143";s:3:"t i";s:3:"144";s:3:"get";s:3:"145";s:3:"n s";s:3:"146";s:3:"one";s:3:"147";s:3:"orb";s:3:"148";s:3:"t h";s:3:"149";s:3:"vis";s:3:"150";s:4:"år ";s:3:"151";s:3:" fr";s:3:"152";s:3:"bil";s:3:"153";s:3:"e k";s:3:"154";s:3:"ens";s:3:"155";s:3:"ind";s:3:"156";s:3:"omm";s:3:"157";s:3:"t m";s:3:"158";s:3:" hv";s:3:"159";s:3:" je";s:3:"160";s:3:"dan";s:3:"161";s:3:"ent";s:3:"162";s:3:"fte";s:3:"163";s:3:"nin";s:3:"164";s:3:" mi";s:3:"165";s:3:"e o";s:3:"166";s:3:"e p";s:3:"167";s:3:"n o";s:3:"168";s:3:"nte";s:3:"169";s:3:" ku";s:3:"170";s:3:"ell";s:3:"171";s:3:"nas";s:3:"172";s:3:"ore";s:3:"173";s:3:"r h";s:3:"174";s:3:"r k";s:3:"175";s:3:"sta";s:3:"176";s:3:"sto";s:3:"177";s:3:"dag";s:3:"178";s:3:"eri";s:3:"179";s:3:"kun";s:3:"180";s:3:"lde";s:3:"181";s:3:"mer";s:3:"182";s:3:"r a";s:3:"183";s:3:"r v";s:3:"184";s:3:"rek";s:3:"185";s:3:"rer";s:3:"186";s:3:"t o";s:3:"187";s:3:"tor";s:3:"188";s:4:"tør";s:3:"189";s:4:" få";s:3:"190";s:4:" må";s:3:"191";s:3:" to";s:3:"192";s:3:"boe";s:3:"193";s:3:"che";s:3:"194";s:3:"e v";s:3:"195";s:3:"i d";s:3:"196";s:3:"ive";s:3:"197";s:3:"kab";s:3:"198";s:3:"ns ";s:3:"199";s:3:"oel";s:3:"200";s:3:"se ";s:3:"201";s:3:"t v";s:3:"202";s:3:" al";s:3:"203";s:3:" bo";s:3:"204";s:3:" un";s:3:"205";s:3:"ans";s:3:"206";s:3:"dre";s:3:"207";s:3:"ire";s:3:"208";s:4:"køb";s:3:"209";s:3:"ors";s:3:"210";s:3:"ove";s:3:"211";s:3:"ren";s:3:"212";s:3:"t b";s:3:"213";s:4:"ør ";s:3:"214";s:3:" ka";s:3:"215";s:3:"ald";s:3:"216";s:3:"bet";s:3:"217";s:3:"gt ";s:3:"218";s:3:"isk";s:3:"219";s:3:"kal";s:3:"220";s:3:"kom";s:3:"221";s:3:"lev";s:3:"222";s:3:"n d";s:3:"223";s:3:"n i";s:3:"224";s:3:"pri";s:3:"225";s:3:"r p";s:3:"226";s:3:"rbr";s:3:"227";s:4:"søg";s:3:"228";s:3:"tel";s:3:"229";s:4:" så";s:3:"230";s:3:" te";s:3:"231";s:3:" va";s:3:"232";s:3:"al ";s:3:"233";s:3:"dir";s:3:"234";s:3:"eje";s:3:"235";s:3:"fis";s:3:"236";s:4:"gså";s:3:"237";s:3:"isc";s:3:"238";s:3:"jer";s:3:"239";s:3:"ker";s:3:"240";s:3:"ogs";s:3:"241";s:3:"sch";s:3:"242";s:3:"st ";s:3:"243";s:3:"t k";s:3:"244";s:3:"uge";s:3:"245";s:3:" di";s:3:"246";s:3:"ag ";s:3:"247";s:3:"d a";s:3:"248";s:3:"g i";s:3:"249";s:3:"ill";s:3:"250";s:3:"l a";s:3:"251";s:3:"lsk";s:3:"252";s:3:"n a";s:3:"253";s:3:"on ";s:3:"254";s:3:"sam";s:3:"255";s:3:"str";s:3:"256";s:3:"tet";s:3:"257";s:3:"var";s:3:"258";s:3:" mo";s:3:"259";s:3:"art";s:3:"260";s:3:"ash";s:3:"261";s:3:"att";s:3:"262";s:3:"e b";s:3:"263";s:3:"han";s:3:"264";s:3:"hav";s:3:"265";s:3:"kla";s:3:"266";s:3:"kon";s:3:"267";s:3:"n t";s:3:"268";s:3:"ned";s:3:"269";s:3:"r o";s:3:"270";s:3:"ra ";s:3:"271";s:3:"rre";s:3:"272";s:3:"ves";s:3:"273";s:3:"vil";s:3:"274";s:3:" el";s:3:"275";s:3:" kr";s:3:"276";s:3:" ov";s:3:"277";s:3:"ann";s:3:"278";s:3:"e u";s:3:"279";s:3:"ess";s:3:"280";s:3:"fra";s:3:"281";s:3:"g a";s:3:"282";s:3:"g d";s:3:"283";s:3:"int";s:3:"284";s:3:"ngs";s:3:"285";s:3:"rde";s:3:"286";s:3:"tra";s:3:"287";s:4:" år";s:3:"288";s:3:"akt";s:3:"289";s:3:"asi";s:3:"290";s:3:"em ";s:3:"291";s:3:"gel";s:3:"292";s:3:"gym";s:3:"293";s:3:"hol";s:3:"294";s:3:"kan";s:3:"295";s:3:"mna";s:3:"296";s:3:"n h";s:3:"297";s:3:"nsk";s:3:"298";s:3:"old";s:3:"299";}s:5:"dutch";a:300:{s:3:"en ";s:1:"0";s:3:"de ";s:1:"1";s:3:" de";s:1:"2";s:3:"et ";s:1:"3";s:3:"an ";s:1:"4";s:3:" he";s:1:"5";s:3:"er ";s:1:"6";s:3:" va";s:1:"7";s:3:"n d";s:1:"8";s:3:"van";s:1:"9";s:3:"een";s:2:"10";s:3:"het";s:2:"11";s:3:" ge";s:2:"12";s:3:"oor";s:2:"13";s:3:" ee";s:2:"14";s:3:"der";s:2:"15";s:3:" en";s:2:"16";s:3:"ij ";s:2:"17";s:3:"aar";s:2:"18";s:3:"gen";s:2:"19";s:3:"te ";s:2:"20";s:3:"ver";s:2:"21";s:3:" in";s:2:"22";s:3:" me";s:2:"23";s:3:"aan";s:2:"24";s:3:"den";s:2:"25";s:3:" we";s:2:"26";s:3:"at ";s:2:"27";s:3:"in ";s:2:"28";s:3:" da";s:2:"29";s:3:" te";s:2:"30";s:3:"eer";s:2:"31";s:3:"nde";s:2:"32";s:3:"ter";s:2:"33";s:3:"ste";s:2:"34";s:3:"n v";s:2:"35";s:3:" vo";s:2:"36";s:3:" zi";s:2:"37";s:3:"ing";s:2:"38";s:3:"n h";s:2:"39";s:3:"voo";s:2:"40";s:3:"is ";s:2:"41";s:3:" op";s:2:"42";s:3:"tie";s:2:"43";s:3:" aa";s:2:"44";s:3:"ede";s:2:"45";s:3:"erd";s:2:"46";s:3:"ers";s:2:"47";s:3:" be";s:2:"48";s:3:"eme";s:2:"49";s:3:"ten";s:2:"50";s:3:"ken";s:2:"51";s:3:"n e";s:2:"52";s:3:" ni";s:2:"53";s:3:" ve";s:2:"54";s:3:"ent";s:2:"55";s:3:"ijn";s:2:"56";s:3:"jn ";s:2:"57";s:3:"mee";s:2:"58";s:3:"iet";s:2:"59";s:3:"n w";s:2:"60";s:3:"ng ";s:2:"61";s:3:"nie";s:2:"62";s:3:" is";s:2:"63";s:3:"cht";s:2:"64";s:3:"dat";s:2:"65";s:3:"ere";s:2:"66";s:3:"ie ";s:2:"67";s:3:"ijk";s:2:"68";s:3:"n b";s:2:"69";s:3:"rde";s:2:"70";s:3:"ar ";s:2:"71";s:3:"e b";s:2:"72";s:3:"e a";s:2:"73";s:3:"met";s:2:"74";s:3:"t d";s:2:"75";s:3:"el ";s:2:"76";s:3:"ond";s:2:"77";s:3:"t h";s:2:"78";s:3:" al";s:2:"79";s:3:"e w";s:2:"80";s:3:"op ";s:2:"81";s:3:"ren";s:2:"82";s:3:" di";s:2:"83";s:3:" on";s:2:"84";s:3:"al ";s:2:"85";s:3:"and";s:2:"86";s:3:"bij";s:2:"87";s:3:"zij";s:2:"88";s:3:" bi";s:2:"89";s:3:" hi";s:2:"90";s:3:" wi";s:2:"91";s:3:"or ";s:2:"92";s:3:"r d";s:2:"93";s:3:"t v";s:2:"94";s:3:" wa";s:2:"95";s:3:"e h";s:2:"96";s:3:"lle";s:2:"97";s:3:"rt ";s:2:"98";s:3:"ang";s:2:"99";s:3:"hij";s:3:"100";s:3:"men";s:3:"101";s:3:"n a";s:3:"102";s:3:"n z";s:3:"103";s:3:"rs ";s:3:"104";s:3:" om";s:3:"105";s:3:"e o";s:3:"106";s:3:"e v";s:3:"107";s:3:"end";s:3:"108";s:3:"est";s:3:"109";s:3:"n t";s:3:"110";s:3:"par";s:3:"111";s:3:" pa";s:3:"112";s:3:" pr";s:3:"113";s:3:" ze";s:3:"114";s:3:"e g";s:3:"115";s:3:"e p";s:3:"116";s:3:"n p";s:3:"117";s:3:"ord";s:3:"118";s:3:"oud";s:3:"119";s:3:"raa";s:3:"120";s:3:"sch";s:3:"121";s:3:"t e";s:3:"122";s:3:"ege";s:3:"123";s:3:"ich";s:3:"124";s:3:"ien";s:3:"125";s:3:"aat";s:3:"126";s:3:"ek ";s:3:"127";s:3:"len";s:3:"128";s:3:"n m";s:3:"129";s:3:"nge";s:3:"130";s:3:"nt ";s:3:"131";s:3:"ove";s:3:"132";s:3:"rd ";s:3:"133";s:3:"wer";s:3:"134";s:3:" ma";s:3:"135";s:3:" mi";s:3:"136";s:3:"daa";s:3:"137";s:3:"e k";s:3:"138";s:3:"lij";s:3:"139";s:3:"mer";s:3:"140";s:3:"n g";s:3:"141";s:3:"n o";s:3:"142";s:3:"om ";s:3:"143";s:3:"sen";s:3:"144";s:3:"t b";s:3:"145";s:3:"wij";s:3:"146";s:3:" ho";s:3:"147";s:3:"e m";s:3:"148";s:3:"ele";s:3:"149";s:3:"gem";s:3:"150";s:3:"heb";s:3:"151";s:3:"pen";s:3:"152";s:3:"ude";s:3:"153";s:3:" bo";s:3:"154";s:3:" ja";s:3:"155";s:3:"die";s:3:"156";s:3:"e e";s:3:"157";s:3:"eli";s:3:"158";s:3:"erk";s:3:"159";s:3:"le ";s:3:"160";s:3:"pro";s:3:"161";s:3:"rij";s:3:"162";s:3:" er";s:3:"163";s:3:" za";s:3:"164";s:3:"e d";s:3:"165";s:3:"ens";s:3:"166";s:3:"ind";s:3:"167";s:3:"ke ";s:3:"168";s:3:"n k";s:3:"169";s:3:"nd ";s:3:"170";s:3:"nen";s:3:"171";s:3:"nte";s:3:"172";s:3:"r h";s:3:"173";s:3:"s d";s:3:"174";s:3:"s e";s:3:"175";s:3:"t z";s:3:"176";s:3:" b ";s:3:"177";s:3:" co";s:3:"178";s:3:" ik";s:3:"179";s:3:" ko";s:3:"180";s:3:" ov";s:3:"181";s:3:"eke";s:3:"182";s:3:"hou";s:3:"183";s:3:"ik ";s:3:"184";s:3:"iti";s:3:"185";s:3:"lan";s:3:"186";s:3:"ns ";s:3:"187";s:3:"t g";s:3:"188";s:3:"t m";s:3:"189";s:3:" do";s:3:"190";s:3:" le";s:3:"191";s:3:" zo";s:3:"192";s:3:"ams";s:3:"193";s:3:"e z";s:3:"194";s:3:"g v";s:3:"195";s:3:"it ";s:3:"196";s:3:"je ";s:3:"197";s:3:"ls ";s:3:"198";s:3:"maa";s:3:"199";s:3:"n i";s:3:"200";s:3:"nke";s:3:"201";s:3:"rke";s:3:"202";s:3:"uit";s:3:"203";s:3:" ha";s:3:"204";s:3:" ka";s:3:"205";s:3:" mo";s:3:"206";s:3:" re";s:3:"207";s:3:" st";s:3:"208";s:3:" to";s:3:"209";s:3:"age";s:3:"210";s:3:"als";s:3:"211";s:3:"ark";s:3:"212";s:3:"art";s:3:"213";s:3:"ben";s:3:"214";s:3:"e r";s:3:"215";s:3:"e s";s:3:"216";s:3:"ert";s:3:"217";s:3:"eze";s:3:"218";s:3:"ht ";s:3:"219";s:3:"ijd";s:3:"220";s:3:"lem";s:3:"221";s:3:"r v";s:3:"222";s:3:"rte";s:3:"223";s:3:"t p";s:3:"224";s:3:"zeg";s:3:"225";s:3:"zic";s:3:"226";s:3:"aak";s:3:"227";s:3:"aal";s:3:"228";s:3:"ag ";s:3:"229";s:3:"ale";s:3:"230";s:3:"bbe";s:3:"231";s:3:"ch ";s:3:"232";s:3:"e t";s:3:"233";s:3:"ebb";s:3:"234";s:3:"erz";s:3:"235";s:3:"ft ";s:3:"236";s:3:"ge ";s:3:"237";s:3:"led";s:3:"238";s:3:"mst";s:3:"239";s:3:"n n";s:3:"240";s:3:"oek";s:3:"241";s:3:"r i";s:3:"242";s:3:"t o";s:3:"243";s:3:"t w";s:3:"244";s:3:"tel";s:3:"245";s:3:"tte";s:3:"246";s:3:"uur";s:3:"247";s:3:"we ";s:3:"248";s:3:"zit";s:3:"249";s:3:" af";s:3:"250";s:3:" li";s:3:"251";s:3:" ui";s:3:"252";s:3:"ak ";s:3:"253";s:3:"all";s:3:"254";s:3:"aut";s:3:"255";s:3:"doo";s:3:"256";s:3:"e i";s:3:"257";s:3:"ene";s:3:"258";s:3:"erg";s:3:"259";s:3:"ete";s:3:"260";s:3:"ges";s:3:"261";s:3:"hee";s:3:"262";s:3:"jaa";s:3:"263";s:3:"jke";s:3:"264";s:3:"kee";s:3:"265";s:3:"kel";s:3:"266";s:3:"kom";s:3:"267";s:3:"lee";s:3:"268";s:3:"moe";s:3:"269";s:3:"n s";s:3:"270";s:3:"ort";s:3:"271";s:3:"rec";s:3:"272";s:3:"s o";s:3:"273";s:3:"s v";s:3:"274";s:3:"teg";s:3:"275";s:3:"tij";s:3:"276";s:3:"ven";s:3:"277";s:3:"waa";s:3:"278";s:3:"wel";s:3:"279";s:3:" an";s:3:"280";s:3:" au";s:3:"281";s:3:" bu";s:3:"282";s:3:" gr";s:3:"283";s:3:" pl";s:3:"284";s:3:" ti";s:3:"285";s:3:"'' ";s:3:"286";s:3:"ade";s:3:"287";s:3:"dag";s:3:"288";s:3:"e l";s:3:"289";s:3:"ech";s:3:"290";s:3:"eel";s:3:"291";s:3:"eft";s:3:"292";s:3:"ger";s:3:"293";s:3:"gt ";s:3:"294";s:3:"ig ";s:3:"295";s:3:"itt";s:3:"296";s:3:"j d";s:3:"297";s:3:"ppe";s:3:"298";s:3:"rda";s:3:"299";}s:7:"english";a:300:{s:3:" th";s:1:"0";s:3:"the";s:1:"1";s:3:"he ";s:1:"2";s:3:"ed ";s:1:"3";s:3:" to";s:1:"4";s:3:" in";s:1:"5";s:3:"er ";s:1:"6";s:3:"ing";s:1:"7";s:3:"ng ";s:1:"8";s:3:" an";s:1:"9";s:3:"nd ";s:2:"10";s:3:" of";s:2:"11";s:3:"and";s:2:"12";s:3:"to ";s:2:"13";s:3:"of ";s:2:"14";s:3:" co";s:2:"15";s:3:"at ";s:2:"16";s:3:"on ";s:2:"17";s:3:"in ";s:2:"18";s:3:" a ";s:2:"19";s:3:"d t";s:2:"20";s:3:" he";s:2:"21";s:3:"e t";s:2:"22";s:3:"ion";s:2:"23";s:3:"es ";s:2:"24";s:3:" re";s:2:"25";s:3:"re ";s:2:"26";s:3:"hat";s:2:"27";s:3:" sa";s:2:"28";s:3:" st";s:2:"29";s:3:" ha";s:2:"30";s:3:"her";s:2:"31";s:3:"tha";s:2:"32";s:3:"tio";s:2:"33";s:3:"or ";s:2:"34";s:3:" ''";s:2:"35";s:3:"en ";s:2:"36";s:3:" wh";s:2:"37";s:3:"e s";s:2:"38";s:3:"ent";s:2:"39";s:3:"n t";s:2:"40";s:3:"s a";s:2:"41";s:3:"as ";s:2:"42";s:3:"for";s:2:"43";s:3:"is ";s:2:"44";s:3:"t t";s:2:"45";s:3:" be";s:2:"46";s:3:"ld ";s:2:"47";s:3:"e a";s:2:"48";s:3:"rs ";s:2:"49";s:3:" wa";s:2:"50";s:3:"ut ";s:2:"51";s:3:"ve ";s:2:"52";s:3:"ll ";s:2:"53";s:3:"al ";s:2:"54";s:3:" ma";s:2:"55";s:3:"e i";s:2:"56";s:3:" fo";s:2:"57";s:3:"'s ";s:2:"58";s:3:"an ";s:2:"59";s:3:"est";s:2:"60";s:3:" hi";s:2:"61";s:3:" mo";s:2:"62";s:3:" se";s:2:"63";s:3:" pr";s:2:"64";s:3:"s t";s:2:"65";s:3:"ate";s:2:"66";s:3:"st ";s:2:"67";s:3:"ter";s:2:"68";s:3:"ere";s:2:"69";s:3:"ted";s:2:"70";s:3:"nt ";s:2:"71";s:3:"ver";s:2:"72";s:3:"d a";s:2:"73";s:3:" wi";s:2:"74";s:3:"se ";s:2:"75";s:3:"e c";s:2:"76";s:3:"ect";s:2:"77";s:3:"ns ";s:2:"78";s:3:" on";s:2:"79";s:3:"ly ";s:2:"80";s:3:"tol";s:2:"81";s:3:"ey ";s:2:"82";s:3:"r t";s:2:"83";s:3:" ca";s:2:"84";s:3:"ati";s:2:"85";s:3:"ts ";s:2:"86";s:3:"all";s:2:"87";s:3:" no";s:2:"88";s:3:"his";s:2:"89";s:3:"s o";s:2:"90";s:3:"ers";s:2:"91";s:3:"con";s:2:"92";s:3:"e o";s:2:"93";s:3:"ear";s:2:"94";s:3:"f t";s:2:"95";s:3:"e w";s:2:"96";s:3:"was";s:2:"97";s:3:"ons";s:2:"98";s:3:"sta";s:2:"99";s:3:"'' ";s:3:"100";s:3:"sti";s:3:"101";s:3:"n a";s:3:"102";s:3:"sto";s:3:"103";s:3:"t h";s:3:"104";s:3:" we";s:3:"105";s:3:"id ";s:3:"106";s:3:"th ";s:3:"107";s:3:" it";s:3:"108";s:3:"ce ";s:3:"109";s:3:" di";s:3:"110";s:3:"ave";s:3:"111";s:3:"d h";s:3:"112";s:3:"cou";s:3:"113";s:3:"pro";s:3:"114";s:3:"ad ";s:3:"115";s:3:"oll";s:3:"116";s:3:"ry ";s:3:"117";s:3:"d s";s:3:"118";s:3:"e m";s:3:"119";s:3:" so";s:3:"120";s:3:"ill";s:3:"121";s:3:"cti";s:3:"122";s:3:"te ";s:3:"123";s:3:"tor";s:3:"124";s:3:"eve";s:3:"125";s:3:"g t";s:3:"126";s:3:"it ";s:3:"127";s:3:" ch";s:3:"128";s:3:" de";s:3:"129";s:3:"hav";s:3:"130";s:3:"oul";s:3:"131";s:3:"ty ";s:3:"132";s:3:"uld";s:3:"133";s:3:"use";s:3:"134";s:3:" al";s:3:"135";s:3:"are";s:3:"136";s:3:"ch ";s:3:"137";s:3:"me ";s:3:"138";s:3:"out";s:3:"139";s:3:"ove";s:3:"140";s:3:"wit";s:3:"141";s:3:"ys ";s:3:"142";s:3:"chi";s:3:"143";s:3:"t a";s:3:"144";s:3:"ith";s:3:"145";s:3:"oth";s:3:"146";s:3:" ab";s:3:"147";s:3:" te";s:3:"148";s:3:" wo";s:3:"149";s:3:"s s";s:3:"150";s:3:"res";s:3:"151";s:3:"t w";s:3:"152";s:3:"tin";s:3:"153";s:3:"e b";s:3:"154";s:3:"e h";s:3:"155";s:3:"nce";s:3:"156";s:3:"t s";s:3:"157";s:3:"y t";s:3:"158";s:3:"e p";s:3:"159";s:3:"ele";s:3:"160";s:3:"hin";s:3:"161";s:3:"s i";s:3:"162";s:3:"nte";s:3:"163";s:3:" li";s:3:"164";s:3:"le ";s:3:"165";s:3:" do";s:3:"166";s:3:"aid";s:3:"167";s:3:"hey";s:3:"168";s:3:"ne ";s:3:"169";s:3:"s w";s:3:"170";s:3:" as";s:3:"171";s:3:" fr";s:3:"172";s:3:" tr";s:3:"173";s:3:"end";s:3:"174";s:3:"sai";s:3:"175";s:3:" el";s:3:"176";s:3:" ne";s:3:"177";s:3:" su";s:3:"178";s:3:"'t ";s:3:"179";s:3:"ay ";s:3:"180";s:3:"hou";s:3:"181";s:3:"ive";s:3:"182";s:3:"lec";s:3:"183";s:3:"n't";s:3:"184";s:3:" ye";s:3:"185";s:3:"but";s:3:"186";s:3:"d o";s:3:"187";s:3:"o t";s:3:"188";s:3:"y o";s:3:"189";s:3:" ho";s:3:"190";s:3:" me";s:3:"191";s:3:"be ";s:3:"192";s:3:"cal";s:3:"193";s:3:"e e";s:3:"194";s:3:"had";s:3:"195";s:3:"ple";s:3:"196";s:3:" at";s:3:"197";s:3:" bu";s:3:"198";s:3:" la";s:3:"199";s:3:"d b";s:3:"200";s:3:"s h";s:3:"201";s:3:"say";s:3:"202";s:3:"t i";s:3:"203";s:3:" ar";s:3:"204";s:3:"e f";s:3:"205";s:3:"ght";s:3:"206";s:3:"hil";s:3:"207";s:3:"igh";s:3:"208";s:3:"int";s:3:"209";s:3:"not";s:3:"210";s:3:"ren";s:3:"211";s:3:" is";s:3:"212";s:3:" pa";s:3:"213";s:3:" sh";s:3:"214";s:3:"ays";s:3:"215";s:3:"com";s:3:"216";s:3:"n s";s:3:"217";s:3:"r a";s:3:"218";s:3:"rin";s:3:"219";s:3:"y a";s:3:"220";s:3:" un";s:3:"221";s:3:"n c";s:3:"222";s:3:"om ";s:3:"223";s:3:"thi";s:3:"224";s:3:" mi";s:3:"225";s:3:"by ";s:3:"226";s:3:"d i";s:3:"227";s:3:"e d";s:3:"228";s:3:"e n";s:3:"229";s:3:"t o";s:3:"230";s:3:" by";s:3:"231";s:3:"e r";s:3:"232";s:3:"eri";s:3:"233";s:3:"old";s:3:"234";s:3:"ome";s:3:"235";s:3:"whe";s:3:"236";s:3:"yea";s:3:"237";s:3:" gr";s:3:"238";s:3:"ar ";s:3:"239";s:3:"ity";s:3:"240";s:3:"mpl";s:3:"241";s:3:"oun";s:3:"242";s:3:"one";s:3:"243";s:3:"ow ";s:3:"244";s:3:"r s";s:3:"245";s:3:"s f";s:3:"246";s:3:"tat";s:3:"247";s:3:" ba";s:3:"248";s:3:" vo";s:3:"249";s:3:"bou";s:3:"250";s:3:"sam";s:3:"251";s:3:"tim";s:3:"252";s:3:"vot";s:3:"253";s:3:"abo";s:3:"254";s:3:"ant";s:3:"255";s:3:"ds ";s:3:"256";s:3:"ial";s:3:"257";s:3:"ine";s:3:"258";s:3:"man";s:3:"259";s:3:"men";s:3:"260";s:3:" or";s:3:"261";s:3:" po";s:3:"262";s:3:"amp";s:3:"263";s:3:"can";s:3:"264";s:3:"der";s:3:"265";s:3:"e l";s:3:"266";s:3:"les";s:3:"267";s:3:"ny ";s:3:"268";s:3:"ot ";s:3:"269";s:3:"rec";s:3:"270";s:3:"tes";s:3:"271";s:3:"tho";s:3:"272";s:3:"ica";s:3:"273";s:3:"ild";s:3:"274";s:3:"ir ";s:3:"275";s:3:"nde";s:3:"276";s:3:"ose";s:3:"277";s:3:"ous";s:3:"278";s:3:"pre";s:3:"279";s:3:"ste";s:3:"280";s:3:"era";s:3:"281";s:3:"per";s:3:"282";s:3:"r o";s:3:"283";s:3:"red";s:3:"284";s:3:"rie";s:3:"285";s:3:" bo";s:3:"286";s:3:" le";s:3:"287";s:3:"ali";s:3:"288";s:3:"ars";s:3:"289";s:3:"ore";s:3:"290";s:3:"ric";s:3:"291";s:3:"s m";s:3:"292";s:3:"str";s:3:"293";s:3:" fa";s:3:"294";s:3:"ess";s:3:"295";s:3:"ie ";s:3:"296";s:3:"ist";s:3:"297";s:3:"lat";s:3:"298";s:3:"uri";s:3:"299";}s:8:"estonian";a:300:{s:3:"st ";s:1:"0";s:3:" ka";s:1:"1";s:3:"on ";s:1:"2";s:3:"ja ";s:1:"3";s:3:" va";s:1:"4";s:3:" on";s:1:"5";s:3:" ja";s:1:"6";s:3:" ko";s:1:"7";s:3:"se ";s:1:"8";s:3:"ast";s:1:"9";s:3:"le ";s:2:"10";s:3:"es ";s:2:"11";s:3:"as ";s:2:"12";s:3:"is ";s:2:"13";s:3:"ud ";s:2:"14";s:3:" sa";s:2:"15";s:3:"da ";s:2:"16";s:3:"ga ";s:2:"17";s:3:" ta";s:2:"18";s:3:"aja";s:2:"19";s:3:"sta";s:2:"20";s:3:" ku";s:2:"21";s:3:" pe";s:2:"22";s:3:"a k";s:2:"23";s:3:"est";s:2:"24";s:3:"ist";s:2:"25";s:3:"ks ";s:2:"26";s:3:"ta ";s:2:"27";s:3:"al ";s:2:"28";s:3:"ava";s:2:"29";s:3:"id ";s:2:"30";s:3:"saa";s:2:"31";s:3:"mis";s:2:"32";s:3:"te ";s:2:"33";s:3:"val";s:2:"34";s:3:" et";s:2:"35";s:3:"nud";s:2:"36";s:3:" te";s:2:"37";s:3:"inn";s:2:"38";s:3:" se";s:2:"39";s:3:" tu";s:2:"40";s:3:"a v";s:2:"41";s:3:"alu";s:2:"42";s:3:"e k";s:2:"43";s:3:"ise";s:2:"44";s:3:"lu ";s:2:"45";s:3:"ma ";s:2:"46";s:3:"mes";s:2:"47";s:3:" mi";s:2:"48";s:3:"et ";s:2:"49";s:3:"iku";s:2:"50";s:3:"lin";s:2:"51";s:3:"ad ";s:2:"52";s:3:"el ";s:2:"53";s:3:"ime";s:2:"54";s:3:"ne ";s:2:"55";s:3:"nna";s:2:"56";s:3:" ha";s:2:"57";s:3:" in";s:2:"58";s:3:" ke";s:2:"59";s:4:" võ";s:2:"60";s:3:"a s";s:2:"61";s:3:"a t";s:2:"62";s:3:"ab ";s:2:"63";s:3:"e s";s:2:"64";s:3:"esi";s:2:"65";s:3:" la";s:2:"66";s:3:" li";s:2:"67";s:3:"e v";s:2:"68";s:3:"eks";s:2:"69";s:3:"ema";s:2:"70";s:3:"las";s:2:"71";s:3:"les";s:2:"72";s:3:"rju";s:2:"73";s:3:"tle";s:2:"74";s:3:"tsi";s:2:"75";s:3:"tus";s:2:"76";s:3:"upa";s:2:"77";s:3:"use";s:2:"78";s:3:"ust";s:2:"79";s:3:"var";s:2:"80";s:4:" lä";s:2:"81";s:3:"ali";s:2:"82";s:3:"arj";s:2:"83";s:3:"de ";s:2:"84";s:3:"ete";s:2:"85";s:3:"i t";s:2:"86";s:3:"iga";s:2:"87";s:3:"ilm";s:2:"88";s:3:"kui";s:2:"89";s:3:"li ";s:2:"90";s:3:"tul";s:2:"91";s:3:" ei";s:2:"92";s:3:" me";s:2:"93";s:4:" sõ";s:2:"94";s:3:"aal";s:2:"95";s:3:"ata";s:2:"96";s:3:"dus";s:2:"97";s:3:"ei ";s:2:"98";s:3:"nik";s:2:"99";s:3:"pea";s:3:"100";s:3:"s k";s:3:"101";s:3:"s o";s:3:"102";s:3:"sal";s:3:"103";s:4:"sõn";s:3:"104";s:3:"ter";s:3:"105";s:3:"ul ";s:3:"106";s:4:"või";s:3:"107";s:3:" el";s:3:"108";s:3:" ne";s:3:"109";s:3:"a j";s:3:"110";s:3:"ate";s:3:"111";s:3:"end";s:3:"112";s:3:"i k";s:3:"113";s:3:"ita";s:3:"114";s:3:"kar";s:3:"115";s:3:"kor";s:3:"116";s:3:"l o";s:3:"117";s:3:"lt ";s:3:"118";s:3:"maa";s:3:"119";s:3:"oli";s:3:"120";s:3:"sti";s:3:"121";s:3:"vad";s:3:"122";s:5:"ään";s:3:"123";s:3:" ju";s:3:"124";s:4:" jä";s:3:"125";s:4:" kü";s:3:"126";s:3:" ma";s:3:"127";s:3:" po";s:3:"128";s:4:" üt";s:3:"129";s:3:"aas";s:3:"130";s:3:"aks";s:3:"131";s:3:"at ";s:3:"132";s:3:"ed ";s:3:"133";s:3:"eri";s:3:"134";s:3:"hoi";s:3:"135";s:3:"i s";s:3:"136";s:3:"ka ";s:3:"137";s:3:"la ";s:3:"138";s:3:"nni";s:3:"139";s:3:"oid";s:3:"140";s:3:"pai";s:3:"141";s:3:"rit";s:3:"142";s:3:"us ";s:3:"143";s:4:"ütl";s:3:"144";s:3:" aa";s:3:"145";s:3:" lo";s:3:"146";s:3:" to";s:3:"147";s:3:" ve";s:3:"148";s:3:"a e";s:3:"149";s:3:"ada";s:3:"150";s:3:"aid";s:3:"151";s:3:"ami";s:3:"152";s:3:"and";s:3:"153";s:3:"dla";s:3:"154";s:3:"e j";s:3:"155";s:3:"ega";s:3:"156";s:3:"gi ";s:3:"157";s:3:"gu ";s:3:"158";s:3:"i p";s:3:"159";s:3:"idl";s:3:"160";s:3:"ik ";s:3:"161";s:3:"ini";s:3:"162";s:3:"jup";s:3:"163";s:3:"kal";s:3:"164";s:3:"kas";s:3:"165";s:3:"kes";s:3:"166";s:3:"koh";s:3:"167";s:3:"s e";s:3:"168";s:3:"s p";s:3:"169";s:3:"sel";s:3:"170";s:3:"sse";s:3:"171";s:3:"ui ";s:3:"172";s:3:" pi";s:3:"173";s:3:" si";s:3:"174";s:3:"aru";s:3:"175";s:3:"eda";s:3:"176";s:3:"eva";s:3:"177";s:3:"fil";s:3:"178";s:3:"i v";s:3:"179";s:3:"ida";s:3:"180";s:3:"ing";s:3:"181";s:5:"lää";s:3:"182";s:3:"me ";s:3:"183";s:3:"na ";s:3:"184";s:3:"nda";s:3:"185";s:3:"nim";s:3:"186";s:3:"ole";s:3:"187";s:3:"ots";s:3:"188";s:3:"ris";s:3:"189";s:3:"s l";s:3:"190";s:3:"sia";s:3:"191";s:3:"t p";s:3:"192";s:3:" en";s:3:"193";s:3:" mu";s:3:"194";s:3:" ol";s:3:"195";s:4:" põ";s:3:"196";s:3:" su";s:3:"197";s:4:" vä";s:3:"198";s:4:" üh";s:3:"199";s:3:"a l";s:3:"200";s:3:"a p";s:3:"201";s:3:"aga";s:3:"202";s:3:"ale";s:3:"203";s:3:"aps";s:3:"204";s:3:"arv";s:3:"205";s:3:"e a";s:3:"206";s:3:"ela";s:3:"207";s:3:"ika";s:3:"208";s:3:"lle";s:3:"209";s:3:"loo";s:3:"210";s:3:"mal";s:3:"211";s:3:"pet";s:3:"212";s:3:"t k";s:3:"213";s:3:"tee";s:3:"214";s:3:"tis";s:3:"215";s:3:"vat";s:3:"216";s:4:"äne";s:3:"217";s:4:"õnn";s:3:"218";s:3:" es";s:3:"219";s:3:" fi";s:3:"220";s:3:" vi";s:3:"221";s:3:"a i";s:3:"222";s:3:"a o";s:3:"223";s:3:"aab";s:3:"224";s:3:"aap";s:3:"225";s:3:"ala";s:3:"226";s:3:"alt";s:3:"227";s:3:"ama";s:3:"228";s:3:"anu";s:3:"229";s:3:"e p";s:3:"230";s:3:"e t";s:3:"231";s:3:"eal";s:3:"232";s:3:"eli";s:3:"233";s:3:"haa";s:3:"234";s:3:"hin";s:3:"235";s:3:"iva";s:3:"236";s:3:"kon";s:3:"237";s:3:"ku ";s:3:"238";s:3:"lik";s:3:"239";s:3:"lm ";s:3:"240";s:3:"min";s:3:"241";s:3:"n t";s:3:"242";s:3:"odu";s:3:"243";s:3:"oon";s:3:"244";s:3:"psa";s:3:"245";s:3:"ri ";s:3:"246";s:3:"si ";s:3:"247";s:3:"stu";s:3:"248";s:3:"t e";s:3:"249";s:3:"t s";s:3:"250";s:3:"ti ";s:3:"251";s:3:"ule";s:3:"252";s:3:"uur";s:3:"253";s:3:"vas";s:3:"254";s:3:"vee";s:3:"255";s:3:" ki";s:3:"256";s:3:" ni";s:3:"257";s:4:" nä";s:3:"258";s:3:" ra";s:3:"259";s:3:"aig";s:3:"260";s:3:"aka";s:3:"261";s:3:"all";s:3:"262";s:3:"atu";s:3:"263";s:3:"e e";s:3:"264";s:3:"eis";s:3:"265";s:3:"ers";s:3:"266";s:3:"i e";s:3:"267";s:3:"ii ";s:3:"268";s:3:"iis";s:3:"269";s:3:"il ";s:3:"270";s:3:"ima";s:3:"271";s:3:"its";s:3:"272";s:3:"kka";s:3:"273";s:3:"kuh";s:3:"274";s:3:"l k";s:3:"275";s:3:"lat";s:3:"276";s:3:"maj";s:3:"277";s:3:"ndu";s:3:"278";s:3:"ni ";s:3:"279";s:3:"nii";s:3:"280";s:3:"oma";s:3:"281";s:3:"ool";s:3:"282";s:3:"rso";s:3:"283";s:3:"ru ";s:3:"284";s:3:"rva";s:3:"285";s:3:"s t";s:3:"286";s:3:"sek";s:3:"287";s:3:"son";s:3:"288";s:3:"ste";s:3:"289";s:3:"t m";s:3:"290";s:3:"taj";s:3:"291";s:3:"tam";s:3:"292";s:3:"ude";s:3:"293";s:3:"uho";s:3:"294";s:3:"vai";s:3:"295";s:3:" ag";s:3:"296";s:3:" os";s:3:"297";s:3:" pa";s:3:"298";s:3:" re";s:3:"299";}s:5:"farsi";a:300:{s:5:"ان ";s:1:"0";s:5:"ای ";s:1:"1";s:5:"ه ا";s:1:"2";s:5:" اي";s:1:"3";s:5:" در";s:1:"4";s:5:"به ";s:1:"5";s:5:" بر";s:1:"6";s:5:"در ";s:1:"7";s:6:"ران";s:1:"8";s:5:" به";s:1:"9";s:5:"ی ا";s:2:"10";s:5:"از ";s:2:"11";s:5:"ين ";s:2:"12";s:5:"می ";s:2:"13";s:5:" از";s:2:"14";s:5:"ده ";s:2:"15";s:5:"ست ";s:2:"16";s:6:"است";s:2:"17";s:5:" اس";s:2:"18";s:5:" که";s:2:"19";s:5:"که ";s:2:"20";s:6:"اير";s:2:"21";s:5:"ند ";s:2:"22";s:6:"اين";s:2:"23";s:5:" ها";s:2:"24";s:6:"يرا";s:2:"25";s:5:"ود ";s:2:"26";s:5:" را";s:2:"27";s:6:"های";s:2:"28";s:5:" خو";s:2:"29";s:5:"ته ";s:2:"30";s:5:"را ";s:2:"31";s:6:"رای";s:2:"32";s:5:"رد ";s:2:"33";s:5:"ن ب";s:2:"34";s:6:"کرد";s:2:"35";s:4:" و ";s:2:"36";s:5:" کر";s:2:"37";s:5:"ات ";s:2:"38";s:6:"برا";s:2:"39";s:5:"د ک";s:2:"40";s:6:"مان";s:2:"41";s:5:"ی د";s:2:"42";s:5:" ان";s:2:"43";s:6:"خوا";s:2:"44";s:6:"شور";s:2:"45";s:5:" با";s:2:"46";s:5:"ن ا";s:2:"47";s:5:" سا";s:2:"48";s:6:"تمی";s:2:"49";s:5:"ری ";s:2:"50";s:6:"اتم";s:2:"51";s:5:"ا ا";s:2:"52";s:6:"واه";s:2:"53";s:5:" ات";s:2:"54";s:5:" عر";s:2:"55";s:5:"اق ";s:2:"56";s:5:"ر م";s:2:"57";s:6:"راق";s:2:"58";s:6:"عرا";s:2:"59";s:5:"ی ب";s:2:"60";s:5:" تا";s:2:"61";s:5:" تو";s:2:"62";s:5:"ار ";s:2:"63";s:5:"ر ا";s:2:"64";s:5:"ن م";s:2:"65";s:5:"ه ب";s:2:"66";s:5:"ور ";s:2:"67";s:5:"يد ";s:2:"68";s:5:"ی ک";s:2:"69";s:5:" ام";s:2:"70";s:5:" دا";s:2:"71";s:5:" کن";s:2:"72";s:6:"اهد";s:2:"73";s:5:"هد ";s:2:"74";s:5:" آن";s:2:"75";s:5:" می";s:2:"76";s:5:" ني";s:2:"77";s:5:" گف";s:2:"78";s:5:"د ا";s:2:"79";s:6:"گفت";s:2:"80";s:5:" کش";s:2:"81";s:5:"ا ب";s:2:"82";s:5:"نی ";s:2:"83";s:5:"ها ";s:2:"84";s:6:"کشو";s:2:"85";s:5:" رو";s:2:"86";s:5:"ت ک";s:2:"87";s:6:"نيو";s:2:"88";s:5:"ه م";s:2:"89";s:5:"وی ";s:2:"90";s:5:"ی ت";s:2:"91";s:5:" شو";s:2:"92";s:5:"ال ";s:2:"93";s:6:"دار";s:2:"94";s:5:"مه ";s:2:"95";s:5:"ن ک";s:2:"96";s:5:"ه د";s:2:"97";s:5:"يه ";s:2:"98";s:5:" ما";s:2:"99";s:6:"امه";s:3:"100";s:5:"د ب";s:3:"101";s:6:"زار";s:3:"102";s:6:"ورا";s:3:"103";s:6:"گزا";s:3:"104";s:5:" پي";s:3:"105";s:5:"آن ";s:3:"106";s:6:"انت";s:3:"107";s:5:"ت ا";s:3:"108";s:5:"فت ";s:3:"109";s:5:"ه ن";s:3:"110";s:5:"ی خ";s:3:"111";s:6:"اما";s:3:"112";s:6:"بات";s:3:"113";s:5:"ما ";s:3:"114";s:6:"ملل";s:3:"115";s:6:"نام";s:3:"116";s:5:"ير ";s:3:"117";s:5:"ی م";s:3:"118";s:5:"ی ه";s:3:"119";s:5:" آم";s:3:"120";s:5:" ای";s:3:"121";s:5:" من";s:3:"122";s:6:"انس";s:3:"123";s:6:"اني";s:3:"124";s:5:"ت د";s:3:"125";s:6:"رده";s:3:"126";s:6:"ساز";s:3:"127";s:5:"ن د";s:3:"128";s:5:"نه ";s:3:"129";s:6:"ورد";s:3:"130";s:5:" او";s:3:"131";s:5:" بي";s:3:"132";s:5:" سو";s:3:"133";s:5:" شد";s:3:"134";s:6:"اده";s:3:"135";s:6:"اند";s:3:"136";s:5:"با ";s:3:"137";s:5:"ت ب";s:3:"138";s:5:"ر ب";s:3:"139";s:5:"ز ا";s:3:"140";s:6:"زما";s:3:"141";s:6:"سته";s:3:"142";s:5:"ن ر";s:3:"143";s:5:"ه س";s:3:"144";s:6:"وان";s:3:"145";s:5:"وز ";s:3:"146";s:5:"ی ر";s:3:"147";s:5:"ی س";s:3:"148";s:5:" هس";s:3:"149";s:6:"ابا";s:3:"150";s:5:"ام ";s:3:"151";s:6:"اور";s:3:"152";s:6:"تخا";s:3:"153";s:6:"خاب";s:3:"154";s:6:"خود";s:3:"155";s:5:"د د";s:3:"156";s:5:"دن ";s:3:"157";s:6:"رها";s:3:"158";s:6:"روز";s:3:"159";s:6:"رگز";s:3:"160";s:6:"نتخ";s:3:"161";s:5:"ه ش";s:3:"162";s:5:"ه ه";s:3:"163";s:6:"هست";s:3:"164";s:5:"يت ";s:3:"165";s:5:"يم ";s:3:"166";s:5:" دو";s:3:"167";s:5:" دي";s:3:"168";s:5:" مو";s:3:"169";s:5:" نو";s:3:"170";s:5:" هم";s:3:"171";s:5:" کا";s:3:"172";s:5:"اد ";s:3:"173";s:6:"اری";s:3:"174";s:6:"انی";s:3:"175";s:5:"بر ";s:3:"176";s:6:"بود";s:3:"177";s:5:"ت ه";s:3:"178";s:5:"ح ه";s:3:"179";s:6:"حال";s:3:"180";s:5:"رش ";s:3:"181";s:5:"عه ";s:3:"182";s:5:"لی ";s:3:"183";s:5:"وم ";s:3:"184";s:6:"ژان";s:3:"185";s:5:" سل";s:3:"186";s:6:"آمر";s:3:"187";s:5:"اح ";s:3:"188";s:6:"توس";s:3:"189";s:6:"داد";s:3:"190";s:6:"دام";s:3:"191";s:5:"ر د";s:3:"192";s:5:"ره ";s:3:"193";s:6:"ريک";s:3:"194";s:5:"زی ";s:3:"195";s:6:"سلا";s:3:"196";s:6:"شود";s:3:"197";s:6:"لاح";s:3:"198";s:6:"مري";s:3:"199";s:6:"نند";s:3:"200";s:5:"ه ع";s:3:"201";s:6:"يما";s:3:"202";s:6:"يکا";s:3:"203";s:6:"پيم";s:3:"204";s:5:"گر ";s:3:"205";s:5:" آژ";s:3:"206";s:5:" ال";s:3:"207";s:5:" بو";s:3:"208";s:5:" مق";s:3:"209";s:5:" مل";s:3:"210";s:5:" وی";s:3:"211";s:6:"آژا";s:3:"212";s:6:"ازم";s:3:"213";s:6:"ازی";s:3:"214";s:6:"بار";s:3:"215";s:6:"برن";s:3:"216";s:5:"ر آ";s:3:"217";s:5:"ز س";s:3:"218";s:6:"سعه";s:3:"219";s:6:"شته";s:3:"220";s:6:"مات";s:3:"221";s:5:"ن آ";s:3:"222";s:5:"ن پ";s:3:"223";s:5:"نس ";s:3:"224";s:5:"ه گ";s:3:"225";s:6:"وسع";s:3:"226";s:6:"يان";s:3:"227";s:6:"يوم";s:3:"228";s:5:"کا ";s:3:"229";s:6:"کام";s:3:"230";s:6:"کند";s:3:"231";s:5:" خا";s:3:"232";s:5:" سر";s:3:"233";s:6:"آور";s:3:"234";s:6:"ارد";s:3:"235";s:6:"اقد";s:3:"236";s:6:"ايم";s:3:"237";s:6:"ايی";s:3:"238";s:6:"برگ";s:3:"239";s:5:"ت ع";s:3:"240";s:5:"تن ";s:3:"241";s:5:"خت ";s:3:"242";s:5:"د و";s:3:"243";s:5:"ر خ";s:3:"244";s:5:"رک ";s:3:"245";s:6:"زير";s:3:"246";s:6:"فته";s:3:"247";s:6:"قدا";s:3:"248";s:5:"ل ت";s:3:"249";s:6:"مين";s:3:"250";s:5:"ن گ";s:3:"251";s:5:"ه آ";s:3:"252";s:5:"ه خ";s:3:"253";s:5:"ه ک";s:3:"254";s:6:"ورک";s:3:"255";s:6:"ويو";s:3:"256";s:6:"يور";s:3:"257";s:6:"يوي";s:3:"258";s:5:"يی ";s:3:"259";s:5:"ک ت";s:3:"260";s:5:"ی ش";s:3:"261";s:5:" اق";s:3:"262";s:5:" حا";s:3:"263";s:5:" حق";s:3:"264";s:5:" دس";s:3:"265";s:5:" شک";s:3:"266";s:5:" عم";s:3:"267";s:5:" يک";s:3:"268";s:5:"ا ت";s:3:"269";s:5:"ا د";s:3:"270";s:6:"ارج";s:3:"271";s:6:"بين";s:3:"272";s:5:"ت م";s:3:"273";s:5:"ت و";s:3:"274";s:6:"تاي";s:3:"275";s:6:"دست";s:3:"276";s:5:"ر ح";s:3:"277";s:5:"ر س";s:3:"278";s:6:"رنا";s:3:"279";s:5:"ز ب";s:3:"280";s:6:"شکا";s:3:"281";s:5:"لل ";s:3:"282";s:5:"م ک";s:3:"283";s:5:"مز ";s:3:"284";s:6:"ندا";s:3:"285";s:6:"نوا";s:3:"286";s:5:"و ا";s:3:"287";s:6:"وره";s:3:"288";s:5:"ون ";s:3:"289";s:6:"وند";s:3:"290";s:6:"يمز";s:3:"291";s:5:" آو";s:3:"292";s:5:" اع";s:3:"293";s:5:" فر";s:3:"294";s:5:" مت";s:3:"295";s:5:" نه";s:3:"296";s:5:" هر";s:3:"297";s:5:" وز";s:3:"298";s:5:" گز";s:3:"299";}s:7:"finnish";a:300:{s:3:"en ";s:1:"0";s:3:"in ";s:1:"1";s:3:"an ";s:1:"2";s:3:"on ";s:1:"3";s:3:"ist";s:1:"4";s:3:"ta ";s:1:"5";s:3:"ja ";s:1:"6";s:3:"n t";s:1:"7";s:3:"sa ";s:1:"8";s:3:"sta";s:1:"9";s:3:"aan";s:2:"10";s:3:"n p";s:2:"11";s:3:" on";s:2:"12";s:3:"ssa";s:2:"13";s:3:"tta";s:2:"14";s:4:"tä ";s:2:"15";s:3:" ka";s:2:"16";s:3:" pa";s:2:"17";s:3:"si ";s:2:"18";s:3:" ja";s:2:"19";s:3:"n k";s:2:"20";s:3:"lla";s:2:"21";s:4:"än ";s:2:"22";s:3:"een";s:2:"23";s:3:"n v";s:2:"24";s:3:"ksi";s:2:"25";s:3:"ett";s:2:"26";s:3:"nen";s:2:"27";s:3:"taa";s:2:"28";s:4:"ttä";s:2:"29";s:3:" va";s:2:"30";s:3:"ill";s:2:"31";s:3:"itt";s:2:"32";s:3:" jo";s:2:"33";s:3:" ko";s:2:"34";s:3:"n s";s:2:"35";s:3:" tu";s:2:"36";s:3:"ia ";s:2:"37";s:3:" su";s:2:"38";s:3:"a p";s:2:"39";s:3:"aa ";s:2:"40";s:3:"la ";s:2:"41";s:3:"lle";s:2:"42";s:3:"n m";s:2:"43";s:3:"le ";s:2:"44";s:3:"tte";s:2:"45";s:3:"na ";s:2:"46";s:3:" ta";s:2:"47";s:3:" ve";s:2:"48";s:3:"at ";s:2:"49";s:3:" vi";s:2:"50";s:3:"utt";s:2:"51";s:3:" sa";s:2:"52";s:3:"ise";s:2:"53";s:3:"sen";s:2:"54";s:3:" ku";s:2:"55";s:4:" nä";s:2:"56";s:4:" pä";s:2:"57";s:3:"ste";s:2:"58";s:3:" ol";s:2:"59";s:3:"a t";s:2:"60";s:3:"ais";s:2:"61";s:3:"maa";s:2:"62";s:3:"ti ";s:2:"63";s:3:"a o";s:2:"64";s:3:"oit";s:2:"65";s:5:"pää";s:2:"66";s:3:" pi";s:2:"67";s:3:"a v";s:2:"68";s:3:"ala";s:2:"69";s:3:"ine";s:2:"70";s:3:"isi";s:2:"71";s:3:"tel";s:2:"72";s:3:"tti";s:2:"73";s:3:" si";s:2:"74";s:3:"a k";s:2:"75";s:3:"all";s:2:"76";s:3:"iin";s:2:"77";s:3:"kin";s:2:"78";s:4:"stä";s:2:"79";s:3:"uom";s:2:"80";s:3:"vii";s:2:"81";s:3:" ma";s:2:"82";s:3:" se";s:2:"83";s:4:"enä";s:2:"84";s:3:" mu";s:2:"85";s:3:"a s";s:2:"86";s:3:"est";s:2:"87";s:3:"iss";s:2:"88";s:4:"llä";s:2:"89";s:3:"lok";s:2:"90";s:4:"lä ";s:2:"91";s:3:"n j";s:2:"92";s:3:"n o";s:2:"93";s:3:"toi";s:2:"94";s:3:"ven";s:2:"95";s:3:"ytt";s:2:"96";s:3:" li";s:2:"97";s:3:"ain";s:2:"98";s:3:"et ";s:2:"99";s:3:"ina";s:3:"100";s:3:"n a";s:3:"101";s:3:"n n";s:3:"102";s:3:"oll";s:3:"103";s:3:"plo";s:3:"104";s:3:"ten";s:3:"105";s:3:"ust";s:3:"106";s:4:"äll";s:3:"107";s:5:"ään";s:3:"108";s:3:" to";s:3:"109";s:3:"den";s:3:"110";s:3:"men";s:3:"111";s:3:"oki";s:3:"112";s:3:"suo";s:3:"113";s:4:"sä ";s:3:"114";s:5:"tää";s:3:"115";s:3:"uks";s:3:"116";s:3:"vat";s:3:"117";s:3:" al";s:3:"118";s:3:" ke";s:3:"119";s:3:" te";s:3:"120";s:3:"a e";s:3:"121";s:3:"lii";s:3:"122";s:3:"tai";s:3:"123";s:3:"tei";s:3:"124";s:4:"äis";s:3:"125";s:5:"ää ";s:3:"126";s:3:" pl";s:3:"127";s:3:"ell";s:3:"128";s:3:"i t";s:3:"129";s:3:"ide";s:3:"130";s:3:"ikk";s:3:"131";s:3:"ki ";s:3:"132";s:3:"nta";s:3:"133";s:3:"ova";s:3:"134";s:3:"yst";s:3:"135";s:3:"yt ";s:3:"136";s:4:"ä p";s:3:"137";s:4:"äyt";s:3:"138";s:3:" ha";s:3:"139";s:3:" pe";s:3:"140";s:4:" tä";s:3:"141";s:3:"a n";s:3:"142";s:3:"aik";s:3:"143";s:3:"i p";s:3:"144";s:3:"i v";s:3:"145";s:3:"nyt";s:3:"146";s:4:"näy";s:3:"147";s:3:"pal";s:3:"148";s:3:"tee";s:3:"149";s:3:"un ";s:3:"150";s:3:" me";s:3:"151";s:3:"a m";s:3:"152";s:3:"ess";s:3:"153";s:3:"kau";s:3:"154";s:3:"pai";s:3:"155";s:3:"stu";s:3:"156";s:3:"ut ";s:3:"157";s:3:"voi";s:3:"158";s:3:" et";s:3:"159";s:3:"a h";s:3:"160";s:3:"eis";s:3:"161";s:3:"hte";s:3:"162";s:3:"i o";s:3:"163";s:3:"iik";s:3:"164";s:3:"ita";s:3:"165";s:3:"jou";s:3:"166";s:3:"mis";s:3:"167";s:3:"nin";s:3:"168";s:3:"nut";s:3:"169";s:3:"sia";s:3:"170";s:4:"ssä";s:3:"171";s:3:"van";s:3:"172";s:3:" ty";s:3:"173";s:3:" yh";s:3:"174";s:3:"aks";s:3:"175";s:3:"ime";s:3:"176";s:3:"loi";s:3:"177";s:3:"me ";s:3:"178";s:3:"n e";s:3:"179";s:3:"n h";s:3:"180";s:3:"n l";s:3:"181";s:3:"oin";s:3:"182";s:3:"ome";s:3:"183";s:3:"ott";s:3:"184";s:3:"ouk";s:3:"185";s:3:"sit";s:3:"186";s:3:"sti";s:3:"187";s:3:"tet";s:3:"188";s:3:"tie";s:3:"189";s:3:"ukk";s:3:"190";s:4:"ä k";s:3:"191";s:3:" ra";s:3:"192";s:3:" ti";s:3:"193";s:3:"aja";s:3:"194";s:3:"asi";s:3:"195";s:3:"ent";s:3:"196";s:3:"iga";s:3:"197";s:3:"iig";s:3:"198";s:3:"ite";s:3:"199";s:3:"jan";s:3:"200";s:3:"kaa";s:3:"201";s:3:"kse";s:3:"202";s:3:"laa";s:3:"203";s:3:"lan";s:3:"204";s:3:"li ";s:3:"205";s:4:"näj";s:3:"206";s:3:"ole";s:3:"207";s:3:"tii";s:3:"208";s:3:"usi";s:3:"209";s:5:"äjä";s:3:"210";s:3:" ov";s:3:"211";s:3:"a a";s:3:"212";s:3:"ant";s:3:"213";s:3:"ava";s:3:"214";s:3:"ei ";s:3:"215";s:3:"eri";s:3:"216";s:3:"kan";s:3:"217";s:3:"kku";s:3:"218";s:3:"lai";s:3:"219";s:3:"lis";s:3:"220";s:4:"läi";s:3:"221";s:3:"mat";s:3:"222";s:3:"ois";s:3:"223";s:3:"pel";s:3:"224";s:3:"sil";s:3:"225";s:3:"sty";s:3:"226";s:3:"taj";s:3:"227";s:3:"tav";s:3:"228";s:3:"ttu";s:3:"229";s:4:"työ";s:3:"230";s:4:"yös";s:3:"231";s:4:"ä o";s:3:"232";s:3:" ai";s:3:"233";s:3:" pu";s:3:"234";s:3:"a j";s:3:"235";s:3:"a l";s:3:"236";s:3:"aal";s:3:"237";s:3:"arv";s:3:"238";s:3:"ass";s:3:"239";s:3:"ien";s:3:"240";s:3:"imi";s:3:"241";s:3:"imm";s:3:"242";s:4:"itä";s:3:"243";s:3:"ka ";s:3:"244";s:3:"kes";s:3:"245";s:3:"kue";s:3:"246";s:3:"lee";s:3:"247";s:3:"lin";s:3:"248";s:3:"llo";s:3:"249";s:3:"one";s:3:"250";s:3:"ri ";s:3:"251";s:3:"t o";s:3:"252";s:3:"t p";s:3:"253";s:3:"tu ";s:3:"254";s:3:"val";s:3:"255";s:3:"vuo";s:3:"256";s:3:" ei";s:3:"257";s:3:" he";s:3:"258";s:3:" hy";s:3:"259";s:3:" my";s:3:"260";s:3:" vo";s:3:"261";s:3:"ali";s:3:"262";s:3:"alo";s:3:"263";s:3:"ano";s:3:"264";s:3:"ast";s:3:"265";s:3:"att";s:3:"266";s:3:"auk";s:3:"267";s:3:"eli";s:3:"268";s:3:"ely";s:3:"269";s:3:"hti";s:3:"270";s:3:"ika";s:3:"271";s:3:"ken";s:3:"272";s:3:"kki";s:3:"273";s:3:"lys";s:3:"274";s:3:"min";s:3:"275";s:4:"myö";s:3:"276";s:3:"oht";s:3:"277";s:3:"oma";s:3:"278";s:3:"tus";s:3:"279";s:3:"umi";s:3:"280";s:3:"yks";s:3:"281";s:4:"ät ";s:3:"282";s:5:"ääl";s:3:"283";s:4:"ös ";s:3:"284";s:3:" ar";s:3:"285";s:3:" eu";s:3:"286";s:3:" hu";s:3:"287";s:3:" na";s:3:"288";s:3:"aat";s:3:"289";s:3:"alk";s:3:"290";s:3:"alu";s:3:"291";s:3:"ans";s:3:"292";s:3:"arj";s:3:"293";s:3:"enn";s:3:"294";s:3:"han";s:3:"295";s:3:"kuu";s:3:"296";s:3:"n y";s:3:"297";s:3:"set";s:3:"298";s:3:"sim";s:3:"299";}s:6:"french";a:300:{s:3:"es ";s:1:"0";s:3:" de";s:1:"1";s:3:"de ";s:1:"2";s:3:" le";s:1:"3";s:3:"ent";s:1:"4";s:3:"le ";s:1:"5";s:3:"nt ";s:1:"6";s:3:"la ";s:1:"7";s:3:"s d";s:1:"8";s:3:" la";s:1:"9";s:3:"ion";s:2:"10";s:3:"on ";s:2:"11";s:3:"re ";s:2:"12";s:3:" pa";s:2:"13";s:3:"e l";s:2:"14";s:3:"e d";s:2:"15";s:3:" l'";s:2:"16";s:3:"e p";s:2:"17";s:3:" co";s:2:"18";s:3:" pr";s:2:"19";s:3:"tio";s:2:"20";s:3:"ns ";s:2:"21";s:3:" en";s:2:"22";s:3:"ne ";s:2:"23";s:3:"que";s:2:"24";s:3:"r l";s:2:"25";s:3:"les";s:2:"26";s:3:"ur ";s:2:"27";s:3:"en ";s:2:"28";s:3:"ati";s:2:"29";s:3:"ue ";s:2:"30";s:3:" po";s:2:"31";s:3:" d'";s:2:"32";s:3:"par";s:2:"33";s:3:" a ";s:2:"34";s:3:"et ";s:2:"35";s:3:"it ";s:2:"36";s:3:" qu";s:2:"37";s:3:"men";s:2:"38";s:3:"ons";s:2:"39";s:3:"te ";s:2:"40";s:3:" et";s:2:"41";s:3:"t d";s:2:"42";s:3:" re";s:2:"43";s:3:"des";s:2:"44";s:3:" un";s:2:"45";s:3:"ie ";s:2:"46";s:3:"s l";s:2:"47";s:3:" su";s:2:"48";s:3:"pou";s:2:"49";s:3:" au";s:2:"50";s:4:" à ";s:2:"51";s:3:"con";s:2:"52";s:3:"er ";s:2:"53";s:3:" no";s:2:"54";s:3:"ait";s:2:"55";s:3:"e c";s:2:"56";s:3:"se ";s:2:"57";s:4:"té ";s:2:"58";s:3:"du ";s:2:"59";s:3:" du";s:2:"60";s:4:" dé";s:2:"61";s:3:"ce ";s:2:"62";s:3:"e e";s:2:"63";s:3:"is ";s:2:"64";s:3:"n d";s:2:"65";s:3:"s a";s:2:"66";s:3:" so";s:2:"67";s:3:"e r";s:2:"68";s:3:"e s";s:2:"69";s:3:"our";s:2:"70";s:3:"res";s:2:"71";s:3:"ssi";s:2:"72";s:3:"eur";s:2:"73";s:3:" se";s:2:"74";s:3:"eme";s:2:"75";s:3:"est";s:2:"76";s:3:"us ";s:2:"77";s:3:"sur";s:2:"78";s:3:"ant";s:2:"79";s:3:"iqu";s:2:"80";s:3:"s p";s:2:"81";s:3:"une";s:2:"82";s:3:"uss";s:2:"83";s:3:"l'a";s:2:"84";s:3:"pro";s:2:"85";s:3:"ter";s:2:"86";s:3:"tre";s:2:"87";s:3:"end";s:2:"88";s:3:"rs ";s:2:"89";s:3:" ce";s:2:"90";s:3:"e a";s:2:"91";s:3:"t p";s:2:"92";s:3:"un ";s:2:"93";s:3:" ma";s:2:"94";s:3:" ru";s:2:"95";s:4:" ré";s:2:"96";s:3:"ous";s:2:"97";s:3:"ris";s:2:"98";s:3:"rus";s:2:"99";s:3:"sse";s:3:"100";s:3:"ans";s:3:"101";s:3:"ar ";s:3:"102";s:3:"com";s:3:"103";s:3:"e m";s:3:"104";s:3:"ire";s:3:"105";s:3:"nce";s:3:"106";s:3:"nte";s:3:"107";s:3:"t l";s:3:"108";s:3:" av";s:3:"109";s:3:" mo";s:3:"110";s:3:" te";s:3:"111";s:3:"il ";s:3:"112";s:3:"me ";s:3:"113";s:3:"ont";s:3:"114";s:3:"ten";s:3:"115";s:3:"a p";s:3:"116";s:3:"dan";s:3:"117";s:3:"pas";s:3:"118";s:3:"qui";s:3:"119";s:3:"s e";s:3:"120";s:3:"s s";s:3:"121";s:3:" in";s:3:"122";s:3:"ist";s:3:"123";s:3:"lle";s:3:"124";s:3:"nou";s:3:"125";s:4:"pré";s:3:"126";s:3:"'un";s:3:"127";s:3:"air";s:3:"128";s:3:"d'a";s:3:"129";s:3:"ir ";s:3:"130";s:3:"n e";s:3:"131";s:3:"rop";s:3:"132";s:3:"ts ";s:3:"133";s:3:" da";s:3:"134";s:3:"a s";s:3:"135";s:3:"as ";s:3:"136";s:3:"au ";s:3:"137";s:3:"den";s:3:"138";s:3:"mai";s:3:"139";s:3:"mis";s:3:"140";s:3:"ori";s:3:"141";s:3:"out";s:3:"142";s:3:"rme";s:3:"143";s:3:"sio";s:3:"144";s:3:"tte";s:3:"145";s:3:"ux ";s:3:"146";s:3:"a d";s:3:"147";s:3:"ien";s:3:"148";s:3:"n a";s:3:"149";s:3:"ntr";s:3:"150";s:3:"omm";s:3:"151";s:3:"ort";s:3:"152";s:3:"ouv";s:3:"153";s:3:"s c";s:3:"154";s:3:"son";s:3:"155";s:3:"tes";s:3:"156";s:3:"ver";s:3:"157";s:4:"ère";s:3:"158";s:3:" il";s:3:"159";s:3:" m ";s:3:"160";s:3:" sa";s:3:"161";s:3:" ve";s:3:"162";s:3:"a r";s:3:"163";s:3:"ais";s:3:"164";s:3:"ava";s:3:"165";s:3:"di ";s:3:"166";s:3:"n p";s:3:"167";s:3:"sti";s:3:"168";s:3:"ven";s:3:"169";s:3:" mi";s:3:"170";s:3:"ain";s:3:"171";s:3:"enc";s:3:"172";s:3:"for";s:3:"173";s:4:"ité";s:3:"174";s:3:"lar";s:3:"175";s:3:"oir";s:3:"176";s:3:"rem";s:3:"177";s:3:"ren";s:3:"178";s:3:"rro";s:3:"179";s:4:"rés";s:3:"180";s:3:"sie";s:3:"181";s:3:"t a";s:3:"182";s:3:"tur";s:3:"183";s:3:" pe";s:3:"184";s:3:" to";s:3:"185";s:3:"d'u";s:3:"186";s:3:"ell";s:3:"187";s:3:"err";s:3:"188";s:3:"ers";s:3:"189";s:3:"ide";s:3:"190";s:3:"ine";s:3:"191";s:3:"iss";s:3:"192";s:3:"mes";s:3:"193";s:3:"por";s:3:"194";s:3:"ran";s:3:"195";s:3:"sit";s:3:"196";s:3:"st ";s:3:"197";s:3:"t r";s:3:"198";s:3:"uti";s:3:"199";s:3:"vai";s:3:"200";s:4:"é l";s:3:"201";s:4:"ési";s:3:"202";s:3:" di";s:3:"203";s:3:" n'";s:3:"204";s:4:" ét";s:3:"205";s:3:"a c";s:3:"206";s:3:"ass";s:3:"207";s:3:"e t";s:3:"208";s:3:"in ";s:3:"209";s:3:"nde";s:3:"210";s:3:"pre";s:3:"211";s:3:"rat";s:3:"212";s:3:"s m";s:3:"213";s:3:"ste";s:3:"214";s:3:"tai";s:3:"215";s:3:"tch";s:3:"216";s:3:"ui ";s:3:"217";s:3:"uro";s:3:"218";s:4:"ès ";s:3:"219";s:3:" es";s:3:"220";s:3:" fo";s:3:"221";s:3:" tr";s:3:"222";s:3:"'ad";s:3:"223";s:3:"app";s:3:"224";s:3:"aux";s:3:"225";s:4:"e à";s:3:"226";s:3:"ett";s:3:"227";s:3:"iti";s:3:"228";s:3:"lit";s:3:"229";s:3:"nal";s:3:"230";s:4:"opé";s:3:"231";s:3:"r d";s:3:"232";s:3:"ra ";s:3:"233";s:3:"rai";s:3:"234";s:3:"ror";s:3:"235";s:3:"s r";s:3:"236";s:3:"tat";s:3:"237";s:4:"uté";s:3:"238";s:4:"à l";s:3:"239";s:3:" af";s:3:"240";s:3:"anc";s:3:"241";s:3:"ara";s:3:"242";s:3:"art";s:3:"243";s:3:"bre";s:3:"244";s:4:"ché";s:3:"245";s:3:"dre";s:3:"246";s:3:"e f";s:3:"247";s:3:"ens";s:3:"248";s:3:"lem";s:3:"249";s:3:"n r";s:3:"250";s:3:"n t";s:3:"251";s:3:"ndr";s:3:"252";s:3:"nne";s:3:"253";s:3:"onn";s:3:"254";s:3:"pos";s:3:"255";s:3:"s t";s:3:"256";s:3:"tiq";s:3:"257";s:3:"ure";s:3:"258";s:3:" tu";s:3:"259";s:3:"ale";s:3:"260";s:3:"and";s:3:"261";s:3:"ave";s:3:"262";s:3:"cla";s:3:"263";s:3:"cou";s:3:"264";s:3:"e n";s:3:"265";s:3:"emb";s:3:"266";s:3:"ins";s:3:"267";s:3:"jou";s:3:"268";s:3:"mme";s:3:"269";s:3:"rie";s:3:"270";s:4:"rès";s:3:"271";s:3:"sem";s:3:"272";s:3:"str";s:3:"273";s:3:"t i";s:3:"274";s:3:"ues";s:3:"275";s:3:"uni";s:3:"276";s:3:"uve";s:3:"277";s:4:"é d";s:3:"278";s:4:"ée ";s:3:"279";s:3:" ch";s:3:"280";s:3:" do";s:3:"281";s:3:" eu";s:3:"282";s:3:" fa";s:3:"283";s:3:" lo";s:3:"284";s:3:" ne";s:3:"285";s:3:" ra";s:3:"286";s:3:"arl";s:3:"287";s:3:"att";s:3:"288";s:3:"ec ";s:3:"289";s:3:"ica";s:3:"290";s:3:"l a";s:3:"291";s:3:"l'o";s:3:"292";s:4:"l'é";s:3:"293";s:3:"mmi";s:3:"294";s:3:"nta";s:3:"295";s:3:"orm";s:3:"296";s:3:"ou ";s:3:"297";s:3:"r u";s:3:"298";s:3:"rle";s:3:"299";}s:6:"german";a:300:{s:3:"en ";s:1:"0";s:3:"er ";s:1:"1";s:3:" de";s:1:"2";s:3:"der";s:1:"3";s:3:"ie ";s:1:"4";s:3:" di";s:1:"5";s:3:"die";s:1:"6";s:3:"sch";s:1:"7";s:3:"ein";s:1:"8";s:3:"che";s:1:"9";s:3:"ich";s:2:"10";s:3:"den";s:2:"11";s:3:"in ";s:2:"12";s:3:"te ";s:2:"13";s:3:"ch ";s:2:"14";s:3:" ei";s:2:"15";s:3:"ung";s:2:"16";s:3:"n d";s:2:"17";s:3:"nd ";s:2:"18";s:3:" be";s:2:"19";s:3:"ver";s:2:"20";s:3:"es ";s:2:"21";s:3:" zu";s:2:"22";s:3:"eit";s:2:"23";s:3:"gen";s:2:"24";s:3:"und";s:2:"25";s:3:" un";s:2:"26";s:3:" au";s:2:"27";s:3:" in";s:2:"28";s:3:"cht";s:2:"29";s:3:"it ";s:2:"30";s:3:"ten";s:2:"31";s:3:" da";s:2:"32";s:3:"ent";s:2:"33";s:3:" ve";s:2:"34";s:3:"and";s:2:"35";s:3:" ge";s:2:"36";s:3:"ine";s:2:"37";s:3:" mi";s:2:"38";s:3:"r d";s:2:"39";s:3:"hen";s:2:"40";s:3:"ng ";s:2:"41";s:3:"nde";s:2:"42";s:3:" vo";s:2:"43";s:3:"e d";s:2:"44";s:3:"ber";s:2:"45";s:3:"men";s:2:"46";s:3:"ei ";s:2:"47";s:3:"mit";s:2:"48";s:3:" st";s:2:"49";s:3:"ter";s:2:"50";s:3:"ren";s:2:"51";s:3:"t d";s:2:"52";s:3:" er";s:2:"53";s:3:"ere";s:2:"54";s:3:"n s";s:2:"55";s:3:"ste";s:2:"56";s:3:" se";s:2:"57";s:3:"e s";s:2:"58";s:3:"ht ";s:2:"59";s:3:"des";s:2:"60";s:3:"ist";s:2:"61";s:3:"ne ";s:2:"62";s:3:"auf";s:2:"63";s:3:"e a";s:2:"64";s:3:"isc";s:2:"65";s:3:"on ";s:2:"66";s:3:"rte";s:2:"67";s:3:" re";s:2:"68";s:3:" we";s:2:"69";s:3:"ges";s:2:"70";s:3:"uch";s:2:"71";s:4:" fü";s:2:"72";s:3:" so";s:2:"73";s:3:"bei";s:2:"74";s:3:"e e";s:2:"75";s:3:"nen";s:2:"76";s:3:"r s";s:2:"77";s:3:"ach";s:2:"78";s:4:"für";s:2:"79";s:3:"ier";s:2:"80";s:3:"par";s:2:"81";s:4:"ür ";s:2:"82";s:3:" ha";s:2:"83";s:3:"as ";s:2:"84";s:3:"ert";s:2:"85";s:3:" an";s:2:"86";s:3:" pa";s:2:"87";s:3:" sa";s:2:"88";s:3:" sp";s:2:"89";s:3:" wi";s:2:"90";s:3:"for";s:2:"91";s:3:"tag";s:2:"92";s:3:"zu ";s:2:"93";s:3:"das";s:2:"94";s:3:"rei";s:2:"95";s:3:"he ";s:2:"96";s:3:"hre";s:2:"97";s:3:"nte";s:2:"98";s:3:"sen";s:2:"99";s:3:"vor";s:3:"100";s:3:" sc";s:3:"101";s:3:"ech";s:3:"102";s:3:"etz";s:3:"103";s:3:"hei";s:3:"104";s:3:"lan";s:3:"105";s:3:"n a";s:3:"106";s:3:"pd ";s:3:"107";s:3:"st ";s:3:"108";s:3:"sta";s:3:"109";s:3:"ese";s:3:"110";s:3:"lic";s:3:"111";s:3:" ab";s:3:"112";s:3:" si";s:3:"113";s:3:"gte";s:3:"114";s:3:" wa";s:3:"115";s:3:"iti";s:3:"116";s:3:"kei";s:3:"117";s:3:"n e";s:3:"118";s:3:"nge";s:3:"119";s:3:"sei";s:3:"120";s:3:"tra";s:3:"121";s:3:"zen";s:3:"122";s:3:" im";s:3:"123";s:3:" la";s:3:"124";s:3:"art";s:3:"125";s:3:"im ";s:3:"126";s:3:"lle";s:3:"127";s:3:"n w";s:3:"128";s:3:"rde";s:3:"129";s:3:"rec";s:3:"130";s:3:"set";s:3:"131";s:3:"str";s:3:"132";s:3:"tei";s:3:"133";s:3:"tte";s:3:"134";s:3:" ni";s:3:"135";s:3:"e p";s:3:"136";s:3:"ehe";s:3:"137";s:3:"ers";s:3:"138";s:3:"g d";s:3:"139";s:3:"nic";s:3:"140";s:3:"von";s:3:"141";s:3:" al";s:3:"142";s:3:" pr";s:3:"143";s:3:"an ";s:3:"144";s:3:"aus";s:3:"145";s:3:"erf";s:3:"146";s:3:"r e";s:3:"147";s:3:"tze";s:3:"148";s:4:"tür";s:3:"149";s:3:"uf ";s:3:"150";s:3:"ag ";s:3:"151";s:3:"als";s:3:"152";s:3:"ar ";s:3:"153";s:3:"chs";s:3:"154";s:3:"end";s:3:"155";s:3:"ge ";s:3:"156";s:3:"ige";s:3:"157";s:3:"ion";s:3:"158";s:3:"ls ";s:3:"159";s:3:"n m";s:3:"160";s:3:"ngs";s:3:"161";s:3:"nis";s:3:"162";s:3:"nt ";s:3:"163";s:3:"ord";s:3:"164";s:3:"s s";s:3:"165";s:3:"sse";s:3:"166";s:4:" tü";s:3:"167";s:3:"ahl";s:3:"168";s:3:"e b";s:3:"169";s:3:"ede";s:3:"170";s:3:"em ";s:3:"171";s:3:"len";s:3:"172";s:3:"n i";s:3:"173";s:3:"orm";s:3:"174";s:3:"pro";s:3:"175";s:3:"rke";s:3:"176";s:3:"run";s:3:"177";s:3:"s d";s:3:"178";s:3:"wah";s:3:"179";s:3:"wer";s:3:"180";s:4:"ürk";s:3:"181";s:3:" me";s:3:"182";s:3:"age";s:3:"183";s:3:"att";s:3:"184";s:3:"ell";s:3:"185";s:3:"est";s:3:"186";s:3:"hat";s:3:"187";s:3:"n b";s:3:"188";s:3:"oll";s:3:"189";s:3:"raf";s:3:"190";s:3:"s a";s:3:"191";s:3:"tsc";s:3:"192";s:3:" es";s:3:"193";s:3:" fo";s:3:"194";s:3:" gr";s:3:"195";s:3:" ja";s:3:"196";s:3:"abe";s:3:"197";s:3:"auc";s:3:"198";s:3:"ben";s:3:"199";s:3:"e n";s:3:"200";s:3:"ege";s:3:"201";s:3:"lie";s:3:"202";s:3:"n u";s:3:"203";s:3:"r v";s:3:"204";s:3:"re ";s:3:"205";s:3:"rit";s:3:"206";s:3:"sag";s:3:"207";s:3:" am";s:3:"208";s:3:"agt";s:3:"209";s:3:"ahr";s:3:"210";s:3:"bra";s:3:"211";s:3:"de ";s:3:"212";s:3:"erd";s:3:"213";s:3:"her";s:3:"214";s:3:"ite";s:3:"215";s:3:"le ";s:3:"216";s:3:"n p";s:3:"217";s:3:"n v";s:3:"218";s:3:"or ";s:3:"219";s:3:"rbe";s:3:"220";s:3:"rt ";s:3:"221";s:3:"sic";s:3:"222";s:3:"wie";s:3:"223";s:4:"übe";s:3:"224";s:3:" is";s:3:"225";s:4:" üb";s:3:"226";s:3:"cha";s:3:"227";s:3:"chi";s:3:"228";s:3:"e f";s:3:"229";s:3:"e m";s:3:"230";s:3:"eri";s:3:"231";s:3:"ied";s:3:"232";s:3:"mme";s:3:"233";s:3:"ner";s:3:"234";s:3:"r a";s:3:"235";s:3:"sti";s:3:"236";s:3:"t a";s:3:"237";s:3:"t s";s:3:"238";s:3:"tis";s:3:"239";s:3:" ko";s:3:"240";s:3:"arb";s:3:"241";s:3:"ds ";s:3:"242";s:3:"gan";s:3:"243";s:3:"n z";s:3:"244";s:3:"r f";s:3:"245";s:3:"r w";s:3:"246";s:3:"ran";s:3:"247";s:3:"se ";s:3:"248";s:3:"t i";s:3:"249";s:3:"wei";s:3:"250";s:3:"wir";s:3:"251";s:3:" br";s:3:"252";s:3:" np";s:3:"253";s:3:"am ";s:3:"254";s:3:"bes";s:3:"255";s:3:"d d";s:3:"256";s:3:"deu";s:3:"257";s:3:"e g";s:3:"258";s:3:"e k";s:3:"259";s:3:"efo";s:3:"260";s:3:"et ";s:3:"261";s:3:"eut";s:3:"262";s:3:"fen";s:3:"263";s:3:"hse";s:3:"264";s:3:"lte";s:3:"265";s:3:"n r";s:3:"266";s:3:"npd";s:3:"267";s:3:"r b";s:3:"268";s:3:"rhe";s:3:"269";s:3:"t w";s:3:"270";s:3:"tz ";s:3:"271";s:3:" fr";s:3:"272";s:3:" ih";s:3:"273";s:3:" ke";s:3:"274";s:3:" ma";s:3:"275";s:3:"ame";s:3:"276";s:3:"ang";s:3:"277";s:3:"d s";s:3:"278";s:3:"eil";s:3:"279";s:3:"el ";s:3:"280";s:3:"era";s:3:"281";s:3:"erh";s:3:"282";s:3:"h d";s:3:"283";s:3:"i d";s:3:"284";s:3:"kan";s:3:"285";s:3:"n f";s:3:"286";s:3:"n l";s:3:"287";s:3:"nts";s:3:"288";s:3:"och";s:3:"289";s:3:"rag";s:3:"290";s:3:"rd ";s:3:"291";s:3:"spd";s:3:"292";s:3:"spr";s:3:"293";s:3:"tio";s:3:"294";s:3:" ar";s:3:"295";s:3:" en";s:3:"296";s:3:" ka";s:3:"297";s:3:"ark";s:3:"298";s:3:"ass";s:3:"299";}s:5:"hausa";a:300:{s:3:" da";s:1:"0";s:3:"da ";s:1:"1";s:3:"in ";s:1:"2";s:3:"an ";s:1:"3";s:3:"ya ";s:1:"4";s:3:" wa";s:1:"5";s:3:" ya";s:1:"6";s:3:"na ";s:1:"7";s:3:"ar ";s:1:"8";s:3:"a d";s:1:"9";s:3:" ma";s:2:"10";s:3:"wa ";s:2:"11";s:3:"a a";s:2:"12";s:3:"a k";s:2:"13";s:3:"a s";s:2:"14";s:3:" ta";s:2:"15";s:3:"wan";s:2:"16";s:3:" a ";s:2:"17";s:3:" ba";s:2:"18";s:3:" ka";s:2:"19";s:3:"ta ";s:2:"20";s:3:"a y";s:2:"21";s:3:"n d";s:2:"22";s:3:" ha";s:2:"23";s:3:" na";s:2:"24";s:3:" su";s:2:"25";s:3:" sa";s:2:"26";s:3:"kin";s:2:"27";s:3:"sa ";s:2:"28";s:3:"ata";s:2:"29";s:3:" ko";s:2:"30";s:3:"a t";s:2:"31";s:3:"su ";s:2:"32";s:3:" ga";s:2:"33";s:3:"ai ";s:2:"34";s:3:" sh";s:2:"35";s:3:"a m";s:2:"36";s:3:"uwa";s:2:"37";s:3:"iya";s:2:"38";s:3:"ma ";s:2:"39";s:3:"a w";s:2:"40";s:3:"asa";s:2:"41";s:3:"yan";s:2:"42";s:3:"ka ";s:2:"43";s:3:"ani";s:2:"44";s:3:"shi";s:2:"45";s:3:"a b";s:2:"46";s:3:"a h";s:2:"47";s:3:"a c";s:2:"48";s:3:"ama";s:2:"49";s:3:"ba ";s:2:"50";s:3:"nan";s:2:"51";s:3:"n a";s:2:"52";s:3:" mu";s:2:"53";s:3:"ana";s:2:"54";s:3:" yi";s:2:"55";s:3:"a g";s:2:"56";s:3:" za";s:2:"57";s:3:"i d";s:2:"58";s:3:" ku";s:2:"59";s:3:"aka";s:2:"60";s:3:"yi ";s:2:"61";s:3:"n k";s:2:"62";s:3:"ann";s:2:"63";s:3:"ke ";s:2:"64";s:3:"tar";s:2:"65";s:3:" ci";s:2:"66";s:3:"iki";s:2:"67";s:3:"n s";s:2:"68";s:3:"ko ";s:2:"69";s:3:" ra";s:2:"70";s:3:"ki ";s:2:"71";s:3:"ne ";s:2:"72";s:3:"a z";s:2:"73";s:3:"mat";s:2:"74";s:3:"hak";s:2:"75";s:3:"nin";s:2:"76";s:3:"e d";s:2:"77";s:3:"nna";s:2:"78";s:3:"uma";s:2:"79";s:3:"nda";s:2:"80";s:3:"a n";s:2:"81";s:3:"ada";s:2:"82";s:3:"cik";s:2:"83";s:3:"ni ";s:2:"84";s:3:"rin";s:2:"85";s:3:"una";s:2:"86";s:3:"ara";s:2:"87";s:3:"kum";s:2:"88";s:3:"akk";s:2:"89";s:3:" ce";s:2:"90";s:3:" du";s:2:"91";s:3:"man";s:2:"92";s:3:"n y";s:2:"93";s:3:"nci";s:2:"94";s:3:"sar";s:2:"95";s:3:"aki";s:2:"96";s:3:"awa";s:2:"97";s:3:"ci ";s:2:"98";s:3:"kan";s:2:"99";s:3:"kar";s:3:"100";s:3:"ari";s:3:"101";s:3:"n m";s:3:"102";s:3:"and";s:3:"103";s:3:"hi ";s:3:"104";s:3:"n t";s:3:"105";s:3:"ga ";s:3:"106";s:3:"owa";s:3:"107";s:3:"ash";s:3:"108";s:3:"kam";s:3:"109";s:3:"dan";s:3:"110";s:3:"ewa";s:3:"111";s:3:"nsa";s:3:"112";s:3:"ali";s:3:"113";s:3:"ami";s:3:"114";s:3:" ab";s:3:"115";s:3:" do";s:3:"116";s:3:"anc";s:3:"117";s:3:"n r";s:3:"118";s:3:"aya";s:3:"119";s:3:"i n";s:3:"120";s:3:"sun";s:3:"121";s:3:"uka";s:3:"122";s:3:" al";s:3:"123";s:3:" ne";s:3:"124";s:3:"a'a";s:3:"125";s:3:"cew";s:3:"126";s:3:"cin";s:3:"127";s:3:"mas";s:3:"128";s:3:"tak";s:3:"129";s:3:"un ";s:3:"130";s:3:"aba";s:3:"131";s:3:"kow";s:3:"132";s:3:"a r";s:3:"133";s:3:"ra ";s:3:"134";s:3:" ja";s:3:"135";s:4:" ƙa";s:3:"136";s:3:"en ";s:3:"137";s:3:"r d";s:3:"138";s:3:"sam";s:3:"139";s:3:"tsa";s:3:"140";s:3:" ru";s:3:"141";s:3:"ce ";s:3:"142";s:3:"i a";s:3:"143";s:3:"abi";s:3:"144";s:3:"ida";s:3:"145";s:3:"mut";s:3:"146";s:3:"n g";s:3:"147";s:3:"n j";s:3:"148";s:3:"san";s:3:"149";s:4:"a ƙ";s:3:"150";s:3:"har";s:3:"151";s:3:"on ";s:3:"152";s:3:"i m";s:3:"153";s:3:"suk";s:3:"154";s:3:" ak";s:3:"155";s:3:" ji";s:3:"156";s:3:"yar";s:3:"157";s:3:"'ya";s:3:"158";s:3:"kwa";s:3:"159";s:3:"min";s:3:"160";s:3:" 'y";s:3:"161";s:3:"ane";s:3:"162";s:3:"ban";s:3:"163";s:3:"ins";s:3:"164";s:3:"ruw";s:3:"165";s:3:"i k";s:3:"166";s:3:"n h";s:3:"167";s:3:" ad";s:3:"168";s:3:"ake";s:3:"169";s:3:"n w";s:3:"170";s:3:"sha";s:3:"171";s:3:"utu";s:3:"172";s:4:" ƴa";s:3:"173";s:3:"bay";s:3:"174";s:3:"tan";s:3:"175";s:4:"ƴan";s:3:"176";s:3:"bin";s:3:"177";s:3:"duk";s:3:"178";s:3:"e m";s:3:"179";s:3:"n n";s:3:"180";s:3:"oka";s:3:"181";s:3:"yin";s:3:"182";s:4:"ɗan";s:3:"183";s:3:" fa";s:3:"184";s:3:"a i";s:3:"185";s:3:"kki";s:3:"186";s:3:"re ";s:3:"187";s:3:"za ";s:3:"188";s:3:"ala";s:3:"189";s:3:"asu";s:3:"190";s:3:"han";s:3:"191";s:3:"i y";s:3:"192";s:3:"mar";s:3:"193";s:3:"ran";s:3:"194";s:4:"ƙas";s:3:"195";s:3:"add";s:3:"196";s:3:"ars";s:3:"197";s:3:"gab";s:3:"198";s:3:"ira";s:3:"199";s:3:"mma";s:3:"200";s:3:"u d";s:3:"201";s:3:" ts";s:3:"202";s:3:"abb";s:3:"203";s:3:"abu";s:3:"204";s:3:"aga";s:3:"205";s:3:"gar";s:3:"206";s:3:"n b";s:3:"207";s:4:" ɗa";s:3:"208";s:3:"aci";s:3:"209";s:3:"aik";s:3:"210";s:3:"am ";s:3:"211";s:3:"dun";s:3:"212";s:3:"e s";s:3:"213";s:3:"i b";s:3:"214";s:3:"i w";s:3:"215";s:3:"kas";s:3:"216";s:3:"kok";s:3:"217";s:3:"wam";s:3:"218";s:3:" am";s:3:"219";s:3:"amf";s:3:"220";s:3:"bba";s:3:"221";s:3:"din";s:3:"222";s:3:"fan";s:3:"223";s:3:"gwa";s:3:"224";s:3:"i s";s:3:"225";s:3:"wat";s:3:"226";s:3:"ano";s:3:"227";s:3:"are";s:3:"228";s:3:"dai";s:3:"229";s:3:"iri";s:3:"230";s:3:"ma'";s:3:"231";s:3:" la";s:3:"232";s:3:"all";s:3:"233";s:3:"dam";s:3:"234";s:3:"ika";s:3:"235";s:3:"mi ";s:3:"236";s:3:"she";s:3:"237";s:3:"tum";s:3:"238";s:3:"uni";s:3:"239";s:3:" an";s:3:"240";s:3:" ai";s:3:"241";s:3:" ke";s:3:"242";s:3:" ki";s:3:"243";s:3:"dag";s:3:"244";s:3:"mai";s:3:"245";s:3:"mfa";s:3:"246";s:3:"no ";s:3:"247";s:3:"nsu";s:3:"248";s:3:"o d";s:3:"249";s:3:"sak";s:3:"250";s:3:"um ";s:3:"251";s:3:" bi";s:3:"252";s:3:" gw";s:3:"253";s:3:" kw";s:3:"254";s:3:"jam";s:3:"255";s:3:"yya";s:3:"256";s:3:"a j";s:3:"257";s:3:"fa ";s:3:"258";s:3:"uta";s:3:"259";s:3:" hu";s:3:"260";s:3:"'a ";s:3:"261";s:3:"ans";s:3:"262";s:4:"aɗa";s:3:"263";s:3:"dda";s:3:"264";s:3:"hin";s:3:"265";s:3:"niy";s:3:"266";s:3:"r s";s:3:"267";s:3:"bat";s:3:"268";s:3:"dar";s:3:"269";s:3:"gan";s:3:"270";s:3:"i t";s:3:"271";s:3:"nta";s:3:"272";s:3:"oki";s:3:"273";s:3:"omi";s:3:"274";s:3:"sal";s:3:"275";s:3:"a l";s:3:"276";s:3:"kac";s:3:"277";s:3:"lla";s:3:"278";s:3:"wad";s:3:"279";s:3:"war";s:3:"280";s:3:"amm";s:3:"281";s:3:"dom";s:3:"282";s:3:"r m";s:3:"283";s:3:"ras";s:3:"284";s:3:"sai";s:3:"285";s:3:" lo";s:3:"286";s:3:"ats";s:3:"287";s:3:"hal";s:3:"288";s:3:"kat";s:3:"289";s:3:"li ";s:3:"290";s:3:"lok";s:3:"291";s:3:"n c";s:3:"292";s:3:"nar";s:3:"293";s:3:"tin";s:3:"294";s:3:"afa";s:3:"295";s:3:"bub";s:3:"296";s:3:"i g";s:3:"297";s:3:"isa";s:3:"298";s:3:"mak";s:3:"299";}s:8:"hawaiian";a:300:{s:3:" ka";s:1:"0";s:3:"na ";s:1:"1";s:3:" o ";s:1:"2";s:3:"ka ";s:1:"3";s:3:" ma";s:1:"4";s:3:" a ";s:1:"5";s:3:" la";s:1:"6";s:3:"a i";s:1:"7";s:3:"a m";s:1:"8";s:3:" i ";s:1:"9";s:3:"la ";s:2:"10";s:3:"ana";s:2:"11";s:3:"ai ";s:2:"12";s:3:"ia ";s:2:"13";s:3:"a o";s:2:"14";s:3:"a k";s:2:"15";s:3:"a h";s:2:"16";s:3:"o k";s:2:"17";s:3:" ke";s:2:"18";s:3:"a a";s:2:"19";s:3:"i k";s:2:"20";s:3:" ho";s:2:"21";s:3:" ia";s:2:"22";s:3:"ua ";s:2:"23";s:3:" na";s:2:"24";s:3:" me";s:2:"25";s:3:"e k";s:2:"26";s:3:"e a";s:2:"27";s:3:"au ";s:2:"28";s:3:"ke ";s:2:"29";s:3:"ma ";s:2:"30";s:3:"mai";s:2:"31";s:3:"aku";s:2:"32";s:3:" ak";s:2:"33";s:3:"ahi";s:2:"34";s:3:" ha";s:2:"35";s:3:" ko";s:2:"36";s:3:" e ";s:2:"37";s:3:"a l";s:2:"38";s:3:" no";s:2:"39";s:3:"me ";s:2:"40";s:3:"ku ";s:2:"41";s:3:"aka";s:2:"42";s:3:"kan";s:2:"43";s:3:"no ";s:2:"44";s:3:"i a";s:2:"45";s:3:"ho ";s:2:"46";s:3:"ou ";s:2:"47";s:3:" ai";s:2:"48";s:3:"i o";s:2:"49";s:3:"a p";s:2:"50";s:3:"o l";s:2:"51";s:3:"o a";s:2:"52";s:3:"ama";s:2:"53";s:3:"a n";s:2:"54";s:3:" an";s:2:"55";s:3:"i m";s:2:"56";s:3:"han";s:2:"57";s:3:"i i";s:2:"58";s:3:"iho";s:2:"59";s:3:"kou";s:2:"60";s:3:"ne ";s:2:"61";s:3:" ih";s:2:"62";s:3:"o i";s:2:"63";s:3:"iki";s:2:"64";s:3:"ona";s:2:"65";s:3:"hoo";s:2:"66";s:3:"le ";s:2:"67";s:3:"e h";s:2:"68";s:3:" he";s:2:"69";s:3:"ina";s:2:"70";s:3:" wa";s:2:"71";s:3:"ea ";s:2:"72";s:3:"ako";s:2:"73";s:3:"u i";s:2:"74";s:3:"kah";s:2:"75";s:3:"oe ";s:2:"76";s:3:"i l";s:2:"77";s:3:"u a";s:2:"78";s:3:" pa";s:2:"79";s:3:"hoi";s:2:"80";s:3:"e i";s:2:"81";s:3:"era";s:2:"82";s:3:"ko ";s:2:"83";s:3:"u m";s:2:"84";s:3:"kua";s:2:"85";s:3:"mak";s:2:"86";s:3:"oi ";s:2:"87";s:3:"kai";s:2:"88";s:3:"i n";s:2:"89";s:3:"a e";s:2:"90";s:3:"hin";s:2:"91";s:3:"ane";s:2:"92";s:3:" ol";s:2:"93";s:3:"i h";s:2:"94";s:3:"mea";s:2:"95";s:3:"wah";s:2:"96";s:3:"lak";s:2:"97";s:3:"e m";s:2:"98";s:3:"o n";s:2:"99";s:3:"u l";s:3:"100";s:3:"ika";s:3:"101";s:3:"ki ";s:3:"102";s:3:"a w";s:3:"103";s:3:"mal";s:3:"104";s:3:"hi ";s:3:"105";s:3:"e n";s:3:"106";s:3:"u o";s:3:"107";s:3:"hik";s:3:"108";s:3:" ku";s:3:"109";s:3:"e l";s:3:"110";s:3:"ele";s:3:"111";s:3:"ra ";s:3:"112";s:3:"ber";s:3:"113";s:3:"ine";s:3:"114";s:3:"abe";s:3:"115";s:3:"ain";s:3:"116";s:3:"ala";s:3:"117";s:3:"lo ";s:3:"118";s:3:" po";s:3:"119";s:3:"kon";s:3:"120";s:3:" ab";s:3:"121";s:3:"ole";s:3:"122";s:3:"he ";s:3:"123";s:3:"pau";s:3:"124";s:3:"mah";s:3:"125";s:3:"va ";s:3:"126";s:3:"ela";s:3:"127";s:3:"kau";s:3:"128";s:3:"nak";s:3:"129";s:3:" oe";s:3:"130";s:3:"kei";s:3:"131";s:3:"oia";s:3:"132";s:3:" ie";s:3:"133";s:3:"ram";s:3:"134";s:3:" oi";s:3:"135";s:3:"oa ";s:3:"136";s:3:"eho";s:3:"137";s:3:"hov";s:3:"138";s:3:"ieh";s:3:"139";s:3:"ova";s:3:"140";s:3:" ua";s:3:"141";s:3:"una";s:3:"142";s:3:"ara";s:3:"143";s:3:"o s";s:3:"144";s:3:"awa";s:3:"145";s:3:"o o";s:3:"146";s:3:"nau";s:3:"147";s:3:"u n";s:3:"148";s:3:"wa ";s:3:"149";s:3:"wai";s:3:"150";s:3:"hel";s:3:"151";s:3:" ae";s:3:"152";s:3:" al";s:3:"153";s:3:"ae ";s:3:"154";s:3:"ta ";s:3:"155";s:3:"aik";s:3:"156";s:3:" hi";s:3:"157";s:3:"ale";s:3:"158";s:3:"ila";s:3:"159";s:3:"lel";s:3:"160";s:3:"ali";s:3:"161";s:3:"eik";s:3:"162";s:3:"olo";s:3:"163";s:3:"onu";s:3:"164";s:3:" lo";s:3:"165";s:3:"aua";s:3:"166";s:3:"e o";s:3:"167";s:3:"ola";s:3:"168";s:3:"hon";s:3:"169";s:3:"mam";s:3:"170";s:3:"nan";s:3:"171";s:3:" au";s:3:"172";s:3:"aha";s:3:"173";s:3:"lau";s:3:"174";s:3:"nua";s:3:"175";s:3:"oho";s:3:"176";s:3:"oma";s:3:"177";s:3:" ao";s:3:"178";s:3:"ii ";s:3:"179";s:3:"alu";s:3:"180";s:3:"ima";s:3:"181";s:3:"mau";s:3:"182";s:3:"ike";s:3:"183";s:3:"apa";s:3:"184";s:3:"elo";s:3:"185";s:3:"lii";s:3:"186";s:3:"poe";s:3:"187";s:3:"aia";s:3:"188";s:3:"noa";s:3:"189";s:3:" in";s:3:"190";s:3:"o m";s:3:"191";s:3:"oka";s:3:"192";s:3:"'u ";s:3:"193";s:3:"aho";s:3:"194";s:3:"ei ";s:3:"195";s:3:"eka";s:3:"196";s:3:"ha ";s:3:"197";s:3:"lu ";s:3:"198";s:3:"nei";s:3:"199";s:3:"hol";s:3:"200";s:3:"ino";s:3:"201";s:3:"o e";s:3:"202";s:3:"ema";s:3:"203";s:3:"iwa";s:3:"204";s:3:"olu";s:3:"205";s:3:"ada";s:3:"206";s:3:"naa";s:3:"207";s:3:"pa ";s:3:"208";s:3:"u k";s:3:"209";s:3:"ewa";s:3:"210";s:3:"hua";s:3:"211";s:3:"lam";s:3:"212";s:3:"lua";s:3:"213";s:3:"o h";s:3:"214";s:3:"ook";s:3:"215";s:3:"u h";s:3:"216";s:3:" li";s:3:"217";s:3:"ahu";s:3:"218";s:3:"amu";s:3:"219";s:3:"ui ";s:3:"220";s:3:" il";s:3:"221";s:3:" mo";s:3:"222";s:3:" se";s:3:"223";s:3:"eia";s:3:"224";s:3:"law";s:3:"225";s:3:" hu";s:3:"226";s:3:" ik";s:3:"227";s:3:"ail";s:3:"228";s:3:"e p";s:3:"229";s:3:"li ";s:3:"230";s:3:"lun";s:3:"231";s:3:"uli";s:3:"232";s:3:"io ";s:3:"233";s:3:"kik";s:3:"234";s:3:"noh";s:3:"235";s:3:"u e";s:3:"236";s:3:" sa";s:3:"237";s:3:"aaw";s:3:"238";s:3:"awe";s:3:"239";s:3:"ena";s:3:"240";s:3:"hal";s:3:"241";s:3:"kol";s:3:"242";s:3:"lan";s:3:"243";s:3:" le";s:3:"244";s:3:" ne";s:3:"245";s:3:"a'u";s:3:"246";s:3:"ilo";s:3:"247";s:3:"kap";s:3:"248";s:3:"oko";s:3:"249";s:3:"sa ";s:3:"250";s:3:" pe";s:3:"251";s:3:"hop";s:3:"252";s:3:"loa";s:3:"253";s:3:"ope";s:3:"254";s:3:"pe ";s:3:"255";s:3:" ad";s:3:"256";s:3:" pu";s:3:"257";s:3:"ahe";s:3:"258";s:3:"aol";s:3:"259";s:3:"ia'";s:3:"260";s:3:"lai";s:3:"261";s:3:"loh";s:3:"262";s:3:"na'";s:3:"263";s:3:"oom";s:3:"264";s:3:"aau";s:3:"265";s:3:"eri";s:3:"266";s:3:"kul";s:3:"267";s:3:"we ";s:3:"268";s:3:"ake";s:3:"269";s:3:"kek";s:3:"270";s:3:"laa";s:3:"271";s:3:"ri ";s:3:"272";s:3:"iku";s:3:"273";s:3:"kak";s:3:"274";s:3:"lim";s:3:"275";s:3:"nah";s:3:"276";s:3:"ner";s:3:"277";s:3:"nui";s:3:"278";s:3:"ono";s:3:"279";s:3:"a u";s:3:"280";s:3:"dam";s:3:"281";s:3:"kum";s:3:"282";s:3:"lok";s:3:"283";s:3:"mua";s:3:"284";s:3:"uma";s:3:"285";s:3:"wal";s:3:"286";s:3:"wi ";s:3:"287";s:3:"'i ";s:3:"288";s:3:"a'i";s:3:"289";s:3:"aan";s:3:"290";s:3:"alo";s:3:"291";s:3:"eta";s:3:"292";s:3:"mu ";s:3:"293";s:3:"ohe";s:3:"294";s:3:"u p";s:3:"295";s:3:"ula";s:3:"296";s:3:"uwa";s:3:"297";s:3:" nu";s:3:"298";s:3:"amo";s:3:"299";}s:5:"hindi";a:300:{s:7:"ें ";s:1:"0";s:7:" है";s:1:"1";s:9:"में";s:1:"2";s:7:" मे";s:1:"3";s:7:"ने ";s:1:"4";s:7:"की ";s:1:"5";s:7:"के ";s:1:"6";s:7:"है ";s:1:"7";s:7:" के";s:1:"8";s:7:" की";s:1:"9";s:7:" को";s:2:"10";s:7:"ों ";s:2:"11";s:7:"को ";s:2:"12";s:7:"ा ह";s:2:"13";s:7:" का";s:2:"14";s:7:"से ";s:2:"15";s:7:"ा क";s:2:"16";s:7:"े क";s:2:"17";s:7:"ं क";s:2:"18";s:7:"या ";s:2:"19";s:7:" कि";s:2:"20";s:7:" से";s:2:"21";s:7:"का ";s:2:"22";s:7:"ी क";s:2:"23";s:7:" ने";s:2:"24";s:7:" और";s:2:"25";s:7:"और ";s:2:"26";s:7:"ना ";s:2:"27";s:7:"कि ";s:2:"28";s:7:"भी ";s:2:"29";s:7:"ी स";s:2:"30";s:7:" जा";s:2:"31";s:7:" पर";s:2:"32";s:7:"ार ";s:2:"33";s:7:" कर";s:2:"34";s:7:"ी ह";s:2:"35";s:7:" हो";s:2:"36";s:7:"ही ";s:2:"37";s:9:"िया";s:2:"38";s:7:" इस";s:2:"39";s:7:" रह";s:2:"40";s:7:"र क";s:2:"41";s:9:"ुना";s:2:"42";s:7:"ता ";s:2:"43";s:7:"ान ";s:2:"44";s:7:"े स";s:2:"45";s:7:" भी";s:2:"46";s:7:" रा";s:2:"47";s:7:"े ह";s:2:"48";s:7:" चु";s:2:"49";s:7:" पा";s:2:"50";s:7:"पर ";s:2:"51";s:9:"चुन";s:2:"52";s:9:"नाव";s:2:"53";s:7:" कह";s:2:"54";s:9:"प्र";s:2:"55";s:7:" भा";s:2:"56";s:9:"राज";s:2:"57";s:9:"हैं";s:2:"58";s:7:"ा स";s:2:"59";s:7:"ै क";s:2:"60";s:7:"ैं ";s:2:"61";s:7:"नी ";s:2:"62";s:7:"ल क";s:2:"63";s:7:"ीं ";s:2:"64";s:7:"़ी ";s:2:"65";s:7:"था ";s:2:"66";s:7:"री ";s:2:"67";s:7:"ाव ";s:2:"68";s:7:"े ब";s:2:"69";s:7:" प्";s:2:"70";s:9:"क्ष";s:2:"71";s:7:"पा ";s:2:"72";s:7:"ले ";s:2:"73";s:7:" दे";s:2:"74";s:7:"ला ";s:2:"75";s:7:"हा ";s:2:"76";s:9:"ाजप";s:2:"77";s:7:" था";s:2:"78";s:7:" नह";s:2:"79";s:7:"इस ";s:2:"80";s:7:"कर ";s:2:"81";s:9:"जपा";s:2:"82";s:9:"नही";s:2:"83";s:9:"भाज";s:2:"84";s:9:"यों";s:2:"85";s:7:"र स";s:2:"86";s:9:"हीं";s:2:"87";s:7:" अम";s:2:"88";s:7:" बा";s:2:"89";s:7:" मा";s:2:"90";s:7:" वि";s:2:"91";s:9:"रीक";s:2:"92";s:7:"िए ";s:2:"93";s:7:"े प";s:2:"94";s:9:"्या";s:2:"95";s:7:" ही";s:2:"96";s:7:"ं म";s:2:"97";s:9:"कार";s:2:"98";s:7:"ा ज";s:2:"99";s:7:"े ल";s:3:"100";s:7:" ता";s:3:"101";s:7:" दि";s:3:"102";s:7:" सा";s:3:"103";s:7:" हम";s:3:"104";s:7:"ा न";s:3:"105";s:7:"ा म";s:3:"106";s:9:"ाक़";s:3:"107";s:9:"्ता";s:3:"108";s:7:" एक";s:3:"109";s:7:" सं";s:3:"110";s:7:" स्";s:3:"111";s:9:"अमर";s:3:"112";s:9:"क़ी";s:3:"113";s:9:"ताज";s:3:"114";s:9:"मरी";s:3:"115";s:9:"स्थ";s:3:"116";s:7:"ा थ";s:3:"117";s:9:"ार्";s:3:"118";s:7:" हु";s:3:"119";s:9:"इरा";s:3:"120";s:7:"एक ";s:3:"121";s:7:"न क";s:3:"122";s:7:"र म";s:3:"123";s:9:"राक";s:3:"124";s:7:"ी ज";s:3:"125";s:7:"ी न";s:3:"126";s:7:" इर";s:3:"127";s:7:" उन";s:3:"128";s:7:" पह";s:3:"129";s:9:"कहा";s:3:"130";s:7:"ते ";s:3:"131";s:7:"े अ";s:3:"132";s:7:" तो";s:3:"133";s:7:" सु";s:3:"134";s:7:"ति ";s:3:"135";s:7:"ती ";s:3:"136";s:7:"तो ";s:3:"137";s:9:"मिल";s:3:"138";s:7:"िक ";s:3:"139";s:9:"ियो";s:3:"140";s:9:"्रे";s:3:"141";s:7:" अप";s:3:"142";s:7:" फ़";s:3:"143";s:7:" लि";s:3:"144";s:7:" लो";s:3:"145";s:7:" सम";s:3:"146";s:7:"म क";s:3:"147";s:9:"र्ट";s:3:"148";s:7:"हो ";s:3:"149";s:7:"ा च";s:3:"150";s:7:"ाई ";s:3:"151";s:9:"ाने";s:3:"152";s:7:"िन ";s:3:"153";s:7:"्य ";s:3:"154";s:7:" उस";s:3:"155";s:7:" क़";s:3:"156";s:7:" सक";s:3:"157";s:7:" सै";s:3:"158";s:7:"ं प";s:3:"159";s:7:"ं ह";s:3:"160";s:7:"गी ";s:3:"161";s:7:"त क";s:3:"162";s:9:"मान";s:3:"163";s:7:"र न";s:3:"164";s:9:"ष्ट";s:3:"165";s:7:"स क";s:3:"166";s:9:"स्त";s:3:"167";s:7:"ाँ ";s:3:"168";s:7:"ी ब";s:3:"169";s:7:"ी म";s:3:"170";s:9:"्री";s:3:"171";s:7:" दो";s:3:"172";s:7:" मि";s:3:"173";s:7:" मु";s:3:"174";s:7:" ले";s:3:"175";s:7:" शा";s:3:"176";s:7:"ं स";s:3:"177";s:9:"ज़ा";s:3:"178";s:9:"त्र";s:3:"179";s:7:"थी ";s:3:"180";s:9:"लिए";s:3:"181";s:7:"सी ";s:3:"182";s:7:"़ा ";s:3:"183";s:9:"़ार";s:3:"184";s:9:"ांग";s:3:"185";s:7:"े द";s:3:"186";s:7:"े म";s:3:"187";s:7:"्व ";s:3:"188";s:7:" ना";s:3:"189";s:7:" बन";s:3:"190";s:9:"ंग्";s:3:"191";s:9:"कां";s:3:"192";s:7:"गा ";s:3:"193";s:9:"ग्र";s:3:"194";s:7:"जा ";s:3:"195";s:9:"ज्य";s:3:"196";s:7:"दी ";s:3:"197";s:7:"न म";s:3:"198";s:9:"पार";s:3:"199";s:7:"भा ";s:3:"200";s:9:"रही";s:3:"201";s:7:"रे ";s:3:"202";s:9:"रेस";s:3:"203";s:7:"ली ";s:3:"204";s:9:"सभा";s:3:"205";s:7:"ा र";s:3:"206";s:7:"ाल ";s:3:"207";s:7:"ी अ";s:3:"208";s:9:"ीकी";s:3:"209";s:7:"े त";s:3:"210";s:7:"ेश ";s:3:"211";s:7:" अं";s:3:"212";s:7:" तक";s:3:"213";s:7:" या";s:3:"214";s:7:"ई ह";s:3:"215";s:9:"करन";s:3:"216";s:7:"तक ";s:3:"217";s:9:"देश";s:3:"218";s:9:"वर्";s:3:"219";s:9:"ाया";s:3:"220";s:7:"ी भ";s:3:"221";s:7:"ेस ";s:3:"222";s:7:"्ष ";s:3:"223";s:7:" गय";s:3:"224";s:7:" जि";s:3:"225";s:7:" थी";s:3:"226";s:7:" बड";s:3:"227";s:7:" यह";s:3:"228";s:7:" वा";s:3:"229";s:9:"ंतर";s:3:"230";s:9:"अंत";s:3:"231";s:7:"क़ ";s:3:"232";s:9:"गया";s:3:"233";s:7:"टी ";s:3:"234";s:9:"निक";s:3:"235";s:9:"न्ह";s:3:"236";s:9:"पहल";s:3:"237";s:9:"बड़";s:3:"238";s:9:"मार";s:3:"239";s:7:"र प";s:3:"240";s:9:"रने";s:3:"241";s:9:"ाज़";s:3:"242";s:7:"ि इ";s:3:"243";s:7:"ी र";s:3:"244";s:7:"े ज";s:3:"245";s:7:"े व";s:3:"246";s:7:"्ट ";s:3:"247";s:9:"्टी";s:3:"248";s:7:" अब";s:3:"249";s:7:" लग";s:3:"250";s:7:" वर";s:3:"251";s:7:" सी";s:3:"252";s:7:"ं भ";s:3:"253";s:9:"उन्";s:3:"254";s:7:"क क";s:3:"255";s:9:"किय";s:3:"256";s:9:"देख";s:3:"257";s:9:"पूर";s:3:"258";s:9:"फ़्";s:3:"259";s:7:"यह ";s:3:"260";s:9:"यान";s:3:"261";s:9:"रिक";s:3:"262";s:9:"रिय";s:3:"263";s:9:"र्ड";s:3:"264";s:9:"लेक";s:3:"265";s:9:"सकत";s:3:"266";s:9:"हों";s:3:"267";s:9:"होग";s:3:"268";s:7:"ा अ";s:3:"269";s:7:"ा द";s:3:"270";s:7:"ा प";s:3:"271";s:7:"ाद ";s:3:"272";s:9:"ारा";s:3:"273";s:7:"ित ";s:3:"274";s:7:"ी त";s:3:"275";s:7:"ी प";s:3:"276";s:7:"ो क";s:3:"277";s:7:"ो द";s:3:"278";s:7:" ते";s:3:"279";s:7:" नि";s:3:"280";s:7:" सर";s:3:"281";s:7:" हा";s:3:"282";s:7:"ं द";s:3:"283";s:9:"अपन";s:3:"284";s:9:"जान";s:3:"285";s:7:"त म";s:3:"286";s:9:"थित";s:3:"287";s:9:"पनी";s:3:"288";s:9:"महल";s:3:"289";s:7:"र ह";s:3:"290";s:9:"लोग";s:3:"291";s:7:"व क";s:3:"292";s:9:"हना";s:3:"293";s:7:"हल ";s:3:"294";s:9:"हाँ";s:3:"295";s:9:"ाज्";s:3:"296";s:9:"ाना";s:3:"297";s:9:"िक्";s:3:"298";s:9:"िस्";s:3:"299";}s:9:"hungarian";a:300:{s:3:" a ";s:1:"0";s:3:" az";s:1:"1";s:3:" sz";s:1:"2";s:3:"az ";s:1:"3";s:3:" me";s:1:"4";s:3:"en ";s:1:"5";s:3:" el";s:1:"6";s:3:" ho";s:1:"7";s:3:"ek ";s:1:"8";s:3:"gy ";s:1:"9";s:3:"tt ";s:2:"10";s:3:"ett";s:2:"11";s:3:"sze";s:2:"12";s:3:" fe";s:2:"13";s:4:"és ";s:2:"14";s:3:" ki";s:2:"15";s:3:"tet";s:2:"16";s:3:" be";s:2:"17";s:3:"et ";s:2:"18";s:3:"ter";s:2:"19";s:4:" kö";s:2:"20";s:4:" és";s:2:"21";s:3:"hog";s:2:"22";s:3:"meg";s:2:"23";s:3:"ogy";s:2:"24";s:3:"szt";s:2:"25";s:3:"te ";s:2:"26";s:3:"t a";s:2:"27";s:3:"zet";s:2:"28";s:3:"a m";s:2:"29";s:3:"nek";s:2:"30";s:3:"nt ";s:2:"31";s:4:"ség";s:2:"32";s:4:"szá";s:2:"33";s:3:"ak ";s:2:"34";s:3:" va";s:2:"35";s:3:"an ";s:2:"36";s:3:"eze";s:2:"37";s:3:"ra ";s:2:"38";s:3:"ta ";s:2:"39";s:3:" mi";s:2:"40";s:3:"int";s:2:"41";s:4:"köz";s:2:"42";s:3:" is";s:2:"43";s:3:"esz";s:2:"44";s:3:"fel";s:2:"45";s:3:"min";s:2:"46";s:3:"nak";s:2:"47";s:3:"ors";s:2:"48";s:3:"zer";s:2:"49";s:3:" te";s:2:"50";s:3:"a a";s:2:"51";s:3:"a k";s:2:"52";s:3:"is ";s:2:"53";s:3:" cs";s:2:"54";s:3:"ele";s:2:"55";s:3:"er ";s:2:"56";s:3:"men";s:2:"57";s:3:"si ";s:2:"58";s:3:"tek";s:2:"59";s:3:"ti ";s:2:"60";s:3:" ne";s:2:"61";s:3:"csa";s:2:"62";s:3:"ent";s:2:"63";s:3:"z e";s:2:"64";s:3:"a t";s:2:"65";s:3:"ala";s:2:"66";s:3:"ere";s:2:"67";s:3:"es ";s:2:"68";s:3:"lom";s:2:"69";s:3:"lte";s:2:"70";s:3:"mon";s:2:"71";s:3:"ond";s:2:"72";s:3:"rsz";s:2:"73";s:3:"sza";s:2:"74";s:3:"tte";s:2:"75";s:4:"zág";s:2:"76";s:4:"ány";s:2:"77";s:3:" fo";s:2:"78";s:3:" ma";s:2:"79";s:3:"ai ";s:2:"80";s:3:"ben";s:2:"81";s:3:"el ";s:2:"82";s:3:"ene";s:2:"83";s:3:"ik ";s:2:"84";s:3:"jel";s:2:"85";s:4:"tás";s:2:"86";s:4:"áll";s:2:"87";s:3:" ha";s:2:"88";s:3:" le";s:2:"89";s:4:" ál";s:2:"90";s:3:"agy";s:2:"91";s:4:"alá";s:2:"92";s:3:"isz";s:2:"93";s:3:"y a";s:2:"94";s:3:"zte";s:2:"95";s:4:"ás ";s:2:"96";s:3:" al";s:2:"97";s:3:"e a";s:2:"98";s:3:"egy";s:2:"99";s:3:"ely";s:3:"100";s:3:"for";s:3:"101";s:3:"lat";s:3:"102";s:3:"lt ";s:3:"103";s:3:"n a";s:3:"104";s:3:"oga";s:3:"105";s:3:"on ";s:3:"106";s:3:"re ";s:3:"107";s:3:"st ";s:3:"108";s:4:"ság";s:3:"109";s:3:"t m";s:3:"110";s:4:"án ";s:3:"111";s:4:"ét ";s:3:"112";s:4:"ült";s:3:"113";s:3:" je";s:3:"114";s:3:"gi ";s:3:"115";s:3:"k a";s:3:"116";s:4:"kül";s:3:"117";s:3:"lam";s:3:"118";s:3:"len";s:3:"119";s:4:"lás";s:3:"120";s:4:"más";s:3:"121";s:3:"s k";s:3:"122";s:3:"vez";s:3:"123";s:4:"áso";s:3:"124";s:5:"özö";s:3:"125";s:3:" ta";s:3:"126";s:3:"a s";s:3:"127";s:3:"a v";s:3:"128";s:3:"asz";s:3:"129";s:4:"atá";s:3:"130";s:4:"ető";s:3:"131";s:3:"kez";s:3:"132";s:3:"let";s:3:"133";s:3:"mag";s:3:"134";s:3:"nem";s:3:"135";s:4:"szé";s:3:"136";s:3:"z m";s:3:"137";s:4:"át ";s:3:"138";s:4:"éte";s:3:"139";s:4:"ölt";s:3:"140";s:3:" de";s:3:"141";s:3:" gy";s:3:"142";s:4:" ké";s:3:"143";s:3:" mo";s:3:"144";s:4:" vá";s:3:"145";s:4:" ér";s:3:"146";s:3:"a b";s:3:"147";s:3:"a f";s:3:"148";s:3:"ami";s:3:"149";s:3:"at ";s:3:"150";s:3:"ato";s:3:"151";s:3:"att";s:3:"152";s:3:"bef";s:3:"153";s:3:"dta";s:3:"154";s:3:"gya";s:3:"155";s:3:"hat";s:3:"156";s:3:"i s";s:3:"157";s:3:"las";s:3:"158";s:3:"ndt";s:3:"159";s:3:"rt ";s:3:"160";s:3:"szo";s:3:"161";s:3:"t k";s:3:"162";s:4:"tár";s:3:"163";s:4:"tés";s:3:"164";s:3:"van";s:3:"165";s:5:"ásá";s:3:"166";s:4:"ól ";s:3:"167";s:4:" bé";s:3:"168";s:3:" eg";s:3:"169";s:3:" or";s:3:"170";s:4:" pá";s:3:"171";s:4:" pé";s:3:"172";s:3:" ve";s:3:"173";s:3:"ban";s:3:"174";s:3:"eke";s:3:"175";s:4:"ekü";s:3:"176";s:4:"elő";s:3:"177";s:3:"erv";s:3:"178";s:3:"ete";s:3:"179";s:3:"fog";s:3:"180";s:3:"i a";s:3:"181";s:3:"kis";s:3:"182";s:4:"lád";s:3:"183";s:3:"nte";s:3:"184";s:3:"nye";s:3:"185";s:3:"nyi";s:3:"186";s:3:"ok ";s:3:"187";s:4:"omá";s:3:"188";s:3:"os ";s:3:"189";s:4:"rán";s:3:"190";s:4:"rás";s:3:"191";s:3:"sal";s:3:"192";s:3:"t e";s:3:"193";s:4:"vál";s:3:"194";s:3:"yar";s:3:"195";s:4:"ágo";s:3:"196";s:4:"ála";s:3:"197";s:4:"ége";s:3:"198";s:4:"ény";s:3:"199";s:4:"ött";s:3:"200";s:4:" tá";s:3:"201";s:4:"adó";s:3:"202";s:3:"elh";s:3:"203";s:3:"fej";s:3:"204";s:3:"het";s:3:"205";s:3:"hoz";s:3:"206";s:3:"ill";s:3:"207";s:4:"jár";s:3:"208";s:4:"kés";s:3:"209";s:3:"llo";s:3:"210";s:3:"mi ";s:3:"211";s:3:"ny ";s:3:"212";s:3:"ont";s:3:"213";s:3:"ren";s:3:"214";s:3:"res";s:3:"215";s:3:"rin";s:3:"216";s:3:"s a";s:3:"217";s:3:"s e";s:3:"218";s:3:"ssz";s:3:"219";s:3:"zt ";s:3:"220";s:3:" ez";s:3:"221";s:3:" ka";s:3:"222";s:3:" ke";s:3:"223";s:3:" ko";s:3:"224";s:3:" re";s:3:"225";s:3:"a h";s:3:"226";s:3:"a n";s:3:"227";s:3:"den";s:3:"228";s:4:"dó ";s:3:"229";s:3:"efo";s:3:"230";s:3:"gad";s:3:"231";s:3:"gat";s:3:"232";s:3:"gye";s:3:"233";s:3:"hel";s:3:"234";s:3:"k e";s:3:"235";s:3:"ket";s:3:"236";s:3:"les";s:3:"237";s:4:"mán";s:3:"238";s:3:"nde";s:3:"239";s:3:"nis";s:3:"240";s:3:"ozz";s:3:"241";s:3:"t b";s:3:"242";s:3:"t i";s:3:"243";s:4:"t é";s:3:"244";s:3:"tat";s:3:"245";s:3:"tos";s:3:"246";s:3:"val";s:3:"247";s:3:"z o";s:3:"248";s:3:"zak";s:3:"249";s:4:"ád ";s:3:"250";s:4:"ály";s:3:"251";s:4:"ára";s:3:"252";s:4:"ési";s:3:"253";s:4:"ész";s:3:"254";s:3:" ak";s:3:"255";s:3:" am";s:3:"256";s:3:" es";s:3:"257";s:4:" há";s:3:"258";s:3:" ny";s:3:"259";s:4:" tö";s:3:"260";s:3:"aka";s:3:"261";s:3:"art";s:3:"262";s:4:"ató";s:3:"263";s:3:"azt";s:3:"264";s:3:"bbe";s:3:"265";s:3:"ber";s:3:"266";s:4:"ció";s:3:"267";s:3:"cso";s:3:"268";s:3:"em ";s:3:"269";s:3:"eti";s:3:"270";s:4:"eté";s:3:"271";s:3:"gal";s:3:"272";s:3:"i t";s:3:"273";s:3:"ini";s:3:"274";s:3:"ist";s:3:"275";s:3:"ja ";s:3:"276";s:3:"ker";s:3:"277";s:3:"ki ";s:3:"278";s:3:"kor";s:3:"279";s:3:"koz";s:3:"280";s:4:"l é";s:3:"281";s:4:"ljá";s:3:"282";s:3:"lye";s:3:"283";s:3:"n v";s:3:"284";s:3:"ni ";s:3:"285";s:4:"pál";s:3:"286";s:3:"ror";s:3:"287";s:4:"ról";s:3:"288";s:4:"rül";s:3:"289";s:3:"s c";s:3:"290";s:3:"s p";s:3:"291";s:3:"s s";s:3:"292";s:3:"s v";s:3:"293";s:3:"sok";s:3:"294";s:3:"t j";s:3:"295";s:3:"t t";s:3:"296";s:3:"tar";s:3:"297";s:3:"tel";s:3:"298";s:3:"vat";s:3:"299";}s:9:"icelandic";a:300:{s:4:"að ";s:1:"0";s:3:"um ";s:1:"1";s:4:" að";s:1:"2";s:3:"ir ";s:1:"3";s:4:"ið ";s:1:"4";s:3:"ur ";s:1:"5";s:3:" ve";s:1:"6";s:4:" í ";s:1:"7";s:3:"na ";s:1:"8";s:4:" á ";s:1:"9";s:3:" se";s:2:"10";s:3:" er";s:2:"11";s:3:" og";s:2:"12";s:3:"ar ";s:2:"13";s:3:"og ";s:2:"14";s:3:"ver";s:2:"15";s:3:" mi";s:2:"16";s:3:"inn";s:2:"17";s:3:"nn ";s:2:"18";s:3:" fy";s:2:"19";s:3:"er ";s:2:"20";s:3:"fyr";s:2:"21";s:3:" ek";s:2:"22";s:3:" en";s:2:"23";s:3:" ha";s:2:"24";s:3:" he";s:2:"25";s:3:"ekk";s:2:"26";s:3:" st";s:2:"27";s:3:"ki ";s:2:"28";s:3:"st ";s:2:"29";s:4:"ði ";s:2:"30";s:3:" ba";s:2:"31";s:3:" me";s:2:"32";s:3:" vi";s:2:"33";s:3:"ig ";s:2:"34";s:3:"rir";s:2:"35";s:3:"yri";s:2:"36";s:3:" um";s:2:"37";s:3:"g f";s:2:"38";s:3:"leg";s:2:"39";s:3:"lei";s:2:"40";s:3:"ns ";s:2:"41";s:4:"ð s";s:2:"42";s:3:" ei";s:2:"43";s:4:" þa";s:2:"44";s:3:"in ";s:2:"45";s:3:"kki";s:2:"46";s:3:"r h";s:2:"47";s:3:"r s";s:2:"48";s:3:"egi";s:2:"49";s:3:"ein";s:2:"50";s:3:"ga ";s:2:"51";s:3:"ing";s:2:"52";s:3:"ra ";s:2:"53";s:3:"sta";s:2:"54";s:3:" va";s:2:"55";s:4:" þe";s:2:"56";s:3:"ann";s:2:"57";s:3:"en ";s:2:"58";s:3:"mil";s:2:"59";s:3:"sem";s:2:"60";s:4:"tjó";s:2:"61";s:4:"arð";s:2:"62";s:3:"di ";s:2:"63";s:3:"eit";s:2:"64";s:3:"haf";s:2:"65";s:3:"ill";s:2:"66";s:3:"ins";s:2:"67";s:3:"ist";s:2:"68";s:3:"llj";s:2:"69";s:3:"ndi";s:2:"70";s:3:"r a";s:2:"71";s:3:"r e";s:2:"72";s:3:"seg";s:2:"73";s:3:"un ";s:2:"74";s:3:"var";s:2:"75";s:3:" bi";s:2:"76";s:3:" el";s:2:"77";s:3:" fo";s:2:"78";s:3:" ge";s:2:"79";s:3:" yf";s:2:"80";s:3:"and";s:2:"81";s:3:"aug";s:2:"82";s:3:"bau";s:2:"83";s:3:"big";s:2:"84";s:3:"ega";s:2:"85";s:3:"eld";s:2:"86";s:4:"erð";s:2:"87";s:3:"fir";s:2:"88";s:3:"foo";s:2:"89";s:3:"gin";s:2:"90";s:3:"itt";s:2:"91";s:3:"n s";s:2:"92";s:3:"ngi";s:2:"93";s:3:"num";s:2:"94";s:3:"od ";s:2:"95";s:3:"ood";s:2:"96";s:3:"sin";s:2:"97";s:3:"ta ";s:2:"98";s:3:"tt ";s:2:"99";s:4:"við";s:3:"100";s:3:"yfi";s:3:"101";s:4:"ð e";s:3:"102";s:4:"ð f";s:3:"103";s:3:" hr";s:3:"104";s:4:" sé";s:3:"105";s:4:" þv";s:3:"106";s:3:"a e";s:3:"107";s:4:"a á";s:3:"108";s:3:"em ";s:3:"109";s:3:"gi ";s:3:"110";s:3:"i f";s:3:"111";s:3:"jar";s:3:"112";s:4:"jór";s:3:"113";s:3:"lja";s:3:"114";s:3:"m e";s:3:"115";s:4:"r á";s:3:"116";s:3:"rei";s:3:"117";s:3:"rst";s:3:"118";s:4:"rða";s:3:"119";s:4:"rði";s:3:"120";s:4:"rðu";s:3:"121";s:3:"stj";s:3:"122";s:3:"und";s:3:"123";s:3:"veg";s:3:"124";s:4:"ví ";s:3:"125";s:4:"ð v";s:3:"126";s:5:"það";s:3:"127";s:5:"því";s:3:"128";s:3:" fj";s:3:"129";s:3:" ko";s:3:"130";s:3:" sl";s:3:"131";s:3:"eik";s:3:"132";s:3:"end";s:3:"133";s:3:"ert";s:3:"134";s:3:"ess";s:3:"135";s:4:"fjá";s:3:"136";s:3:"fur";s:3:"137";s:3:"gir";s:3:"138";s:4:"hús";s:3:"139";s:4:"jár";s:3:"140";s:3:"n e";s:3:"141";s:3:"ri ";s:3:"142";s:3:"tar";s:3:"143";s:5:"ð þ";s:3:"144";s:4:"ðar";s:3:"145";s:4:"ður";s:3:"146";s:4:"þes";s:3:"147";s:3:" br";s:3:"148";s:4:" hú";s:3:"149";s:3:" kr";s:3:"150";s:3:" le";s:3:"151";s:3:" up";s:3:"152";s:3:"a s";s:3:"153";s:3:"egg";s:3:"154";s:3:"i s";s:3:"155";s:3:"irt";s:3:"156";s:3:"ja ";s:3:"157";s:4:"kið";s:3:"158";s:3:"len";s:3:"159";s:4:"með";s:3:"160";s:3:"mik";s:3:"161";s:3:"n b";s:3:"162";s:3:"nar";s:3:"163";s:3:"nir";s:3:"164";s:3:"nun";s:3:"165";s:3:"r f";s:3:"166";s:3:"r v";s:3:"167";s:4:"rið";s:3:"168";s:3:"rt ";s:3:"169";s:3:"sti";s:3:"170";s:3:"t v";s:3:"171";s:3:"ti ";s:3:"172";s:3:"una";s:3:"173";s:3:"upp";s:3:"174";s:4:"ða ";s:3:"175";s:4:"óna";s:3:"176";s:3:" al";s:3:"177";s:3:" fr";s:3:"178";s:3:" gr";s:3:"179";s:3:"a v";s:3:"180";s:3:"all";s:3:"181";s:3:"an ";s:3:"182";s:3:"da ";s:3:"183";s:4:"eið";s:3:"184";s:4:"eð ";s:3:"185";s:3:"fa ";s:3:"186";s:3:"fra";s:3:"187";s:3:"g e";s:3:"188";s:3:"ger";s:3:"189";s:4:"gið";s:3:"190";s:3:"gt ";s:3:"191";s:3:"han";s:3:"192";s:3:"hef";s:3:"193";s:3:"hel";s:3:"194";s:3:"her";s:3:"195";s:3:"hra";s:3:"196";s:3:"i a";s:3:"197";s:3:"i e";s:3:"198";s:3:"i v";s:3:"199";s:4:"i þ";s:3:"200";s:3:"iki";s:3:"201";s:4:"jón";s:3:"202";s:4:"jör";s:3:"203";s:3:"ka ";s:3:"204";s:4:"kró";s:3:"205";s:4:"lík";s:3:"206";s:3:"m h";s:3:"207";s:3:"n a";s:3:"208";s:3:"nga";s:3:"209";s:3:"r l";s:3:"210";s:3:"ram";s:3:"211";s:3:"ru ";s:3:"212";s:5:"ráð";s:3:"213";s:4:"rón";s:3:"214";s:3:"svo";s:3:"215";s:3:"vin";s:3:"216";s:4:"í b";s:3:"217";s:4:"í h";s:3:"218";s:4:"ð h";s:3:"219";s:4:"ð k";s:3:"220";s:4:"ð m";s:3:"221";s:5:"örð";s:3:"222";s:3:" af";s:3:"223";s:3:" fa";s:3:"224";s:4:" lí";s:3:"225";s:4:" rá";s:3:"226";s:3:" sk";s:3:"227";s:3:" sv";s:3:"228";s:3:" te";s:3:"229";s:3:"a b";s:3:"230";s:3:"a f";s:3:"231";s:3:"a h";s:3:"232";s:3:"a k";s:3:"233";s:3:"a u";s:3:"234";s:3:"afi";s:3:"235";s:3:"agn";s:3:"236";s:3:"arn";s:3:"237";s:3:"ast";s:3:"238";s:3:"ber";s:3:"239";s:3:"efu";s:3:"240";s:3:"enn";s:3:"241";s:3:"erb";s:3:"242";s:3:"erg";s:3:"243";s:3:"fi ";s:3:"244";s:3:"g a";s:3:"245";s:3:"gar";s:3:"246";s:4:"iðs";s:3:"247";s:3:"ker";s:3:"248";s:3:"kke";s:3:"249";s:3:"lan";s:3:"250";s:4:"ljó";s:3:"251";s:3:"llt";s:3:"252";s:3:"ma ";s:3:"253";s:4:"mið";s:3:"254";s:3:"n v";s:3:"255";s:4:"n í";s:3:"256";s:3:"nan";s:3:"257";s:3:"nda";s:3:"258";s:3:"ndu";s:3:"259";s:4:"nið";s:3:"260";s:3:"nna";s:3:"261";s:3:"nnu";s:3:"262";s:3:"nu ";s:3:"263";s:3:"r o";s:3:"264";s:3:"rbe";s:3:"265";s:3:"rgi";s:3:"266";s:4:"slö";s:3:"267";s:4:"sé ";s:3:"268";s:3:"t a";s:3:"269";s:3:"t h";s:3:"270";s:3:"til";s:3:"271";s:3:"tin";s:3:"272";s:3:"ugu";s:3:"273";s:3:"vil";s:3:"274";s:3:"ygg";s:3:"275";s:4:"á s";s:3:"276";s:4:"ð a";s:3:"277";s:4:"ð b";s:3:"278";s:4:"órn";s:3:"279";s:4:"ögn";s:3:"280";s:4:"öku";s:3:"281";s:3:" at";s:3:"282";s:3:" fi";s:3:"283";s:4:" fé";s:3:"284";s:3:" ka";s:3:"285";s:3:" ma";s:3:"286";s:3:" no";s:3:"287";s:3:" sa";s:3:"288";s:3:" si";s:3:"289";s:3:" ti";s:3:"290";s:4:" ák";s:3:"291";s:3:"a m";s:3:"292";s:3:"a t";s:3:"293";s:4:"a í";s:3:"294";s:4:"a þ";s:3:"295";s:3:"afa";s:3:"296";s:3:"afs";s:3:"297";s:3:"ald";s:3:"298";s:3:"arf";s:3:"299";}s:10:"indonesian";a:300:{s:3:"an ";s:1:"0";s:3:" me";s:1:"1";s:3:"kan";s:1:"2";s:3:"ang";s:1:"3";s:3:"ng ";s:1:"4";s:3:" pe";s:1:"5";s:3:"men";s:1:"6";s:3:" di";s:1:"7";s:3:" ke";s:1:"8";s:3:" da";s:1:"9";s:3:" se";s:2:"10";s:3:"eng";s:2:"11";s:3:" be";s:2:"12";s:3:"nga";s:2:"13";s:3:"nya";s:2:"14";s:3:" te";s:2:"15";s:3:"ah ";s:2:"16";s:3:"ber";s:2:"17";s:3:"aka";s:2:"18";s:3:" ya";s:2:"19";s:3:"dan";s:2:"20";s:3:"di ";s:2:"21";s:3:"yan";s:2:"22";s:3:"n p";s:2:"23";s:3:"per";s:2:"24";s:3:"a m";s:2:"25";s:3:"ita";s:2:"26";s:3:" pa";s:2:"27";s:3:"da ";s:2:"28";s:3:"ata";s:2:"29";s:3:"ada";s:2:"30";s:3:"ya ";s:2:"31";s:3:"ta ";s:2:"32";s:3:" in";s:2:"33";s:3:"ala";s:2:"34";s:3:"eri";s:2:"35";s:3:"ia ";s:2:"36";s:3:"a d";s:2:"37";s:3:"n k";s:2:"38";s:3:"am ";s:2:"39";s:3:"ga ";s:2:"40";s:3:"at ";s:2:"41";s:3:"era";s:2:"42";s:3:"n d";s:2:"43";s:3:"ter";s:2:"44";s:3:" ka";s:2:"45";s:3:"a p";s:2:"46";s:3:"ari";s:2:"47";s:3:"emb";s:2:"48";s:3:"n m";s:2:"49";s:3:"ri ";s:2:"50";s:3:" ba";s:2:"51";s:3:"aan";s:2:"52";s:3:"ak ";s:2:"53";s:3:"ra ";s:2:"54";s:3:" it";s:2:"55";s:3:"ara";s:2:"56";s:3:"ela";s:2:"57";s:3:"ni ";s:2:"58";s:3:"ali";s:2:"59";s:3:"ran";s:2:"60";s:3:"ar ";s:2:"61";s:3:"eru";s:2:"62";s:3:"lah";s:2:"63";s:3:"a b";s:2:"64";s:3:"asi";s:2:"65";s:3:"awa";s:2:"66";s:3:"eba";s:2:"67";s:3:"gan";s:2:"68";s:3:"n b";s:2:"69";s:3:" ha";s:2:"70";s:3:"ini";s:2:"71";s:3:"mer";s:2:"72";s:3:" la";s:2:"73";s:3:" mi";s:2:"74";s:3:"and";s:2:"75";s:3:"ena";s:2:"76";s:3:"wan";s:2:"77";s:3:" sa";s:2:"78";s:3:"aha";s:2:"79";s:3:"lam";s:2:"80";s:3:"n i";s:2:"81";s:3:"nda";s:2:"82";s:3:" wa";s:2:"83";s:3:"a i";s:2:"84";s:3:"dua";s:2:"85";s:3:"g m";s:2:"86";s:3:"mi ";s:2:"87";s:3:"n a";s:2:"88";s:3:"rus";s:2:"89";s:3:"tel";s:2:"90";s:3:"yak";s:2:"91";s:3:" an";s:2:"92";s:3:"dal";s:2:"93";s:3:"h d";s:2:"94";s:3:"i s";s:2:"95";s:3:"ing";s:2:"96";s:3:"min";s:2:"97";s:3:"ngg";s:2:"98";s:3:"tak";s:2:"99";s:3:"ami";s:3:"100";s:3:"beb";s:3:"101";s:3:"den";s:3:"102";s:3:"gat";s:3:"103";s:3:"ian";s:3:"104";s:3:"ih ";s:3:"105";s:3:"pad";s:3:"106";s:3:"rga";s:3:"107";s:3:"san";s:3:"108";s:3:"ua ";s:3:"109";s:3:" de";s:3:"110";s:3:"a t";s:3:"111";s:3:"arg";s:3:"112";s:3:"dar";s:3:"113";s:3:"elu";s:3:"114";s:3:"har";s:3:"115";s:3:"i k";s:3:"116";s:3:"i m";s:3:"117";s:3:"i p";s:3:"118";s:3:"ika";s:3:"119";s:3:"in ";s:3:"120";s:3:"iny";s:3:"121";s:3:"itu";s:3:"122";s:3:"mba";s:3:"123";s:3:"n t";s:3:"124";s:3:"ntu";s:3:"125";s:3:"pan";s:3:"126";s:3:"pen";s:3:"127";s:3:"sah";s:3:"128";s:3:"tan";s:3:"129";s:3:"tu ";s:3:"130";s:3:"a k";s:3:"131";s:3:"ban";s:3:"132";s:3:"edu";s:3:"133";s:3:"eka";s:3:"134";s:3:"g d";s:3:"135";s:3:"ka ";s:3:"136";s:3:"ker";s:3:"137";s:3:"nde";s:3:"138";s:3:"nta";s:3:"139";s:3:"ora";s:3:"140";s:3:"usa";s:3:"141";s:3:" du";s:3:"142";s:3:" ma";s:3:"143";s:3:"a s";s:3:"144";s:3:"ai ";s:3:"145";s:3:"ant";s:3:"146";s:3:"bas";s:3:"147";s:3:"end";s:3:"148";s:3:"i d";s:3:"149";s:3:"ira";s:3:"150";s:3:"kam";s:3:"151";s:3:"lan";s:3:"152";s:3:"n s";s:3:"153";s:3:"uli";s:3:"154";s:3:"al ";s:3:"155";s:3:"apa";s:3:"156";s:3:"ere";s:3:"157";s:3:"ert";s:3:"158";s:3:"lia";s:3:"159";s:3:"mem";s:3:"160";s:3:"rka";s:3:"161";s:3:"si ";s:3:"162";s:3:"tal";s:3:"163";s:3:"ung";s:3:"164";s:3:" ak";s:3:"165";s:3:"a a";s:3:"166";s:3:"a w";s:3:"167";s:3:"ani";s:3:"168";s:3:"ask";s:3:"169";s:3:"ent";s:3:"170";s:3:"gar";s:3:"171";s:3:"haa";s:3:"172";s:3:"i i";s:3:"173";s:3:"isa";s:3:"174";s:3:"ked";s:3:"175";s:3:"mbe";s:3:"176";s:3:"ska";s:3:"177";s:3:"tor";s:3:"178";s:3:"uan";s:3:"179";s:3:"uk ";s:3:"180";s:3:"uka";s:3:"181";s:3:" ad";s:3:"182";s:3:" to";s:3:"183";s:3:"asa";s:3:"184";s:3:"aya";s:3:"185";s:3:"bag";s:3:"186";s:3:"dia";s:3:"187";s:3:"dun";s:3:"188";s:3:"erj";s:3:"189";s:3:"mas";s:3:"190";s:3:"na ";s:3:"191";s:3:"rek";s:3:"192";s:3:"rit";s:3:"193";s:3:"sih";s:3:"194";s:3:"us ";s:3:"195";s:3:" bi";s:3:"196";s:3:"a h";s:3:"197";s:3:"ama";s:3:"198";s:3:"dib";s:3:"199";s:3:"ers";s:3:"200";s:3:"g s";s:3:"201";s:3:"han";s:3:"202";s:3:"ik ";s:3:"203";s:3:"kem";s:3:"204";s:3:"ma ";s:3:"205";s:3:"n l";s:3:"206";s:3:"nit";s:3:"207";s:3:"r b";s:3:"208";s:3:"rja";s:3:"209";s:3:"sa ";s:3:"210";s:3:" ju";s:3:"211";s:3:" or";s:3:"212";s:3:" si";s:3:"213";s:3:" ti";s:3:"214";s:3:"a y";s:3:"215";s:3:"aga";s:3:"216";s:3:"any";s:3:"217";s:3:"as ";s:3:"218";s:3:"cul";s:3:"219";s:3:"eme";s:3:"220";s:3:"emu";s:3:"221";s:3:"eny";s:3:"222";s:3:"epa";s:3:"223";s:3:"erb";s:3:"224";s:3:"erl";s:3:"225";s:3:"gi ";s:3:"226";s:3:"h m";s:3:"227";s:3:"i a";s:3:"228";s:3:"kel";s:3:"229";s:3:"li ";s:3:"230";s:3:"mel";s:3:"231";s:3:"nia";s:3:"232";s:3:"opa";s:3:"233";s:3:"rta";s:3:"234";s:3:"sia";s:3:"235";s:3:"tah";s:3:"236";s:3:"ula";s:3:"237";s:3:"un ";s:3:"238";s:3:"unt";s:3:"239";s:3:" at";s:3:"240";s:3:" bu";s:3:"241";s:3:" pu";s:3:"242";s:3:" ta";s:3:"243";s:3:"agi";s:3:"244";s:3:"alu";s:3:"245";s:3:"amb";s:3:"246";s:3:"bah";s:3:"247";s:3:"bis";s:3:"248";s:3:"er ";s:3:"249";s:3:"i t";s:3:"250";s:3:"ibe";s:3:"251";s:3:"ir ";s:3:"252";s:3:"ja ";s:3:"253";s:3:"k m";s:3:"254";s:3:"kar";s:3:"255";s:3:"lai";s:3:"256";s:3:"lal";s:3:"257";s:3:"lu ";s:3:"258";s:3:"mpa";s:3:"259";s:3:"ngk";s:3:"260";s:3:"nja";s:3:"261";s:3:"or ";s:3:"262";s:3:"pa ";s:3:"263";s:3:"pas";s:3:"264";s:3:"pem";s:3:"265";s:3:"rak";s:3:"266";s:3:"rik";s:3:"267";s:3:"seb";s:3:"268";s:3:"tam";s:3:"269";s:3:"tem";s:3:"270";s:3:"top";s:3:"271";s:3:"tuk";s:3:"272";s:3:"uni";s:3:"273";s:3:"war";s:3:"274";s:3:" al";s:3:"275";s:3:" ga";s:3:"276";s:3:" ge";s:3:"277";s:3:" ir";s:3:"278";s:3:" ja";s:3:"279";s:3:" mu";s:3:"280";s:3:" na";s:3:"281";s:3:" pr";s:3:"282";s:3:" su";s:3:"283";s:3:" un";s:3:"284";s:3:"ad ";s:3:"285";s:3:"adi";s:3:"286";s:3:"akt";s:3:"287";s:3:"ann";s:3:"288";s:3:"apo";s:3:"289";s:3:"bel";s:3:"290";s:3:"bul";s:3:"291";s:3:"der";s:3:"292";s:3:"ega";s:3:"293";s:3:"eke";s:3:"294";s:3:"ema";s:3:"295";s:3:"emp";s:3:"296";s:3:"ene";s:3:"297";s:3:"enj";s:3:"298";s:3:"esa";s:3:"299";}s:7:"italian";a:300:{s:3:" di";s:1:"0";s:3:"to ";s:1:"1";s:3:"la ";s:1:"2";s:3:" de";s:1:"3";s:3:"di ";s:1:"4";s:3:"no ";s:1:"5";s:3:" co";s:1:"6";s:3:"re ";s:1:"7";s:3:"ion";s:1:"8";s:3:"e d";s:1:"9";s:3:" e ";s:2:"10";s:3:"le ";s:2:"11";s:3:"del";s:2:"12";s:3:"ne ";s:2:"13";s:3:"ti ";s:2:"14";s:3:"ell";s:2:"15";s:3:" la";s:2:"16";s:3:" un";s:2:"17";s:3:"ni ";s:2:"18";s:3:"i d";s:2:"19";s:3:"per";s:2:"20";s:3:" pe";s:2:"21";s:3:"ent";s:2:"22";s:3:" in";s:2:"23";s:3:"one";s:2:"24";s:3:"he ";s:2:"25";s:3:"ta ";s:2:"26";s:3:"zio";s:2:"27";s:3:"che";s:2:"28";s:3:"o d";s:2:"29";s:3:"a d";s:2:"30";s:3:"na ";s:2:"31";s:3:"ato";s:2:"32";s:3:"e s";s:2:"33";s:3:" so";s:2:"34";s:3:"i s";s:2:"35";s:3:"lla";s:2:"36";s:3:"a p";s:2:"37";s:3:"li ";s:2:"38";s:3:"te ";s:2:"39";s:3:" al";s:2:"40";s:3:" ch";s:2:"41";s:3:"er ";s:2:"42";s:3:" pa";s:2:"43";s:3:" si";s:2:"44";s:3:"con";s:2:"45";s:3:"sta";s:2:"46";s:3:" pr";s:2:"47";s:3:"a c";s:2:"48";s:3:" se";s:2:"49";s:3:"el ";s:2:"50";s:3:"ia ";s:2:"51";s:3:"si ";s:2:"52";s:3:"e p";s:2:"53";s:3:" da";s:2:"54";s:3:"e i";s:2:"55";s:3:"i p";s:2:"56";s:3:"ont";s:2:"57";s:3:"ano";s:2:"58";s:3:"i c";s:2:"59";s:3:"all";s:2:"60";s:3:"azi";s:2:"61";s:3:"nte";s:2:"62";s:3:"on ";s:2:"63";s:3:"nti";s:2:"64";s:3:"o s";s:2:"65";s:3:" ri";s:2:"66";s:3:"i a";s:2:"67";s:3:"o a";s:2:"68";s:3:"un ";s:2:"69";s:3:" an";s:2:"70";s:3:"are";s:2:"71";s:3:"ari";s:2:"72";s:3:"e a";s:2:"73";s:3:"i e";s:2:"74";s:3:"ita";s:2:"75";s:3:"men";s:2:"76";s:3:"ri ";s:2:"77";s:3:" ca";s:2:"78";s:3:" il";s:2:"79";s:3:" no";s:2:"80";s:3:" po";s:2:"81";s:3:"a s";s:2:"82";s:3:"ant";s:2:"83";s:3:"il ";s:2:"84";s:3:"in ";s:2:"85";s:3:"a l";s:2:"86";s:3:"ati";s:2:"87";s:3:"cia";s:2:"88";s:3:"e c";s:2:"89";s:3:"ro ";s:2:"90";s:3:"ann";s:2:"91";s:3:"est";s:2:"92";s:3:"gli";s:2:"93";s:4:"tà ";s:2:"94";s:3:" qu";s:2:"95";s:3:"e l";s:2:"96";s:3:"nta";s:2:"97";s:3:" a ";s:2:"98";s:3:"com";s:2:"99";s:3:"o c";s:3:"100";s:3:"ra ";s:3:"101";s:3:" le";s:3:"102";s:3:" ne";s:3:"103";s:3:"ali";s:3:"104";s:3:"ere";s:3:"105";s:3:"ist";s:3:"106";s:3:" ma";s:3:"107";s:4:" è ";s:3:"108";s:3:"io ";s:3:"109";s:3:"lle";s:3:"110";s:3:"me ";s:3:"111";s:3:"era";s:3:"112";s:3:"ica";s:3:"113";s:3:"ost";s:3:"114";s:3:"pro";s:3:"115";s:3:"tar";s:3:"116";s:3:"una";s:3:"117";s:3:" pi";s:3:"118";s:3:"da ";s:3:"119";s:3:"tat";s:3:"120";s:3:" mi";s:3:"121";s:3:"att";s:3:"122";s:3:"ca ";s:3:"123";s:3:"mo ";s:3:"124";s:3:"non";s:3:"125";s:3:"par";s:3:"126";s:3:"sti";s:3:"127";s:3:" fa";s:3:"128";s:3:" i ";s:3:"129";s:3:" re";s:3:"130";s:3:" su";s:3:"131";s:3:"ess";s:3:"132";s:3:"ini";s:3:"133";s:3:"nto";s:3:"134";s:3:"o l";s:3:"135";s:3:"ssi";s:3:"136";s:3:"tto";s:3:"137";s:3:"a e";s:3:"138";s:3:"ame";s:3:"139";s:3:"col";s:3:"140";s:3:"ei ";s:3:"141";s:3:"ma ";s:3:"142";s:3:"o i";s:3:"143";s:3:"za ";s:3:"144";s:3:" st";s:3:"145";s:3:"a a";s:3:"146";s:3:"ale";s:3:"147";s:3:"anc";s:3:"148";s:3:"ani";s:3:"149";s:3:"i m";s:3:"150";s:3:"ian";s:3:"151";s:3:"o p";s:3:"152";s:3:"oni";s:3:"153";s:3:"sio";s:3:"154";s:3:"tan";s:3:"155";s:3:"tti";s:3:"156";s:3:" lo";s:3:"157";s:3:"i r";s:3:"158";s:3:"oci";s:3:"159";s:3:"oli";s:3:"160";s:3:"ona";s:3:"161";s:3:"ono";s:3:"162";s:3:"tra";s:3:"163";s:3:" l ";s:3:"164";s:3:"a r";s:3:"165";s:3:"eri";s:3:"166";s:3:"ett";s:3:"167";s:3:"lo ";s:3:"168";s:3:"nza";s:3:"169";s:3:"que";s:3:"170";s:3:"str";s:3:"171";s:3:"ter";s:3:"172";s:3:"tta";s:3:"173";s:3:" ba";s:3:"174";s:3:" li";s:3:"175";s:3:" te";s:3:"176";s:3:"ass";s:3:"177";s:3:"e f";s:3:"178";s:3:"enz";s:3:"179";s:3:"for";s:3:"180";s:3:"nno";s:3:"181";s:3:"olo";s:3:"182";s:3:"ori";s:3:"183";s:3:"res";s:3:"184";s:3:"tor";s:3:"185";s:3:" ci";s:3:"186";s:3:" vo";s:3:"187";s:3:"a i";s:3:"188";s:3:"al ";s:3:"189";s:3:"chi";s:3:"190";s:3:"e n";s:3:"191";s:3:"lia";s:3:"192";s:3:"pre";s:3:"193";s:3:"ria";s:3:"194";s:3:"uni";s:3:"195";s:3:"ver";s:3:"196";s:3:" sp";s:3:"197";s:3:"imo";s:3:"198";s:3:"l a";s:3:"199";s:3:"l c";s:3:"200";s:3:"ran";s:3:"201";s:3:"sen";s:3:"202";s:3:"soc";s:3:"203";s:3:"tic";s:3:"204";s:3:" fi";s:3:"205";s:3:" mo";s:3:"206";s:3:"a n";s:3:"207";s:3:"ce ";s:3:"208";s:3:"dei";s:3:"209";s:3:"ggi";s:3:"210";s:3:"gio";s:3:"211";s:3:"iti";s:3:"212";s:3:"l s";s:3:"213";s:3:"lit";s:3:"214";s:3:"ll ";s:3:"215";s:3:"mon";s:3:"216";s:3:"ola";s:3:"217";s:3:"pac";s:3:"218";s:3:"sim";s:3:"219";s:3:"tit";s:3:"220";s:3:"utt";s:3:"221";s:3:"vol";s:3:"222";s:3:" ar";s:3:"223";s:3:" fo";s:3:"224";s:3:" ha";s:3:"225";s:3:" sa";s:3:"226";s:3:"acc";s:3:"227";s:3:"e r";s:3:"228";s:3:"ire";s:3:"229";s:3:"man";s:3:"230";s:3:"ntr";s:3:"231";s:3:"rat";s:3:"232";s:3:"sco";s:3:"233";s:3:"tro";s:3:"234";s:3:"tut";s:3:"235";s:3:"va ";s:3:"236";s:3:" do";s:3:"237";s:3:" gi";s:3:"238";s:3:" me";s:3:"239";s:3:" sc";s:3:"240";s:3:" tu";s:3:"241";s:3:" ve";s:3:"242";s:3:" vi";s:3:"243";s:3:"a m";s:3:"244";s:3:"ber";s:3:"245";s:3:"can";s:3:"246";s:3:"cit";s:3:"247";s:3:"i l";s:3:"248";s:3:"ier";s:3:"249";s:4:"ità";s:3:"250";s:3:"lli";s:3:"251";s:3:"min";s:3:"252";s:3:"n p";s:3:"253";s:3:"nat";s:3:"254";s:3:"nda";s:3:"255";s:3:"o e";s:3:"256";s:3:"o f";s:3:"257";s:3:"o u";s:3:"258";s:3:"ore";s:3:"259";s:3:"oro";s:3:"260";s:3:"ort";s:3:"261";s:3:"sto";s:3:"262";s:3:"ten";s:3:"263";s:3:"tiv";s:3:"264";s:3:"van";s:3:"265";s:3:"art";s:3:"266";s:3:"cco";s:3:"267";s:3:"ci ";s:3:"268";s:3:"cos";s:3:"269";s:3:"dal";s:3:"270";s:3:"e v";s:3:"271";s:3:"i i";s:3:"272";s:3:"ila";s:3:"273";s:3:"ino";s:3:"274";s:3:"l p";s:3:"275";s:3:"n c";s:3:"276";s:3:"nit";s:3:"277";s:3:"ole";s:3:"278";s:3:"ome";s:3:"279";s:3:"po ";s:3:"280";s:3:"rio";s:3:"281";s:3:"sa ";s:3:"282";s:3:" ce";s:3:"283";s:3:" es";s:3:"284";s:3:" tr";s:3:"285";s:3:"a b";s:3:"286";s:3:"and";s:3:"287";s:3:"ata";s:3:"288";s:3:"der";s:3:"289";s:3:"ens";s:3:"290";s:3:"ers";s:3:"291";s:3:"gi ";s:3:"292";s:3:"ial";s:3:"293";s:3:"ina";s:3:"294";s:3:"itt";s:3:"295";s:3:"izi";s:3:"296";s:3:"lan";s:3:"297";s:3:"lor";s:3:"298";s:3:"mil";s:3:"299";}s:6:"kazakh";a:300:{s:5:"ан ";s:1:"0";s:5:"ен ";s:1:"1";s:5:"ың ";s:1:"2";s:5:" қа";s:1:"3";s:5:" ба";s:1:"4";s:5:"ай ";s:1:"5";s:6:"нда";s:1:"6";s:5:"ын ";s:1:"7";s:5:" са";s:1:"8";s:5:" ал";s:1:"9";s:5:"ді ";s:2:"10";s:6:"ары";s:2:"11";s:5:"ды ";s:2:"12";s:5:"ып ";s:2:"13";s:5:" мұ";s:2:"14";s:5:" бі";s:2:"15";s:6:"асы";s:2:"16";s:5:"да ";s:2:"17";s:6:"най";s:2:"18";s:5:" жа";s:2:"19";s:6:"мұн";s:2:"20";s:6:"ста";s:2:"21";s:6:"ған";s:2:"22";s:5:"н б";s:2:"23";s:6:"ұна";s:2:"24";s:5:" бо";s:2:"25";s:6:"ның";s:2:"26";s:5:"ін ";s:2:"27";s:6:"лар";s:2:"28";s:6:"сын";s:2:"29";s:5:" де";s:2:"30";s:6:"аға";s:2:"31";s:6:"тан";s:2:"32";s:5:" кө";s:2:"33";s:6:"бір";s:2:"34";s:5:"ер ";s:2:"35";s:6:"мен";s:2:"36";s:6:"аза";s:2:"37";s:6:"ынд";s:2:"38";s:6:"ыны";s:2:"39";s:5:" ме";s:2:"40";s:6:"анд";s:2:"41";s:6:"ері";s:2:"42";s:6:"бол";s:2:"43";s:6:"дың";s:2:"44";s:6:"қаз";s:2:"45";s:6:"аты";s:2:"46";s:5:"сы ";s:2:"47";s:6:"тын";s:2:"48";s:5:"ғы ";s:2:"49";s:5:" ке";s:2:"50";s:5:"ар ";s:2:"51";s:6:"зақ";s:2:"52";s:5:"ық ";s:2:"53";s:6:"ала";s:2:"54";s:6:"алы";s:2:"55";s:6:"аны";s:2:"56";s:6:"ара";s:2:"57";s:6:"ағы";s:2:"58";s:6:"ген";s:2:"59";s:6:"тар";s:2:"60";s:6:"тер";s:2:"61";s:6:"тыр";s:2:"62";s:6:"айд";s:2:"63";s:6:"ард";s:2:"64";s:5:"де ";s:2:"65";s:5:"ға ";s:2:"66";s:5:" қо";s:2:"67";s:6:"бар";s:2:"68";s:5:"ің ";s:2:"69";s:6:"қан";s:2:"70";s:5:" бе";s:2:"71";s:5:" қы";s:2:"72";s:6:"ақс";s:2:"73";s:6:"гер";s:2:"74";s:6:"дан";s:2:"75";s:6:"дар";s:2:"76";s:6:"лық";s:2:"77";s:6:"лға";s:2:"78";s:6:"ына";s:2:"79";s:5:"ір ";s:2:"80";s:6:"ірі";s:2:"81";s:6:"ғас";s:2:"82";s:5:" та";s:2:"83";s:5:"а б";s:2:"84";s:5:"гі ";s:2:"85";s:6:"еді";s:2:"86";s:6:"еле";s:2:"87";s:6:"йды";s:2:"88";s:5:"н к";s:2:"89";s:5:"н т";s:2:"90";s:6:"ола";s:2:"91";s:6:"рын";s:2:"92";s:5:"іп ";s:2:"93";s:6:"қст";s:2:"94";s:6:"қта";s:2:"95";s:5:"ң б";s:2:"96";s:5:" ай";s:2:"97";s:5:" ол";s:2:"98";s:5:" со";s:2:"99";s:6:"айт";s:3:"100";s:6:"дағ";s:3:"101";s:6:"иге";s:3:"102";s:6:"лер";s:3:"103";s:6:"лып";s:3:"104";s:5:"н а";s:3:"105";s:5:"ік ";s:3:"106";s:6:"ақт";s:3:"107";s:6:"бағ";s:3:"108";s:6:"кен";s:3:"109";s:5:"н қ";s:3:"110";s:5:"ны ";s:3:"111";s:6:"рге";s:3:"112";s:6:"рға";s:3:"113";s:5:"ыр ";s:3:"114";s:5:" ар";s:3:"115";s:6:"алғ";s:3:"116";s:6:"аса";s:3:"117";s:6:"бас";s:3:"118";s:6:"бер";s:3:"119";s:5:"ге ";s:3:"120";s:6:"еті";s:3:"121";s:5:"на ";s:3:"122";s:6:"нде";s:3:"123";s:5:"не ";s:3:"124";s:6:"ниг";s:3:"125";s:6:"рды";s:3:"126";s:5:"ры ";s:3:"127";s:6:"сай";s:3:"128";s:5:" ау";s:3:"129";s:5:" кү";s:3:"130";s:5:" ни";s:3:"131";s:5:" от";s:3:"132";s:5:" өз";s:3:"133";s:6:"ауд";s:3:"134";s:5:"еп ";s:3:"135";s:6:"иял";s:3:"136";s:6:"лты";s:3:"137";s:5:"н ж";s:3:"138";s:5:"н о";s:3:"139";s:6:"осы";s:3:"140";s:6:"оты";s:3:"141";s:6:"рып";s:3:"142";s:5:"рі ";s:3:"143";s:6:"тке";s:3:"144";s:5:"ты ";s:3:"145";s:5:"ы б";s:3:"146";s:5:"ы ж";s:3:"147";s:6:"ылы";s:3:"148";s:6:"ысы";s:3:"149";s:5:"і с";s:3:"150";s:6:"қар";s:3:"151";s:5:" бұ";s:3:"152";s:5:" да";s:3:"153";s:5:" же";s:3:"154";s:5:" тұ";s:3:"155";s:5:" құ";s:3:"156";s:6:"ады";s:3:"157";s:6:"айл";s:3:"158";s:5:"ап ";s:3:"159";s:6:"ата";s:3:"160";s:6:"ені";s:3:"161";s:6:"йла";s:3:"162";s:5:"н м";s:3:"163";s:5:"н с";s:3:"164";s:6:"нды";s:3:"165";s:6:"нді";s:3:"166";s:5:"р м";s:3:"167";s:6:"тай";s:3:"168";s:6:"тін";s:3:"169";s:5:"ы т";s:3:"170";s:5:"ыс ";s:3:"171";s:6:"інд";s:3:"172";s:5:" би";s:3:"173";s:5:"а ж";s:3:"174";s:6:"ауы";s:3:"175";s:6:"деп";s:3:"176";s:6:"дің";s:3:"177";s:6:"еке";s:3:"178";s:6:"ери";s:3:"179";s:6:"йын";s:3:"180";s:6:"кел";s:3:"181";s:6:"лды";s:3:"182";s:5:"ма ";s:3:"183";s:6:"нан";s:3:"184";s:6:"оны";s:3:"185";s:5:"п ж";s:3:"186";s:5:"п о";s:3:"187";s:5:"р б";s:3:"188";s:6:"рия";s:3:"189";s:6:"рла";s:3:"190";s:6:"уда";s:3:"191";s:6:"шыл";s:3:"192";s:5:"ы а";s:3:"193";s:6:"ықт";s:3:"194";s:5:"і а";s:3:"195";s:5:"і б";s:3:"196";s:5:"із ";s:3:"197";s:6:"ілі";s:3:"198";s:5:"ң қ";s:3:"199";s:5:" ас";s:3:"200";s:5:" ек";s:3:"201";s:5:" жо";s:3:"202";s:5:" мә";s:3:"203";s:5:" ос";s:3:"204";s:5:" ре";s:3:"205";s:5:" се";s:3:"206";s:6:"алд";s:3:"207";s:6:"дал";s:3:"208";s:6:"дег";s:3:"209";s:6:"дей";s:3:"210";s:5:"е б";s:3:"211";s:5:"ет ";s:3:"212";s:6:"жас";s:3:"213";s:5:"й б";s:3:"214";s:6:"лау";s:3:"215";s:6:"лда";s:3:"216";s:6:"мет";s:3:"217";s:6:"нын";s:3:"218";s:6:"сар";s:3:"219";s:5:"сі ";s:3:"220";s:5:"ті ";s:3:"221";s:6:"ыры";s:3:"222";s:6:"ыта";s:3:"223";s:6:"ісі";s:3:"224";s:5:"ң а";s:3:"225";s:6:"өте";s:3:"226";s:5:" ат";s:3:"227";s:5:" ел";s:3:"228";s:5:" жү";s:3:"229";s:5:" ма";s:3:"230";s:5:" то";s:3:"231";s:5:" шы";s:3:"232";s:5:"а а";s:3:"233";s:6:"алт";s:3:"234";s:6:"ама";s:3:"235";s:6:"арл";s:3:"236";s:6:"аст";s:3:"237";s:6:"бұл";s:3:"238";s:6:"дай";s:3:"239";s:6:"дық";s:3:"240";s:5:"ек ";s:3:"241";s:6:"ель";s:3:"242";s:6:"есі";s:3:"243";s:6:"зді";s:3:"244";s:6:"көт";s:3:"245";s:6:"лем";s:3:"246";s:5:"ль ";s:3:"247";s:5:"н е";s:3:"248";s:5:"п а";s:3:"249";s:5:"р а";s:3:"250";s:6:"рес";s:3:"251";s:5:"са ";s:3:"252";s:5:"та ";s:3:"253";s:6:"тте";s:3:"254";s:6:"тұр";s:3:"255";s:5:"шы ";s:3:"256";s:5:"ы д";s:3:"257";s:5:"ы қ";s:3:"258";s:5:"ыз ";s:3:"259";s:6:"қыт";s:3:"260";s:5:" ко";s:3:"261";s:5:" не";s:3:"262";s:5:" ой";s:3:"263";s:5:" ор";s:3:"264";s:5:" сұ";s:3:"265";s:5:" тү";s:3:"266";s:6:"аль";s:3:"267";s:6:"аре";s:3:"268";s:6:"атт";s:3:"269";s:6:"дір";s:3:"270";s:5:"ев ";s:3:"271";s:6:"егі";s:3:"272";s:6:"еда";s:3:"273";s:6:"екі";s:3:"274";s:6:"елд";s:3:"275";s:6:"ерг";s:3:"276";s:6:"ерд";s:3:"277";s:6:"ияд";s:3:"278";s:6:"кер";s:3:"279";s:6:"кет";s:3:"280";s:6:"лыс";s:3:"281";s:6:"ліс";s:3:"282";s:6:"мед";s:3:"283";s:6:"мпи";s:3:"284";s:5:"н д";s:3:"285";s:5:"ні ";s:3:"286";s:6:"нін";s:3:"287";s:5:"п т";s:3:"288";s:6:"пек";s:3:"289";s:6:"рел";s:3:"290";s:6:"рта";s:3:"291";s:6:"ріл";s:3:"292";s:6:"рін";s:3:"293";s:6:"сен";s:3:"294";s:6:"тал";s:3:"295";s:6:"шіл";s:3:"296";s:5:"ы к";s:3:"297";s:5:"ы м";s:3:"298";s:6:"ыст";s:3:"299";}s:6:"kyrgyz";a:300:{s:5:"ын ";s:1:"0";s:5:"ан ";s:1:"1";s:5:" жа";s:1:"2";s:5:"ен ";s:1:"3";s:5:"да ";s:1:"4";s:5:" та";s:1:"5";s:5:"ар ";s:1:"6";s:5:"ин ";s:1:"7";s:5:" ка";s:1:"8";s:6:"ары";s:1:"9";s:5:" ал";s:2:"10";s:5:" ба";s:2:"11";s:5:" би";s:2:"12";s:6:"лар";s:2:"13";s:5:" бо";s:2:"14";s:5:" кы";s:2:"15";s:6:"ала";s:2:"16";s:5:"н к";s:2:"17";s:5:" са";s:2:"18";s:6:"нда";s:2:"19";s:6:"ган";s:2:"20";s:6:"тар";s:2:"21";s:5:" де";s:2:"22";s:6:"анд";s:2:"23";s:5:"н б";s:2:"24";s:5:" ке";s:2:"25";s:6:"ард";s:2:"26";s:6:"мен";s:2:"27";s:5:"н т";s:2:"28";s:6:"ара";s:2:"29";s:6:"нын";s:2:"30";s:5:" да";s:2:"31";s:5:" ме";s:2:"32";s:6:"кыр";s:2:"33";s:5:" че";s:2:"34";s:5:"н а";s:2:"35";s:5:"ры ";s:2:"36";s:5:" ко";s:2:"37";s:6:"ген";s:2:"38";s:6:"дар";s:2:"39";s:6:"кен";s:2:"40";s:6:"кта";s:2:"41";s:5:"уу ";s:2:"42";s:6:"ене";s:2:"43";s:6:"ери";s:2:"44";s:5:" ша";s:2:"45";s:6:"алы";s:2:"46";s:5:"ат ";s:2:"47";s:5:"на ";s:2:"48";s:5:" кө";s:2:"49";s:5:" эм";s:2:"50";s:6:"аты";s:2:"51";s:6:"дан";s:2:"52";s:6:"деп";s:2:"53";s:6:"дын";s:2:"54";s:5:"еп ";s:2:"55";s:6:"нен";s:2:"56";s:6:"рын";s:2:"57";s:5:" бе";s:2:"58";s:6:"кан";s:2:"59";s:6:"луу";s:2:"60";s:6:"ргы";s:2:"61";s:6:"тан";s:2:"62";s:6:"шай";s:2:"63";s:6:"ырг";s:2:"64";s:5:"үн ";s:2:"65";s:5:" ар";s:2:"66";s:5:" ма";s:2:"67";s:6:"агы";s:2:"68";s:6:"акт";s:2:"69";s:6:"аны";s:2:"70";s:5:"гы ";s:2:"71";s:6:"гыз";s:2:"72";s:5:"ды ";s:2:"73";s:6:"рда";s:2:"74";s:5:"ай ";s:2:"75";s:6:"бир";s:2:"76";s:6:"бол";s:2:"77";s:5:"ер ";s:2:"78";s:5:"н с";s:2:"79";s:6:"нды";s:2:"80";s:5:"ун ";s:2:"81";s:5:"ча ";s:2:"82";s:6:"ынд";s:2:"83";s:5:"а к";s:2:"84";s:6:"ага";s:2:"85";s:6:"айл";s:2:"86";s:6:"ана";s:2:"87";s:5:"ап ";s:2:"88";s:5:"га ";s:2:"89";s:6:"лге";s:2:"90";s:6:"нча";s:2:"91";s:5:"п к";s:2:"92";s:6:"рды";s:2:"93";s:6:"туу";s:2:"94";s:6:"ыны";s:2:"95";s:5:" ан";s:2:"96";s:5:" өз";s:2:"97";s:6:"ама";s:2:"98";s:6:"ата";s:2:"99";s:6:"дин";s:3:"100";s:5:"йт ";s:3:"101";s:6:"лга";s:3:"102";s:6:"лоо";s:3:"103";s:5:"оо ";s:3:"104";s:5:"ри ";s:3:"105";s:6:"тин";s:3:"106";s:5:"ыз ";s:3:"107";s:5:"ып ";s:3:"108";s:6:"өрү";s:3:"109";s:5:" па";s:3:"110";s:5:" эк";s:3:"111";s:5:"а б";s:3:"112";s:6:"алг";s:3:"113";s:6:"асы";s:3:"114";s:6:"ашт";s:3:"115";s:6:"биз";s:3:"116";s:6:"кел";s:3:"117";s:6:"кте";s:3:"118";s:6:"тал";s:3:"119";s:5:" не";s:3:"120";s:5:" су";s:3:"121";s:6:"акы";s:3:"122";s:6:"ент";s:3:"123";s:6:"инд";s:3:"124";s:5:"ир ";s:3:"125";s:6:"кал";s:3:"126";s:5:"н д";s:3:"127";s:6:"нде";s:3:"128";s:6:"ого";s:3:"129";s:6:"онд";s:3:"130";s:6:"оюн";s:3:"131";s:5:"р б";s:3:"132";s:5:"р м";s:3:"133";s:6:"ран";s:3:"134";s:6:"сал";s:3:"135";s:6:"ста";s:3:"136";s:5:"сы ";s:3:"137";s:6:"ура";s:3:"138";s:6:"ыгы";s:3:"139";s:5:" аш";s:3:"140";s:5:" ми";s:3:"141";s:5:" сы";s:3:"142";s:5:" ту";s:3:"143";s:5:"ал ";s:3:"144";s:6:"арт";s:3:"145";s:6:"бор";s:3:"146";s:6:"елг";s:3:"147";s:6:"ени";s:3:"148";s:5:"ет ";s:3:"149";s:6:"жат";s:3:"150";s:6:"йло";s:3:"151";s:6:"кар";s:3:"152";s:5:"н м";s:3:"153";s:6:"огу";s:3:"154";s:5:"п а";s:3:"155";s:5:"п ж";s:3:"156";s:5:"р э";s:3:"157";s:6:"сын";s:3:"158";s:5:"ык ";s:3:"159";s:6:"юнч";s:3:"160";s:5:" бу";s:3:"161";s:5:" ур";s:3:"162";s:5:"а а";s:3:"163";s:5:"ак ";s:3:"164";s:6:"алд";s:3:"165";s:6:"алу";s:3:"166";s:6:"бар";s:3:"167";s:6:"бер";s:3:"168";s:6:"бою";s:3:"169";s:5:"ге ";s:3:"170";s:6:"дон";s:3:"171";s:6:"еги";s:3:"172";s:6:"ект";s:3:"173";s:6:"ефт";s:3:"174";s:5:"из ";s:3:"175";s:6:"кат";s:3:"176";s:6:"лды";s:3:"177";s:5:"н ч";s:3:"178";s:5:"н э";s:3:"179";s:5:"н ө";s:3:"180";s:6:"ндо";s:3:"181";s:6:"неф";s:3:"182";s:5:"он ";s:3:"183";s:6:"сат";s:3:"184";s:6:"тор";s:3:"185";s:5:"ты ";s:3:"186";s:6:"уда";s:3:"187";s:5:"ул ";s:3:"188";s:6:"ула";s:3:"189";s:6:"ууд";s:3:"190";s:5:"ы б";s:3:"191";s:5:"ы ж";s:3:"192";s:5:"ы к";s:3:"193";s:5:"ыл ";s:3:"194";s:6:"ына";s:3:"195";s:6:"эке";s:3:"196";s:6:"ясы";s:3:"197";s:5:" ат";s:3:"198";s:5:" до";s:3:"199";s:5:" жы";s:3:"200";s:5:" со";s:3:"201";s:5:" чы";s:3:"202";s:6:"аас";s:3:"203";s:6:"айт";s:3:"204";s:6:"аст";s:3:"205";s:6:"баа";s:3:"206";s:6:"баш";s:3:"207";s:6:"гар";s:3:"208";s:6:"гын";s:3:"209";s:5:"дө ";s:3:"210";s:5:"е б";s:3:"211";s:5:"ек ";s:3:"212";s:6:"жыл";s:3:"213";s:5:"и б";s:3:"214";s:5:"ик ";s:3:"215";s:6:"ияс";s:3:"216";s:6:"кыз";s:3:"217";s:6:"лда";s:3:"218";s:6:"лык";s:3:"219";s:6:"мда";s:3:"220";s:5:"н ж";s:3:"221";s:6:"нди";s:3:"222";s:5:"ни ";s:3:"223";s:6:"нин";s:3:"224";s:6:"орд";s:3:"225";s:6:"рдо";s:3:"226";s:6:"сто";s:3:"227";s:5:"та ";s:3:"228";s:6:"тер";s:3:"229";s:6:"тти";s:3:"230";s:6:"тур";s:3:"231";s:6:"тын";s:3:"232";s:5:"уп ";s:3:"233";s:6:"ушу";s:3:"234";s:6:"фти";s:3:"235";s:6:"ыкт";s:3:"236";s:5:"үп ";s:3:"237";s:5:"өн ";s:3:"238";s:5:" ай";s:3:"239";s:5:" бү";s:3:"240";s:5:" ич";s:3:"241";s:5:" иш";s:3:"242";s:5:" мо";s:3:"243";s:5:" пр";s:3:"244";s:5:" ре";s:3:"245";s:5:" өк";s:3:"246";s:5:" өт";s:3:"247";s:5:"а д";s:3:"248";s:5:"а у";s:3:"249";s:5:"а э";s:3:"250";s:6:"айм";s:3:"251";s:6:"амд";s:3:"252";s:6:"атт";s:3:"253";s:6:"бек";s:3:"254";s:6:"бул";s:3:"255";s:6:"гол";s:3:"256";s:6:"дег";s:3:"257";s:6:"еге";s:3:"258";s:6:"ейт";s:3:"259";s:6:"еле";s:3:"260";s:6:"енд";s:3:"261";s:6:"жак";s:3:"262";s:5:"и к";s:3:"263";s:6:"ини";s:3:"264";s:6:"ири";s:3:"265";s:6:"йма";s:3:"266";s:6:"кто";s:3:"267";s:6:"лик";s:3:"268";s:6:"мак";s:3:"269";s:6:"мес";s:3:"270";s:5:"н у";s:3:"271";s:5:"н ш";s:3:"272";s:6:"нтт";s:3:"273";s:5:"ол ";s:3:"274";s:6:"оло";s:3:"275";s:6:"пар";s:3:"276";s:6:"рак";s:3:"277";s:6:"рүү";s:3:"278";s:6:"сыр";s:3:"279";s:5:"ти ";s:3:"280";s:6:"тик";s:3:"281";s:6:"тта";s:3:"282";s:6:"төр";s:3:"283";s:5:"у ж";s:3:"284";s:5:"у с";s:3:"285";s:6:"шка";s:3:"286";s:5:"ы м";s:3:"287";s:6:"ызы";s:3:"288";s:6:"ылд";s:3:"289";s:6:"эме";s:3:"290";s:6:"үрү";s:3:"291";s:6:"өлү";s:3:"292";s:6:"өтө";s:3:"293";s:5:" же";s:3:"294";s:5:" тү";s:3:"295";s:5:" эл";s:3:"296";s:5:" өн";s:3:"297";s:5:"а ж";s:3:"298";s:6:"ады";s:3:"299";}s:5:"latin";a:300:{s:3:"um ";s:1:"0";s:3:"us ";s:1:"1";s:3:"ut ";s:1:"2";s:3:"et ";s:1:"3";s:3:"is ";s:1:"4";s:3:" et";s:1:"5";s:3:" in";s:1:"6";s:3:" qu";s:1:"7";s:3:"tur";s:1:"8";s:3:" pr";s:1:"9";s:3:"est";s:2:"10";s:3:"tio";s:2:"11";s:3:" au";s:2:"12";s:3:"am ";s:2:"13";s:3:"em ";s:2:"14";s:3:"aut";s:2:"15";s:3:" di";s:2:"16";s:3:"ent";s:2:"17";s:3:"in ";s:2:"18";s:3:"dic";s:2:"19";s:3:"t e";s:2:"20";s:3:" es";s:2:"21";s:3:"ur ";s:2:"22";s:3:"ati";s:2:"23";s:3:"ion";s:2:"24";s:3:"st ";s:2:"25";s:3:" ut";s:2:"26";s:3:"ae ";s:2:"27";s:3:"qua";s:2:"28";s:3:" de";s:2:"29";s:3:"nt ";s:2:"30";s:3:" su";s:2:"31";s:3:" si";s:2:"32";s:3:"itu";s:2:"33";s:3:"unt";s:2:"34";s:3:"rum";s:2:"35";s:3:"ia ";s:2:"36";s:3:"es ";s:2:"37";s:3:"ter";s:2:"38";s:3:" re";s:2:"39";s:3:"nti";s:2:"40";s:3:"rae";s:2:"41";s:3:"s e";s:2:"42";s:3:"qui";s:2:"43";s:3:"io ";s:2:"44";s:3:"pro";s:2:"45";s:3:"it ";s:2:"46";s:3:"per";s:2:"47";s:3:"ita";s:2:"48";s:3:"one";s:2:"49";s:3:"ici";s:2:"50";s:3:"ius";s:2:"51";s:3:" co";s:2:"52";s:3:"t d";s:2:"53";s:3:"bus";s:2:"54";s:3:"pra";s:2:"55";s:3:"m e";s:2:"56";s:3:" no";s:2:"57";s:3:"edi";s:2:"58";s:3:"tia";s:2:"59";s:3:"ue ";s:2:"60";s:3:"ibu";s:2:"61";s:3:" se";s:2:"62";s:3:" ad";s:2:"63";s:3:"er ";s:2:"64";s:3:" fi";s:2:"65";s:3:"ili";s:2:"66";s:3:"que";s:2:"67";s:3:"t i";s:2:"68";s:3:"de ";s:2:"69";s:3:"oru";s:2:"70";s:3:" te";s:2:"71";s:3:"ali";s:2:"72";s:3:" pe";s:2:"73";s:3:"aed";s:2:"74";s:3:"cit";s:2:"75";s:3:"m d";s:2:"76";s:3:"t s";s:2:"77";s:3:"tat";s:2:"78";s:3:"tem";s:2:"79";s:3:"tis";s:2:"80";s:3:"t p";s:2:"81";s:3:"sti";s:2:"82";s:3:"te ";s:2:"83";s:3:"cum";s:2:"84";s:3:"ere";s:2:"85";s:3:"ium";s:2:"86";s:3:" ex";s:2:"87";s:3:"rat";s:2:"88";s:3:"ta ";s:2:"89";s:3:"con";s:2:"90";s:3:"cti";s:2:"91";s:3:"oni";s:2:"92";s:3:"ra ";s:2:"93";s:3:"s i";s:2:"94";s:3:" cu";s:2:"95";s:3:" sa";s:2:"96";s:3:"eni";s:2:"97";s:3:"nis";s:2:"98";s:3:"nte";s:2:"99";s:3:"eri";s:3:"100";s:3:"omi";s:3:"101";s:3:"re ";s:3:"102";s:3:"s a";s:3:"103";s:3:"min";s:3:"104";s:3:"os ";s:3:"105";s:3:"ti ";s:3:"106";s:3:"uer";s:3:"107";s:3:" ma";s:3:"108";s:3:" ue";s:3:"109";s:3:"m s";s:3:"110";s:3:"nem";s:3:"111";s:3:"t m";s:3:"112";s:3:" mo";s:3:"113";s:3:" po";s:3:"114";s:3:" ui";s:3:"115";s:3:"gen";s:3:"116";s:3:"ict";s:3:"117";s:3:"m i";s:3:"118";s:3:"ris";s:3:"119";s:3:"s s";s:3:"120";s:3:"t a";s:3:"121";s:3:"uae";s:3:"122";s:3:" do";s:3:"123";s:3:"m a";s:3:"124";s:3:"t c";s:3:"125";s:3:" ge";s:3:"126";s:3:"as ";s:3:"127";s:3:"e i";s:3:"128";s:3:"e p";s:3:"129";s:3:"ne ";s:3:"130";s:3:" ca";s:3:"131";s:3:"ine";s:3:"132";s:3:"quo";s:3:"133";s:3:"s p";s:3:"134";s:3:" al";s:3:"135";s:3:"e e";s:3:"136";s:3:"ntu";s:3:"137";s:3:"ro ";s:3:"138";s:3:"tri";s:3:"139";s:3:"tus";s:3:"140";s:3:"uit";s:3:"141";s:3:"atu";s:3:"142";s:3:"ini";s:3:"143";s:3:"iqu";s:3:"144";s:3:"m p";s:3:"145";s:3:"ost";s:3:"146";s:3:"res";s:3:"147";s:3:"ura";s:3:"148";s:3:" ac";s:3:"149";s:3:" fu";s:3:"150";s:3:"a e";s:3:"151";s:3:"ant";s:3:"152";s:3:"nes";s:3:"153";s:3:"nim";s:3:"154";s:3:"sun";s:3:"155";s:3:"tra";s:3:"156";s:3:"e a";s:3:"157";s:3:"s d";s:3:"158";s:3:" pa";s:3:"159";s:3:" uo";s:3:"160";s:3:"ecu";s:3:"161";s:3:" om";s:3:"162";s:3:" tu";s:3:"163";s:3:"ad ";s:3:"164";s:3:"cut";s:3:"165";s:3:"omn";s:3:"166";s:3:"s q";s:3:"167";s:3:" ei";s:3:"168";s:3:"ex ";s:3:"169";s:3:"icu";s:3:"170";s:3:"tor";s:3:"171";s:3:"uid";s:3:"172";s:3:" ip";s:3:"173";s:3:" me";s:3:"174";s:3:"e s";s:3:"175";s:3:"era";s:3:"176";s:3:"eru";s:3:"177";s:3:"iam";s:3:"178";s:3:"ide";s:3:"179";s:3:"ips";s:3:"180";s:3:" iu";s:3:"181";s:3:"a s";s:3:"182";s:3:"do ";s:3:"183";s:3:"e d";s:3:"184";s:3:"eiu";s:3:"185";s:3:"ica";s:3:"186";s:3:"im ";s:3:"187";s:3:"m c";s:3:"188";s:3:"m u";s:3:"189";s:3:"tiu";s:3:"190";s:3:" ho";s:3:"191";s:3:"cat";s:3:"192";s:3:"ist";s:3:"193";s:3:"nat";s:3:"194";s:3:"on ";s:3:"195";s:3:"pti";s:3:"196";s:3:"reg";s:3:"197";s:3:"rit";s:3:"198";s:3:"s t";s:3:"199";s:3:"sic";s:3:"200";s:3:"spe";s:3:"201";s:3:" en";s:3:"202";s:3:" sp";s:3:"203";s:3:"dis";s:3:"204";s:3:"eli";s:3:"205";s:3:"liq";s:3:"206";s:3:"lis";s:3:"207";s:3:"men";s:3:"208";s:3:"mus";s:3:"209";s:3:"num";s:3:"210";s:3:"pos";s:3:"211";s:3:"sio";s:3:"212";s:3:" an";s:3:"213";s:3:" gr";s:3:"214";s:3:"abi";s:3:"215";s:3:"acc";s:3:"216";s:3:"ect";s:3:"217";s:3:"ri ";s:3:"218";s:3:"uan";s:3:"219";s:3:" le";s:3:"220";s:3:"ecc";s:3:"221";s:3:"ete";s:3:"222";s:3:"gra";s:3:"223";s:3:"non";s:3:"224";s:3:"se ";s:3:"225";s:3:"uen";s:3:"226";s:3:"uis";s:3:"227";s:3:" fa";s:3:"228";s:3:" tr";s:3:"229";s:3:"ate";s:3:"230";s:3:"e c";s:3:"231";s:3:"fil";s:3:"232";s:3:"na ";s:3:"233";s:3:"ni ";s:3:"234";s:3:"pul";s:3:"235";s:3:"s f";s:3:"236";s:3:"ui ";s:3:"237";s:3:"at ";s:3:"238";s:3:"cce";s:3:"239";s:3:"dam";s:3:"240";s:3:"i e";s:3:"241";s:3:"ina";s:3:"242";s:3:"leg";s:3:"243";s:3:"nos";s:3:"244";s:3:"ori";s:3:"245";s:3:"pec";s:3:"246";s:3:"rop";s:3:"247";s:3:"sta";s:3:"248";s:3:"uia";s:3:"249";s:3:"ene";s:3:"250";s:3:"iue";s:3:"251";s:3:"iui";s:3:"252";s:3:"siu";s:3:"253";s:3:"t t";s:3:"254";s:3:"t u";s:3:"255";s:3:"tib";s:3:"256";s:3:"tit";s:3:"257";s:3:" da";s:3:"258";s:3:" ne";s:3:"259";s:3:"a d";s:3:"260";s:3:"and";s:3:"261";s:3:"ege";s:3:"262";s:3:"equ";s:3:"263";s:3:"hom";s:3:"264";s:3:"imu";s:3:"265";s:3:"lor";s:3:"266";s:3:"m m";s:3:"267";s:3:"mni";s:3:"268";s:3:"ndo";s:3:"269";s:3:"ner";s:3:"270";s:3:"o e";s:3:"271";s:3:"r e";s:3:"272";s:3:"sit";s:3:"273";s:3:"tum";s:3:"274";s:3:"utu";s:3:"275";s:3:"a p";s:3:"276";s:3:"bis";s:3:"277";s:3:"bit";s:3:"278";s:3:"cer";s:3:"279";s:3:"cta";s:3:"280";s:3:"dom";s:3:"281";s:3:"fut";s:3:"282";s:3:"i s";s:3:"283";s:3:"ign";s:3:"284";s:3:"int";s:3:"285";s:3:"mod";s:3:"286";s:3:"ndu";s:3:"287";s:3:"nit";s:3:"288";s:3:"rib";s:3:"289";s:3:"rti";s:3:"290";s:3:"tas";s:3:"291";s:3:"und";s:3:"292";s:3:" ab";s:3:"293";s:3:"err";s:3:"294";s:3:"ers";s:3:"295";s:3:"ite";s:3:"296";s:3:"iti";s:3:"297";s:3:"m t";s:3:"298";s:3:"o p";s:3:"299";}s:7:"latvian";a:300:{s:3:"as ";s:1:"0";s:3:" la";s:1:"1";s:3:" pa";s:1:"2";s:3:" ne";s:1:"3";s:3:"es ";s:1:"4";s:3:" un";s:1:"5";s:3:"un ";s:1:"6";s:3:" ka";s:1:"7";s:3:" va";s:1:"8";s:3:"ar ";s:1:"9";s:3:"s p";s:2:"10";s:3:" ar";s:2:"11";s:3:" vi";s:2:"12";s:3:"is ";s:2:"13";s:3:"ai ";s:2:"14";s:3:" no";s:2:"15";s:3:"ja ";s:2:"16";s:3:"ija";s:2:"17";s:3:"iem";s:2:"18";s:3:"em ";s:2:"19";s:3:"tu ";s:2:"20";s:3:"tie";s:2:"21";s:3:"vie";s:2:"22";s:3:"lat";s:2:"23";s:3:"aks";s:2:"24";s:3:"ien";s:2:"25";s:3:"kst";s:2:"26";s:3:"ies";s:2:"27";s:3:"s a";s:2:"28";s:3:"rak";s:2:"29";s:3:"atv";s:2:"30";s:3:"tvi";s:2:"31";s:3:" ja";s:2:"32";s:3:" pi";s:2:"33";s:3:"ka ";s:2:"34";s:3:" ir";s:2:"35";s:3:"ir ";s:2:"36";s:3:"ta ";s:2:"37";s:3:" sa";s:2:"38";s:3:"ts ";s:2:"39";s:4:" kā";s:2:"40";s:4:"ās ";s:2:"41";s:3:" ti";s:2:"42";s:3:"ot ";s:2:"43";s:3:"s n";s:2:"44";s:3:" ie";s:2:"45";s:3:" ta";s:2:"46";s:4:"arī";s:2:"47";s:3:"par";s:2:"48";s:3:"pie";s:2:"49";s:3:" pr";s:2:"50";s:4:"kā ";s:2:"51";s:3:" at";s:2:"52";s:3:" ra";s:2:"53";s:3:"am ";s:2:"54";s:4:"inā";s:2:"55";s:4:"tā ";s:2:"56";s:3:" iz";s:2:"57";s:3:"jas";s:2:"58";s:3:"lai";s:2:"59";s:3:" na";s:2:"60";s:3:"aut";s:2:"61";s:4:"ieš";s:2:"62";s:3:"s s";s:2:"63";s:3:" ap";s:2:"64";s:3:" ko";s:2:"65";s:3:" st";s:2:"66";s:3:"iek";s:2:"67";s:3:"iet";s:2:"68";s:3:"jau";s:2:"69";s:3:"us ";s:2:"70";s:4:"rī ";s:2:"71";s:3:"tik";s:2:"72";s:4:"ība";s:2:"73";s:3:"na ";s:2:"74";s:3:" ga";s:2:"75";s:3:"cij";s:2:"76";s:3:"s i";s:2:"77";s:3:" uz";s:2:"78";s:3:"jum";s:2:"79";s:3:"s v";s:2:"80";s:3:"ms ";s:2:"81";s:3:"var";s:2:"82";s:3:" ku";s:2:"83";s:3:" ma";s:2:"84";s:4:"jā ";s:2:"85";s:3:"sta";s:2:"86";s:3:"s u";s:2:"87";s:4:" tā";s:2:"88";s:3:"die";s:2:"89";s:3:"kai";s:2:"90";s:3:"kas";s:2:"91";s:3:"ska";s:2:"92";s:3:" ci";s:2:"93";s:3:" da";s:2:"94";s:3:"kur";s:2:"95";s:3:"lie";s:2:"96";s:3:"tas";s:2:"97";s:3:"a p";s:2:"98";s:3:"est";s:2:"99";s:4:"stā";s:3:"100";s:4:"šan";s:3:"101";s:3:"nes";s:3:"102";s:3:"nie";s:3:"103";s:3:"s d";s:3:"104";s:3:"s m";s:3:"105";s:3:"val";s:3:"106";s:3:" di";s:3:"107";s:3:" es";s:3:"108";s:3:" re";s:3:"109";s:3:"no ";s:3:"110";s:3:"to ";s:3:"111";s:3:"umu";s:3:"112";s:3:"vai";s:3:"113";s:4:"ši ";s:3:"114";s:4:" vē";s:3:"115";s:3:"kum";s:3:"116";s:3:"nu ";s:3:"117";s:3:"rie";s:3:"118";s:3:"s t";s:3:"119";s:4:"ām ";s:3:"120";s:3:"ad ";s:3:"121";s:3:"et ";s:3:"122";s:3:"mu ";s:3:"123";s:3:"s l";s:3:"124";s:3:" be";s:3:"125";s:3:"aud";s:3:"126";s:3:"tur";s:3:"127";s:3:"vij";s:3:"128";s:4:"viņ";s:3:"129";s:4:"āju";s:3:"130";s:3:"bas";s:3:"131";s:3:"gad";s:3:"132";s:3:"i n";s:3:"133";s:3:"ika";s:3:"134";s:3:"os ";s:3:"135";s:3:"a v";s:3:"136";s:3:"not";s:3:"137";s:3:"oti";s:3:"138";s:3:"sts";s:3:"139";s:3:"aik";s:3:"140";s:3:"u a";s:3:"141";s:4:"ā a";s:3:"142";s:4:"āk ";s:3:"143";s:3:" to";s:3:"144";s:3:"ied";s:3:"145";s:3:"stu";s:3:"146";s:3:"ti ";s:3:"147";s:3:"u p";s:3:"148";s:4:"vēl";s:3:"149";s:4:"āci";s:3:"150";s:4:" šo";s:3:"151";s:3:"gi ";s:3:"152";s:3:"ko ";s:3:"153";s:3:"pro";s:3:"154";s:3:"s r";s:3:"155";s:4:"tāj";s:3:"156";s:3:"u s";s:3:"157";s:3:"u v";s:3:"158";s:3:"vis";s:3:"159";s:3:"aun";s:3:"160";s:3:"ks ";s:3:"161";s:3:"str";s:3:"162";s:3:"zin";s:3:"163";s:3:"a a";s:3:"164";s:4:"adī";s:3:"165";s:3:"da ";s:3:"166";s:3:"dar";s:3:"167";s:3:"ena";s:3:"168";s:3:"ici";s:3:"169";s:3:"kra";s:3:"170";s:3:"nas";s:3:"171";s:4:"stī";s:3:"172";s:4:"šu ";s:3:"173";s:4:" mē";s:3:"174";s:3:"a n";s:3:"175";s:3:"eci";s:3:"176";s:3:"i s";s:3:"177";s:3:"ie ";s:3:"178";s:4:"iņa";s:3:"179";s:3:"ju ";s:3:"180";s:3:"las";s:3:"181";s:3:"r t";s:3:"182";s:3:"ums";s:3:"183";s:4:"šie";s:3:"184";s:3:"bu ";s:3:"185";s:3:"cit";s:3:"186";s:3:"i a";s:3:"187";s:3:"ina";s:3:"188";s:3:"ma ";s:3:"189";s:3:"pus";s:3:"190";s:3:"ra ";s:3:"191";s:3:" au";s:3:"192";s:3:" se";s:3:"193";s:3:" sl";s:3:"194";s:3:"a s";s:3:"195";s:3:"ais";s:3:"196";s:4:"eši";s:3:"197";s:3:"iec";s:3:"198";s:3:"iku";s:3:"199";s:4:"pār";s:3:"200";s:3:"s b";s:3:"201";s:3:"s k";s:3:"202";s:3:"sot";s:3:"203";s:5:"ādā";s:3:"204";s:3:" in";s:3:"205";s:3:" li";s:3:"206";s:3:" tr";s:3:"207";s:3:"ana";s:3:"208";s:3:"eso";s:3:"209";s:3:"ikr";s:3:"210";s:3:"man";s:3:"211";s:3:"ne ";s:3:"212";s:3:"u k";s:3:"213";s:3:" tu";s:3:"214";s:3:"an ";s:3:"215";s:3:"av ";s:3:"216";s:3:"bet";s:3:"217";s:4:"būt";s:3:"218";s:3:"im ";s:3:"219";s:3:"isk";s:3:"220";s:4:"līd";s:3:"221";s:3:"nav";s:3:"222";s:3:"ras";s:3:"223";s:3:"ri ";s:3:"224";s:3:"s g";s:3:"225";s:3:"sti";s:3:"226";s:4:"īdz";s:3:"227";s:3:" ai";s:3:"228";s:3:"arb";s:3:"229";s:3:"cin";s:3:"230";s:3:"das";s:3:"231";s:3:"ent";s:3:"232";s:3:"gal";s:3:"233";s:3:"i p";s:3:"234";s:3:"lik";s:3:"235";s:4:"mā ";s:3:"236";s:3:"nek";s:3:"237";s:3:"pat";s:3:"238";s:4:"rēt";s:3:"239";s:3:"si ";s:3:"240";s:3:"tra";s:3:"241";s:4:"uši";s:3:"242";s:3:"vei";s:3:"243";s:3:" br";s:3:"244";s:3:" pu";s:3:"245";s:3:" sk";s:3:"246";s:3:"als";s:3:"247";s:3:"ama";s:3:"248";s:3:"edz";s:3:"249";s:3:"eka";s:3:"250";s:4:"ešu";s:3:"251";s:3:"ieg";s:3:"252";s:3:"jis";s:3:"253";s:3:"kam";s:3:"254";s:3:"lst";s:3:"255";s:4:"nāk";s:3:"256";s:3:"oli";s:3:"257";s:3:"pre";s:3:"258";s:4:"pēc";s:3:"259";s:3:"rot";s:3:"260";s:4:"tās";s:3:"261";s:3:"usi";s:3:"262";s:4:"ēl ";s:3:"263";s:4:"ēs ";s:3:"264";s:3:" bi";s:3:"265";s:3:" de";s:3:"266";s:3:" me";s:3:"267";s:4:" pā";s:3:"268";s:3:"a i";s:3:"269";s:3:"aid";s:3:"270";s:4:"ajā";s:3:"271";s:3:"ikt";s:3:"272";s:3:"kat";s:3:"273";s:3:"lic";s:3:"274";s:3:"lod";s:3:"275";s:3:"mi ";s:3:"276";s:3:"ni ";s:3:"277";s:3:"pri";s:3:"278";s:4:"rād";s:3:"279";s:4:"rīg";s:3:"280";s:3:"sim";s:3:"281";s:4:"trā";s:3:"282";s:3:"u l";s:3:"283";s:3:"uto";s:3:"284";s:3:"uz ";s:3:"285";s:4:"ēc ";s:3:"286";s:5:"ītā";s:3:"287";s:3:" ce";s:3:"288";s:4:" jā";s:3:"289";s:3:" sv";s:3:"290";s:3:"a t";s:3:"291";s:3:"aga";s:3:"292";s:3:"aiz";s:3:"293";s:3:"atu";s:3:"294";s:3:"ba ";s:3:"295";s:3:"cie";s:3:"296";s:3:"du ";s:3:"297";s:3:"dzi";s:3:"298";s:4:"dzī";s:3:"299";}s:10:"lithuanian";a:300:{s:3:"as ";s:1:"0";s:3:" pa";s:1:"1";s:3:" ka";s:1:"2";s:3:"ai ";s:1:"3";s:3:"us ";s:1:"4";s:3:"os ";s:1:"5";s:3:"is ";s:1:"6";s:3:" ne";s:1:"7";s:3:" ir";s:1:"8";s:3:"ir ";s:1:"9";s:3:"ti ";s:2:"10";s:3:" pr";s:2:"11";s:3:"aus";s:2:"12";s:3:"ini";s:2:"13";s:3:"s p";s:2:"14";s:3:"pas";s:2:"15";s:4:"ių ";s:2:"16";s:3:" ta";s:2:"17";s:3:" vi";s:2:"18";s:3:"iau";s:2:"19";s:3:" ko";s:2:"20";s:3:" su";s:2:"21";s:3:"kai";s:2:"22";s:3:"o p";s:2:"23";s:3:"usi";s:2:"24";s:3:" sa";s:2:"25";s:3:"vo ";s:2:"26";s:3:"tai";s:2:"27";s:3:"ali";s:2:"28";s:4:"tų ";s:2:"29";s:3:"io ";s:2:"30";s:3:"jo ";s:2:"31";s:3:"s k";s:2:"32";s:3:"sta";s:2:"33";s:3:"iai";s:2:"34";s:3:" bu";s:2:"35";s:3:" nu";s:2:"36";s:3:"ius";s:2:"37";s:3:"mo ";s:2:"38";s:3:" po";s:2:"39";s:3:"ien";s:2:"40";s:3:"s s";s:2:"41";s:3:"tas";s:2:"42";s:3:" me";s:2:"43";s:3:"uvo";s:2:"44";s:3:"kad";s:2:"45";s:4:" iš";s:2:"46";s:3:" la";s:2:"47";s:3:"to ";s:2:"48";s:3:"ais";s:2:"49";s:3:"ie ";s:2:"50";s:3:"kur";s:2:"51";s:3:"uri";s:2:"52";s:3:" ku";s:2:"53";s:3:"ijo";s:2:"54";s:4:"čia";s:2:"55";s:3:"au ";s:2:"56";s:3:"met";s:2:"57";s:3:"je ";s:2:"58";s:3:" va";s:2:"59";s:3:"ad ";s:2:"60";s:3:" ap";s:2:"61";s:3:"and";s:2:"62";s:3:" gr";s:2:"63";s:3:" ti";s:2:"64";s:3:"kal";s:2:"65";s:3:"asi";s:2:"66";s:3:"i p";s:2:"67";s:4:"iči";s:2:"68";s:3:"s i";s:2:"69";s:3:"s v";s:2:"70";s:3:"ink";s:2:"71";s:3:"o n";s:2:"72";s:4:"ės ";s:2:"73";s:3:"buv";s:2:"74";s:3:"s a";s:2:"75";s:3:" ga";s:2:"76";s:3:"aip";s:2:"77";s:3:"avi";s:2:"78";s:3:"mas";s:2:"79";s:3:"pri";s:2:"80";s:3:"tik";s:2:"81";s:3:" re";s:2:"82";s:3:"etu";s:2:"83";s:3:"jos";s:2:"84";s:3:" da";s:2:"85";s:3:"ent";s:2:"86";s:3:"oli";s:2:"87";s:3:"par";s:2:"88";s:3:"ant";s:2:"89";s:3:"ara";s:2:"90";s:3:"tar";s:2:"91";s:3:"ama";s:2:"92";s:3:"gal";s:2:"93";s:3:"imo";s:2:"94";s:4:"išk";s:2:"95";s:3:"o s";s:2:"96";s:3:" at";s:2:"97";s:3:" be";s:2:"98";s:4:" į ";s:2:"99";s:3:"min";s:3:"100";s:3:"tin";s:3:"101";s:3:" tu";s:3:"102";s:3:"s n";s:3:"103";s:3:" jo";s:3:"104";s:3:"dar";s:3:"105";s:3:"ip ";s:3:"106";s:3:"rei";s:3:"107";s:3:" te";s:3:"108";s:4:"dži";s:3:"109";s:3:"kas";s:3:"110";s:3:"nin";s:3:"111";s:3:"tei";s:3:"112";s:3:"vie";s:3:"113";s:3:" li";s:3:"114";s:3:" se";s:3:"115";s:3:"cij";s:3:"116";s:3:"gar";s:3:"117";s:3:"lai";s:3:"118";s:3:"art";s:3:"119";s:3:"lau";s:3:"120";s:3:"ras";s:3:"121";s:3:"no ";s:3:"122";s:3:"o k";s:3:"123";s:4:"tą ";s:3:"124";s:3:" ar";s:3:"125";s:4:"ėjo";s:3:"126";s:4:"vič";s:3:"127";s:3:"iga";s:3:"128";s:3:"pra";s:3:"129";s:3:"vis";s:3:"130";s:3:" na";s:3:"131";s:3:"men";s:3:"132";s:3:"oki";s:3:"133";s:4:"raš";s:3:"134";s:3:"s t";s:3:"135";s:3:"iet";s:3:"136";s:3:"ika";s:3:"137";s:3:"int";s:3:"138";s:3:"kom";s:3:"139";s:3:"tam";s:3:"140";s:3:"aug";s:3:"141";s:3:"avo";s:3:"142";s:3:"rie";s:3:"143";s:3:"s b";s:3:"144";s:3:" st";s:3:"145";s:3:"eim";s:3:"146";s:3:"ko ";s:3:"147";s:3:"nus";s:3:"148";s:3:"pol";s:3:"149";s:3:"ria";s:3:"150";s:3:"sau";s:3:"151";s:3:"api";s:3:"152";s:3:"me ";s:3:"153";s:3:"ne ";s:3:"154";s:3:"sik";s:3:"155";s:4:" ši";s:3:"156";s:3:"i n";s:3:"157";s:3:"ia ";s:3:"158";s:3:"ici";s:3:"159";s:3:"oja";s:3:"160";s:3:"sak";s:3:"161";s:3:"sti";s:3:"162";s:3:"ui ";s:3:"163";s:3:"ame";s:3:"164";s:3:"lie";s:3:"165";s:3:"o t";s:3:"166";s:3:"pie";s:3:"167";s:4:"čiu";s:3:"168";s:3:" di";s:3:"169";s:3:" pe";s:3:"170";s:3:"gri";s:3:"171";s:3:"ios";s:3:"172";s:3:"lia";s:3:"173";s:3:"lin";s:3:"174";s:3:"s d";s:3:"175";s:3:"s g";s:3:"176";s:3:"ta ";s:3:"177";s:3:"uot";s:3:"178";s:3:" ja";s:3:"179";s:4:" už";s:3:"180";s:3:"aut";s:3:"181";s:3:"i s";s:3:"182";s:3:"ino";s:3:"183";s:4:"mą ";s:3:"184";s:3:"oje";s:3:"185";s:3:"rav";s:3:"186";s:4:"dėl";s:3:"187";s:3:"nti";s:3:"188";s:3:"o a";s:3:"189";s:3:"toj";s:3:"190";s:4:"ėl ";s:3:"191";s:3:" to";s:3:"192";s:3:" vy";s:3:"193";s:3:"ar ";s:3:"194";s:3:"ina";s:3:"195";s:3:"lic";s:3:"196";s:3:"o v";s:3:"197";s:3:"sei";s:3:"198";s:3:"su ";s:3:"199";s:3:" mi";s:3:"200";s:3:" pi";s:3:"201";s:3:"din";s:3:"202";s:4:"iš ";s:3:"203";s:3:"lan";s:3:"204";s:3:"si ";s:3:"205";s:3:"tus";s:3:"206";s:3:" ba";s:3:"207";s:3:"asa";s:3:"208";s:3:"ata";s:3:"209";s:3:"kla";s:3:"210";s:3:"omi";s:3:"211";s:3:"tat";s:3:"212";s:3:" an";s:3:"213";s:3:" ji";s:3:"214";s:3:"als";s:3:"215";s:3:"ena";s:3:"216";s:4:"jų ";s:3:"217";s:3:"nuo";s:3:"218";s:3:"per";s:3:"219";s:3:"rig";s:3:"220";s:3:"s m";s:3:"221";s:3:"val";s:3:"222";s:3:"yta";s:3:"223";s:4:"čio";s:3:"224";s:3:" ra";s:3:"225";s:3:"i k";s:3:"226";s:3:"lik";s:3:"227";s:3:"net";s:3:"228";s:4:"nė ";s:3:"229";s:3:"tis";s:3:"230";s:3:"tuo";s:3:"231";s:3:"yti";s:3:"232";s:4:"ęs ";s:3:"233";s:4:"ų s";s:3:"234";s:3:"ada";s:3:"235";s:3:"ari";s:3:"236";s:3:"do ";s:3:"237";s:3:"eik";s:3:"238";s:3:"eis";s:3:"239";s:3:"ist";s:3:"240";s:3:"lst";s:3:"241";s:3:"ma ";s:3:"242";s:3:"nes";s:3:"243";s:3:"sav";s:3:"244";s:3:"sio";s:3:"245";s:3:"tau";s:3:"246";s:3:" ki";s:3:"247";s:3:"aik";s:3:"248";s:3:"aud";s:3:"249";s:3:"ies";s:3:"250";s:3:"ori";s:3:"251";s:3:"s r";s:3:"252";s:3:"ska";s:3:"253";s:3:" ge";s:3:"254";s:3:"ast";s:3:"255";s:3:"eig";s:3:"256";s:3:"et ";s:3:"257";s:3:"iam";s:3:"258";s:3:"isa";s:3:"259";s:3:"mis";s:3:"260";s:3:"nam";s:3:"261";s:3:"ome";s:3:"262";s:4:"žia";s:3:"263";s:3:"aba";s:3:"264";s:3:"aul";s:3:"265";s:3:"ikr";s:3:"266";s:4:"ką ";s:3:"267";s:3:"nta";s:3:"268";s:3:"ra ";s:3:"269";s:3:"tur";s:3:"270";s:3:" ma";s:3:"271";s:3:"die";s:3:"272";s:3:"ei ";s:3:"273";s:3:"i t";s:3:"274";s:3:"nas";s:3:"275";s:3:"rin";s:3:"276";s:3:"sto";s:3:"277";s:3:"tie";s:3:"278";s:3:"tuv";s:3:"279";s:3:"vos";s:3:"280";s:4:"ų p";s:3:"281";s:4:" dė";s:3:"282";s:3:"are";s:3:"283";s:3:"ats";s:3:"284";s:4:"enė";s:3:"285";s:3:"ili";s:3:"286";s:3:"ima";s:3:"287";s:3:"kar";s:3:"288";s:3:"ms ";s:3:"289";s:3:"nia";s:3:"290";s:3:"r p";s:3:"291";s:3:"rod";s:3:"292";s:3:"s l";s:3:"293";s:3:" o ";s:3:"294";s:3:"e p";s:3:"295";s:3:"es ";s:3:"296";s:3:"ide";s:3:"297";s:3:"ik ";s:3:"298";s:3:"ja ";s:3:"299";}s:10:"macedonian";a:300:{s:5:"на ";s:1:"0";s:5:" на";s:1:"1";s:5:"та ";s:1:"2";s:6:"ата";s:1:"3";s:6:"ија";s:1:"4";s:5:" пр";s:1:"5";s:5:"то ";s:1:"6";s:5:"ја ";s:1:"7";s:5:" за";s:1:"8";s:5:"а н";s:1:"9";s:4:" и ";s:2:"10";s:5:"а с";s:2:"11";s:5:"те ";s:2:"12";s:6:"ите";s:2:"13";s:5:" ко";s:2:"14";s:5:"от ";s:2:"15";s:5:" де";s:2:"16";s:5:" по";s:2:"17";s:5:"а д";s:2:"18";s:5:"во ";s:2:"19";s:5:"за ";s:2:"20";s:5:" во";s:2:"21";s:5:" од";s:2:"22";s:5:" се";s:2:"23";s:5:" не";s:2:"24";s:5:"се ";s:2:"25";s:5:" до";s:2:"26";s:5:"а в";s:2:"27";s:5:"ка ";s:2:"28";s:6:"ање";s:2:"29";s:5:"а п";s:2:"30";s:5:"о п";s:2:"31";s:6:"ува";s:2:"32";s:6:"циј";s:2:"33";s:5:"а о";s:2:"34";s:6:"ици";s:2:"35";s:6:"ето";s:2:"36";s:5:"о н";s:2:"37";s:6:"ани";s:2:"38";s:5:"ни ";s:2:"39";s:5:" вл";s:2:"40";s:6:"дек";s:2:"41";s:6:"ека";s:2:"42";s:6:"њет";s:2:"43";s:5:"ќе ";s:2:"44";s:4:" е ";s:2:"45";s:5:"а з";s:2:"46";s:5:"а и";s:2:"47";s:5:"ат ";s:2:"48";s:6:"вла";s:2:"49";s:5:"го ";s:2:"50";s:5:"е н";s:2:"51";s:5:"од ";s:2:"52";s:6:"пре";s:2:"53";s:5:" го";s:2:"54";s:5:" да";s:2:"55";s:5:" ма";s:2:"56";s:5:" ре";s:2:"57";s:5:" ќе";s:2:"58";s:6:"али";s:2:"59";s:5:"и д";s:2:"60";s:5:"и н";s:2:"61";s:6:"иот";s:2:"62";s:6:"нат";s:2:"63";s:6:"ово";s:2:"64";s:5:" па";s:2:"65";s:5:" ра";s:2:"66";s:5:" со";s:2:"67";s:6:"ове";s:2:"68";s:6:"пра";s:2:"69";s:6:"што";s:2:"70";s:5:"ње ";s:2:"71";s:5:"а е";s:2:"72";s:5:"да ";s:2:"73";s:6:"дат";s:2:"74";s:6:"дон";s:2:"75";s:5:"е в";s:2:"76";s:5:"е д";s:2:"77";s:5:"е з";s:2:"78";s:5:"е с";s:2:"79";s:6:"кон";s:2:"80";s:6:"нит";s:2:"81";s:5:"но ";s:2:"82";s:6:"они";s:2:"83";s:6:"ото";s:2:"84";s:6:"пар";s:2:"85";s:6:"при";s:2:"86";s:6:"ста";s:2:"87";s:5:"т н";s:2:"88";s:5:" шт";s:2:"89";s:5:"а к";s:2:"90";s:6:"аци";s:2:"91";s:5:"ва ";s:2:"92";s:6:"вањ";s:2:"93";s:5:"е п";s:2:"94";s:6:"ени";s:2:"95";s:5:"ла ";s:2:"96";s:6:"лад";s:2:"97";s:6:"мак";s:2:"98";s:6:"нес";s:2:"99";s:6:"нос";s:3:"100";s:6:"про";s:3:"101";s:6:"рен";s:3:"102";s:6:"јат";s:3:"103";s:5:" ин";s:3:"104";s:5:" ме";s:3:"105";s:5:" то";s:3:"106";s:5:"а г";s:3:"107";s:5:"а м";s:3:"108";s:5:"а р";s:3:"109";s:6:"аке";s:3:"110";s:6:"ако";s:3:"111";s:6:"вор";s:3:"112";s:6:"гов";s:3:"113";s:6:"едо";s:3:"114";s:6:"ена";s:3:"115";s:5:"и и";s:3:"116";s:6:"ира";s:3:"117";s:6:"кед";s:3:"118";s:5:"не ";s:3:"119";s:6:"ниц";s:3:"120";s:6:"ниј";s:3:"121";s:6:"ост";s:3:"122";s:5:"ра ";s:3:"123";s:6:"рат";s:3:"124";s:6:"ред";s:3:"125";s:6:"ска";s:3:"126";s:6:"тен";s:3:"127";s:5:" ка";s:3:"128";s:5:" сп";s:3:"129";s:5:" ја";s:3:"130";s:5:"а т";s:3:"131";s:6:"аде";s:3:"132";s:6:"арт";s:3:"133";s:5:"е г";s:3:"134";s:5:"е и";s:3:"135";s:6:"кат";s:3:"136";s:6:"лас";s:3:"137";s:6:"нио";s:3:"138";s:5:"о с";s:3:"139";s:5:"ри ";s:3:"140";s:5:" ба";s:3:"141";s:5:" би";s:3:"142";s:6:"ава";s:3:"143";s:6:"ате";s:3:"144";s:6:"вни";s:3:"145";s:5:"д н";s:3:"146";s:6:"ден";s:3:"147";s:6:"дов";s:3:"148";s:6:"држ";s:3:"149";s:6:"дув";s:3:"150";s:5:"е о";s:3:"151";s:5:"ен ";s:3:"152";s:6:"ере";s:3:"153";s:6:"ери";s:3:"154";s:5:"и п";s:3:"155";s:5:"и с";s:3:"156";s:6:"ина";s:3:"157";s:6:"кој";s:3:"158";s:6:"нци";s:3:"159";s:5:"о м";s:3:"160";s:5:"о о";s:3:"161";s:6:"одн";s:3:"162";s:6:"пор";s:3:"163";s:6:"ски";s:3:"164";s:6:"спо";s:3:"165";s:6:"ств";s:3:"166";s:6:"сти";s:3:"167";s:6:"тво";s:3:"168";s:5:"ти ";s:3:"169";s:5:" об";s:3:"170";s:5:" ов";s:3:"171";s:5:"а б";s:3:"172";s:6:"алн";s:3:"173";s:6:"ара";s:3:"174";s:6:"бар";s:3:"175";s:5:"е к";s:3:"176";s:5:"ед ";s:3:"177";s:6:"ент";s:3:"178";s:6:"еѓу";s:3:"179";s:5:"и о";s:3:"180";s:5:"ии ";s:3:"181";s:6:"меѓ";s:3:"182";s:5:"о д";s:3:"183";s:6:"оја";s:3:"184";s:6:"пот";s:3:"185";s:6:"раз";s:3:"186";s:6:"раш";s:3:"187";s:6:"спр";s:3:"188";s:6:"сто";s:3:"189";s:5:"т д";s:3:"190";s:5:"ци ";s:3:"191";s:5:" бе";s:3:"192";s:5:" гр";s:3:"193";s:5:" др";s:3:"194";s:5:" из";s:3:"195";s:5:" ст";s:3:"196";s:5:"аа ";s:3:"197";s:6:"бид";s:3:"198";s:6:"вед";s:3:"199";s:6:"гла";s:3:"200";s:6:"еко";s:3:"201";s:6:"енд";s:3:"202";s:6:"есе";s:3:"203";s:6:"етс";s:3:"204";s:6:"зац";s:3:"205";s:5:"и т";s:3:"206";s:6:"иза";s:3:"207";s:6:"инс";s:3:"208";s:6:"ист";s:3:"209";s:5:"ки ";s:3:"210";s:6:"ков";s:3:"211";s:6:"кол";s:3:"212";s:5:"ку ";s:3:"213";s:6:"лиц";s:3:"214";s:5:"о з";s:3:"215";s:5:"о и";s:3:"216";s:6:"ова";s:3:"217";s:6:"олк";s:3:"218";s:6:"оре";s:3:"219";s:6:"ори";s:3:"220";s:6:"под";s:3:"221";s:6:"рањ";s:3:"222";s:6:"реф";s:3:"223";s:6:"ржа";s:3:"224";s:6:"ров";s:3:"225";s:6:"рти";s:3:"226";s:5:"со ";s:3:"227";s:6:"тор";s:3:"228";s:6:"фер";s:3:"229";s:6:"цен";s:3:"230";s:6:"цит";s:3:"231";s:4:" а ";s:3:"232";s:5:" вр";s:3:"233";s:5:" гл";s:3:"234";s:5:" дп";s:3:"235";s:5:" мо";s:3:"236";s:5:" ни";s:3:"237";s:5:" но";s:3:"238";s:5:" оп";s:3:"239";s:5:" от";s:3:"240";s:5:"а ќ";s:3:"241";s:6:"або";s:3:"242";s:6:"ада";s:3:"243";s:6:"аса";s:3:"244";s:6:"аша";s:3:"245";s:5:"ба ";s:3:"246";s:6:"бот";s:3:"247";s:6:"ваа";s:3:"248";s:6:"ват";s:3:"249";s:6:"вот";s:3:"250";s:5:"ги ";s:3:"251";s:6:"гра";s:3:"252";s:5:"де ";s:3:"253";s:6:"дин";s:3:"254";s:6:"дум";s:3:"255";s:6:"евр";s:3:"256";s:6:"еду";s:3:"257";s:6:"ено";s:3:"258";s:6:"ера";s:3:"259";s:5:"ес ";s:3:"260";s:6:"ење";s:3:"261";s:5:"же ";s:3:"262";s:6:"зак";s:3:"263";s:5:"и в";s:3:"264";s:6:"ила";s:3:"265";s:6:"иту";s:3:"266";s:6:"коа";s:3:"267";s:6:"кои";s:3:"268";s:6:"лан";s:3:"269";s:6:"лку";s:3:"270";s:6:"лож";s:3:"271";s:6:"мот";s:3:"272";s:6:"нду";s:3:"273";s:6:"нст";s:3:"274";s:5:"о в";s:3:"275";s:5:"оа ";s:3:"276";s:6:"оал";s:3:"277";s:6:"обр";s:3:"278";s:5:"ов ";s:3:"279";s:6:"ови";s:3:"280";s:6:"овн";s:3:"281";s:5:"ои ";s:3:"282";s:5:"ор ";s:3:"283";s:6:"орм";s:3:"284";s:5:"ој ";s:3:"285";s:6:"рет";s:3:"286";s:6:"сед";s:3:"287";s:5:"ст ";s:3:"288";s:6:"тер";s:3:"289";s:6:"тиј";s:3:"290";s:6:"тоа";s:3:"291";s:6:"фор";s:3:"292";s:6:"ции";s:3:"293";s:5:"ѓу ";s:3:"294";s:5:" ал";s:3:"295";s:5:" ве";s:3:"296";s:5:" вм";s:3:"297";s:5:" ги";s:3:"298";s:5:" ду";s:3:"299";}s:9:"mongolian";a:300:{s:5:"ын ";s:1:"0";s:5:" ба";s:1:"1";s:5:"йн ";s:1:"2";s:6:"бай";s:1:"3";s:6:"ийн";s:1:"4";s:6:"уул";s:1:"5";s:5:" ул";s:1:"6";s:6:"улс";s:1:"7";s:5:"ан ";s:1:"8";s:5:" ха";s:1:"9";s:6:"ний";s:2:"10";s:5:"н х";s:2:"11";s:6:"гаа";s:2:"12";s:6:"сын";s:2:"13";s:5:"ий ";s:2:"14";s:6:"лсы";s:2:"15";s:5:" бо";s:2:"16";s:5:"й б";s:2:"17";s:5:"эн ";s:2:"18";s:5:"ах ";s:2:"19";s:6:"бол";s:2:"20";s:5:"ол ";s:2:"21";s:5:"н б";s:2:"22";s:6:"оло";s:2:"23";s:5:" хэ";s:2:"24";s:6:"онг";s:2:"25";s:6:"гол";s:2:"26";s:6:"гуу";s:2:"27";s:6:"нго";s:2:"28";s:5:"ыг ";s:2:"29";s:6:"жил";s:2:"30";s:5:" мо";s:2:"31";s:6:"лаг";s:2:"32";s:6:"лла";s:2:"33";s:6:"мон";s:2:"34";s:5:" тє";s:2:"35";s:5:" ху";s:2:"36";s:6:"айд";s:2:"37";s:5:"ны ";s:2:"38";s:5:"он ";s:2:"39";s:6:"сан";s:2:"40";s:6:"хий";s:2:"41";s:5:" аж";s:2:"42";s:5:" ор";s:2:"43";s:5:"л у";s:2:"44";s:5:"н т";s:2:"45";s:6:"улг";s:2:"46";s:6:"айг";s:2:"47";s:6:"длы";s:2:"48";s:5:"йг ";s:2:"49";s:5:" за";s:2:"50";s:6:"дэс";s:2:"51";s:5:"н а";s:2:"52";s:6:"ндэ";s:2:"53";s:6:"ула";s:2:"54";s:5:"ээ ";s:2:"55";s:6:"ага";s:2:"56";s:6:"ийг";s:2:"57";s:4:"vй ";s:2:"58";s:5:"аа ";s:2:"59";s:5:"й а";s:2:"60";s:6:"лын";s:2:"61";s:5:"н з";s:2:"62";s:5:" аю";s:2:"63";s:5:" зє";s:2:"64";s:6:"аар";s:2:"65";s:5:"ад ";s:2:"66";s:5:"ар ";s:2:"67";s:5:"гvй";s:2:"68";s:6:"зєв";s:2:"69";s:6:"ажи";s:2:"70";s:5:"ал ";s:2:"71";s:6:"аюу";s:2:"72";s:5:"г х";s:2:"73";s:5:"лгv";s:2:"74";s:5:"лж ";s:2:"75";s:6:"сни";s:2:"76";s:6:"эсн";s:2:"77";s:6:"юул";s:2:"78";s:6:"йдл";s:2:"79";s:6:"лыг";s:2:"80";s:6:"нхи";s:2:"81";s:6:"ууд";s:2:"82";s:6:"хам";s:2:"83";s:5:" нэ";s:2:"84";s:5:" са";s:2:"85";s:6:"гий";s:2:"86";s:6:"лах";s:2:"87";s:6:"лєл";s:2:"88";s:6:"рєн";s:2:"89";s:6:"єгч";s:2:"90";s:5:" та";s:2:"91";s:6:"илл";s:2:"92";s:6:"лий";s:2:"93";s:6:"лэх";s:2:"94";s:6:"рий";s:2:"95";s:5:"эх ";s:2:"96";s:5:" ер";s:2:"97";s:5:" эр";s:2:"98";s:6:"влє";s:2:"99";s:6:"ерє";s:3:"100";s:6:"ийл";s:3:"101";s:6:"лон";s:3:"102";s:6:"лєг";s:3:"103";s:6:"євл";s:3:"104";s:6:"єнх";s:3:"105";s:5:" хо";s:3:"106";s:6:"ари";s:3:"107";s:5:"их ";s:3:"108";s:6:"хан";s:3:"109";s:5:"эр ";s:3:"110";s:5:"єн ";s:3:"111";s:4:"vvл";s:3:"112";s:5:"ж б";s:3:"113";s:6:"тэй";s:3:"114";s:5:"х х";s:3:"115";s:6:"эрх";s:3:"116";s:4:" vн";s:3:"117";s:5:" нь";s:3:"118";s:5:"vнд";s:3:"119";s:6:"алт";s:3:"120";s:6:"йлє";s:3:"121";s:5:"нь ";s:3:"122";s:6:"тєр";s:3:"123";s:5:" га";s:3:"124";s:5:" су";s:3:"125";s:6:"аан";s:3:"126";s:6:"даа";s:3:"127";s:6:"илц";s:3:"128";s:6:"йгу";s:3:"129";s:5:"л а";s:3:"130";s:6:"лаа";s:3:"131";s:5:"н н";s:3:"132";s:6:"руу";s:3:"133";s:5:"эй ";s:3:"134";s:5:" то";s:3:"135";s:5:"н с";s:3:"136";s:6:"рил";s:3:"137";s:6:"єри";s:3:"138";s:6:"ааг";s:3:"139";s:5:"гч ";s:3:"140";s:6:"лээ";s:3:"141";s:5:"н о";s:3:"142";s:6:"рэг";s:3:"143";s:6:"суу";s:3:"144";s:6:"эрэ";s:3:"145";s:6:"їїл";s:3:"146";s:4:" yн";s:3:"147";s:5:" бу";s:3:"148";s:5:" дэ";s:3:"149";s:5:" ол";s:3:"150";s:5:" ту";s:3:"151";s:5:" ши";s:3:"152";s:5:"yнд";s:3:"153";s:6:"аши";s:3:"154";s:5:"г т";s:3:"155";s:5:"иг ";s:3:"156";s:5:"йл ";s:3:"157";s:6:"хар";s:3:"158";s:6:"шин";s:3:"159";s:5:"эг ";s:3:"160";s:5:"єр ";s:3:"161";s:5:" их";s:3:"162";s:5:" хє";s:3:"163";s:5:" хї";s:3:"164";s:5:"ам ";s:3:"165";s:6:"анг";s:3:"166";s:5:"ин ";s:3:"167";s:6:"йга";s:3:"168";s:6:"лса";s:3:"169";s:4:"н v";s:3:"170";s:5:"н е";s:3:"171";s:6:"нал";s:3:"172";s:5:"нд ";s:3:"173";s:6:"хуу";s:3:"174";s:6:"цаа";s:3:"175";s:5:"эд ";s:3:"176";s:6:"ээр";s:3:"177";s:5:"єл ";s:3:"178";s:5:"vйл";s:3:"179";s:6:"ада";s:3:"180";s:6:"айн";s:3:"181";s:6:"ала";s:3:"182";s:6:"амт";s:3:"183";s:6:"гах";s:3:"184";s:5:"д х";s:3:"185";s:6:"дал";s:3:"186";s:6:"зар";s:3:"187";s:5:"л б";s:3:"188";s:6:"лан";s:3:"189";s:5:"н д";s:3:"190";s:6:"сэн";s:3:"191";s:6:"улл";s:3:"192";s:5:"х б";s:3:"193";s:6:"хэр";s:3:"194";s:4:" бv";s:3:"195";s:5:" да";s:3:"196";s:5:" зо";s:3:"197";s:5:"vрэ";s:3:"198";s:6:"аад";s:3:"199";s:6:"гээ";s:3:"200";s:6:"лэн";s:3:"201";s:5:"н и";s:3:"202";s:5:"н э";s:3:"203";s:6:"нга";s:3:"204";s:5:"нэ ";s:3:"205";s:6:"тал";s:3:"206";s:6:"тын";s:3:"207";s:6:"хур";s:3:"208";s:5:"эл ";s:3:"209";s:5:" на";s:3:"210";s:5:" ни";s:3:"211";s:5:" он";s:3:"212";s:5:"vлэ";s:3:"213";s:5:"аг ";s:3:"214";s:5:"аж ";s:3:"215";s:5:"ай ";s:3:"216";s:6:"ата";s:3:"217";s:6:"бар";s:3:"218";s:5:"г б";s:3:"219";s:6:"гад";s:3:"220";s:6:"гїй";s:3:"221";s:5:"й х";s:3:"222";s:5:"лт ";s:3:"223";s:5:"н м";s:3:"224";s:5:"на ";s:3:"225";s:6:"оро";s:3:"226";s:6:"уль";s:3:"227";s:6:"чин";s:3:"228";s:5:"эж ";s:3:"229";s:6:"энэ";s:3:"230";s:6:"ээд";s:3:"231";s:5:"їй ";s:3:"232";s:6:"їлэ";s:3:"233";s:5:" би";s:3:"234";s:5:" тэ";s:3:"235";s:5:" эн";s:3:"236";s:6:"аны";s:3:"237";s:6:"дий";s:3:"238";s:6:"дээ";s:3:"239";s:6:"лал";s:3:"240";s:6:"лга";s:3:"241";s:5:"лд ";s:3:"242";s:6:"лог";s:3:"243";s:5:"ль ";s:3:"244";s:5:"н у";s:3:"245";s:5:"н ї";s:3:"246";s:5:"р б";s:3:"247";s:6:"рал";s:3:"248";s:6:"сон";s:3:"249";s:6:"тай";s:3:"250";s:6:"удл";s:3:"251";s:6:"элт";s:3:"252";s:6:"эрг";s:3:"253";s:6:"єлє";s:3:"254";s:4:" vй";s:3:"255";s:4:" в ";s:3:"256";s:5:" гэ";s:3:"257";s:4:" хv";s:3:"258";s:6:"ара";s:3:"259";s:5:"бvр";s:3:"260";s:5:"д н";s:3:"261";s:5:"д о";s:3:"262";s:5:"л х";s:3:"263";s:5:"лс ";s:3:"264";s:6:"лты";s:3:"265";s:5:"н г";s:3:"266";s:6:"нэг";s:3:"267";s:6:"огт";s:3:"268";s:6:"олы";s:3:"269";s:6:"оёр";s:3:"270";s:5:"р т";s:3:"271";s:6:"рээ";s:3:"272";s:6:"тав";s:3:"273";s:6:"тог";s:3:"274";s:6:"уур";s:3:"275";s:6:"хоё";s:3:"276";s:6:"хэл";s:3:"277";s:6:"хээ";s:3:"278";s:6:"элэ";s:3:"279";s:5:"ёр ";s:3:"280";s:5:" ав";s:3:"281";s:5:" ас";s:3:"282";s:5:" аш";s:3:"283";s:5:" ду";s:3:"284";s:5:" со";s:3:"285";s:5:" чи";s:3:"286";s:5:" эв";s:3:"287";s:5:" єр";s:3:"288";s:6:"аал";s:3:"289";s:6:"алд";s:3:"290";s:6:"амж";s:3:"291";s:6:"анд";s:3:"292";s:6:"асу";s:3:"293";s:6:"вэр";s:3:"294";s:5:"г у";s:3:"295";s:6:"двэ";s:3:"296";s:4:"жvv";s:3:"297";s:6:"лца";s:3:"298";s:6:"лэл";s:3:"299";}s:6:"nepali";a:300:{s:7:"को ";s:1:"0";s:7:"का ";s:1:"1";s:7:"मा ";s:1:"2";s:9:"हरु";s:1:"3";s:7:" ने";s:1:"4";s:9:"नेप";s:1:"5";s:9:"पाल";s:1:"6";s:9:"ेपा";s:1:"7";s:7:" सम";s:1:"8";s:7:"ले ";s:1:"9";s:7:" प्";s:2:"10";s:9:"प्र";s:2:"11";s:9:"कार";s:2:"12";s:7:"ा स";s:2:"13";s:9:"एको";s:2:"14";s:7:" भए";s:2:"15";s:5:" छ ";s:2:"16";s:7:" भा";s:2:"17";s:9:"्रम";s:2:"18";s:7:" गर";s:2:"19";s:9:"रुक";s:2:"20";s:5:" र ";s:2:"21";s:9:"भार";s:2:"22";s:9:"ारत";s:2:"23";s:7:" का";s:2:"24";s:7:" वि";s:2:"25";s:9:"भएक";s:2:"26";s:9:"ाली";s:2:"27";s:7:"ली ";s:2:"28";s:7:"ा प";s:2:"29";s:9:"ीहर";s:2:"30";s:9:"ार्";s:2:"31";s:7:"ो छ";s:2:"32";s:7:"ना ";s:2:"33";s:7:"रु ";s:2:"34";s:9:"ालक";s:2:"35";s:9:"्या";s:2:"36";s:7:" बा";s:2:"37";s:9:"एका";s:2:"38";s:7:"ने ";s:2:"39";s:9:"न्त";s:2:"40";s:7:"ा ब";s:2:"41";s:9:"ाको";s:2:"42";s:7:"ार ";s:2:"43";s:7:"ा भ";s:2:"44";s:9:"ाहर";s:2:"45";s:9:"्रो";s:2:"46";s:9:"क्ष";s:2:"47";s:7:"न् ";s:2:"48";s:9:"ारी";s:2:"49";s:7:" नि";s:2:"50";s:7:"ा न";s:2:"51";s:7:"ी स";s:2:"52";s:7:" डु";s:2:"53";s:9:"क्र";s:2:"54";s:9:"जना";s:2:"55";s:7:"यो ";s:2:"56";s:7:"ा छ";s:2:"57";s:9:"ेवा";s:2:"58";s:9:"्ता";s:2:"59";s:7:" रा";s:2:"60";s:9:"त्य";s:2:"61";s:9:"न्द";s:2:"62";s:9:"हुन";s:2:"63";s:7:"ा क";s:2:"64";s:9:"ामा";s:2:"65";s:7:"ी न";s:2:"66";s:9:"्दा";s:2:"67";s:7:" से";s:2:"68";s:9:"छन्";s:2:"69";s:9:"म्ब";s:2:"70";s:9:"रोत";s:2:"71";s:9:"सेव";s:2:"72";s:9:"स्त";s:2:"73";s:9:"स्र";s:2:"74";s:9:"ेका";s:2:"75";s:7:"्त ";s:2:"76";s:7:" बी";s:2:"77";s:7:" हु";s:2:"78";s:9:"क्त";s:2:"79";s:9:"त्र";s:2:"80";s:7:"रत ";s:2:"81";s:9:"र्न";s:2:"82";s:9:"र्य";s:2:"83";s:7:"ा र";s:2:"84";s:9:"ाका";s:2:"85";s:9:"ुको";s:2:"86";s:7:" एक";s:2:"87";s:7:" सं";s:2:"88";s:7:" सु";s:2:"89";s:9:"बीब";s:2:"90";s:9:"बीस";s:2:"91";s:9:"लको";s:2:"92";s:9:"स्य";s:2:"93";s:9:"ीबी";s:2:"94";s:9:"ीसी";s:2:"95";s:9:"ेको";s:2:"96";s:7:"ो स";s:2:"97";s:9:"्यक";s:2:"98";s:7:" छन";s:2:"99";s:7:" जन";s:3:"100";s:7:" बि";s:3:"101";s:7:" मु";s:3:"102";s:7:" स्";s:3:"103";s:9:"गर्";s:3:"104";s:9:"ताह";s:3:"105";s:9:"न्ध";s:3:"106";s:9:"बार";s:3:"107";s:9:"मन्";s:3:"108";s:9:"मस्";s:3:"109";s:9:"रुल";s:3:"110";s:9:"लाई";s:3:"111";s:7:"ा व";s:3:"112";s:7:"ाई ";s:3:"113";s:7:"ाल ";s:3:"114";s:9:"िका";s:3:"115";s:7:" त्";s:3:"116";s:7:" मा";s:3:"117";s:7:" यस";s:3:"118";s:7:" रु";s:3:"119";s:9:"ताक";s:3:"120";s:9:"बन्";s:3:"121";s:7:"र ब";s:3:"122";s:7:"रण ";s:3:"123";s:9:"रुप";s:3:"124";s:9:"रेक";s:3:"125";s:9:"ष्ट";s:3:"126";s:9:"सम्";s:3:"127";s:7:"सी ";s:3:"128";s:9:"ाएक";s:3:"129";s:9:"ुका";s:3:"130";s:9:"ुक्";s:3:"131";s:7:" अध";s:3:"132";s:7:" अन";s:3:"133";s:7:" तथ";s:3:"134";s:7:" थि";s:3:"135";s:7:" दे";s:3:"136";s:7:" पर";s:3:"137";s:7:" बै";s:3:"138";s:9:"तथा";s:3:"139";s:7:"ता ";s:3:"140";s:7:"दा ";s:3:"141";s:9:"द्द";s:3:"142";s:7:"नी ";s:3:"143";s:9:"बाट";s:3:"144";s:9:"यक्";s:3:"145";s:7:"री ";s:3:"146";s:9:"रीह";s:3:"147";s:9:"र्म";s:3:"148";s:9:"लका";s:3:"149";s:9:"समस";s:3:"150";s:7:"ा अ";s:3:"151";s:7:"ा ए";s:3:"152";s:7:"ाट ";s:3:"153";s:7:"िय ";s:3:"154";s:7:"ो प";s:3:"155";s:7:"ो म";s:3:"156";s:7:"्न ";s:3:"157";s:9:"्ने";s:3:"158";s:9:"्षा";s:3:"159";s:7:" पा";s:3:"160";s:7:" यो";s:3:"161";s:7:" हा";s:3:"162";s:9:"अधि";s:3:"163";s:9:"डुव";s:3:"164";s:7:"त भ";s:3:"165";s:7:"त स";s:3:"166";s:7:"था ";s:3:"167";s:9:"धिक";s:3:"168";s:9:"पमा";s:3:"169";s:9:"बैठ";s:3:"170";s:9:"मुद";s:3:"171";s:7:"या ";s:3:"172";s:9:"युक";s:3:"173";s:7:"र न";s:3:"174";s:9:"रति";s:3:"175";s:9:"वान";s:3:"176";s:9:"सार";s:3:"177";s:7:"ा आ";s:3:"178";s:7:"ा ज";s:3:"179";s:7:"ा ह";s:3:"180";s:9:"ुद्";s:3:"181";s:9:"ुपम";s:3:"182";s:9:"ुले";s:3:"183";s:9:"ुवा";s:3:"184";s:9:"ैठक";s:3:"185";s:7:"ो ब";s:3:"186";s:9:"्तर";s:3:"187";s:7:"्य ";s:3:"188";s:9:"्यस";s:3:"189";s:7:" क्";s:3:"190";s:7:" मन";s:3:"191";s:7:" रह";s:3:"192";s:9:"चार";s:3:"193";s:9:"तिय";s:3:"194";s:7:"दै ";s:3:"195";s:9:"निर";s:3:"196";s:7:"नु ";s:3:"197";s:9:"पर्";s:3:"198";s:9:"रक्";s:3:"199";s:9:"र्द";s:3:"200";s:9:"समा";s:3:"201";s:9:"सुर";s:3:"202";s:9:"ाउन";s:3:"203";s:7:"ान ";s:3:"204";s:9:"ानम";s:3:"205";s:9:"ारण";s:3:"206";s:9:"ाले";s:3:"207";s:7:"ि ब";s:3:"208";s:9:"ियो";s:3:"209";s:9:"ुन्";s:3:"210";s:9:"ुरक";s:3:"211";s:9:"्त्";s:3:"212";s:9:"्बन";s:3:"213";s:9:"्रा";s:3:"214";s:7:"्ष ";s:3:"215";s:7:" आर";s:3:"216";s:7:" जल";s:3:"217";s:7:" बे";s:3:"218";s:7:" या";s:3:"219";s:7:" सा";s:3:"220";s:9:"आएक";s:3:"221";s:7:"एक ";s:3:"222";s:9:"कर्";s:3:"223";s:9:"जलस";s:3:"224";s:9:"णका";s:3:"225";s:7:"त र";s:3:"226";s:9:"द्र";s:3:"227";s:9:"धान";s:3:"228";s:7:"धि ";s:3:"229";s:9:"नका";s:3:"230";s:9:"नमा";s:3:"231";s:7:"नि ";s:3:"232";s:9:"ममा";s:3:"233";s:7:"रम ";s:3:"234";s:9:"रहे";s:3:"235";s:9:"राज";s:3:"236";s:9:"लस्";s:3:"237";s:7:"ला ";s:3:"238";s:9:"वार";s:3:"239";s:9:"सका";s:3:"240";s:9:"हिल";s:3:"241";s:9:"हेक";s:3:"242";s:7:"ा त";s:3:"243";s:9:"ारे";s:3:"244";s:9:"िन्";s:3:"245";s:9:"िस्";s:3:"246";s:7:"े स";s:3:"247";s:7:"ो न";s:3:"248";s:7:"ो र";s:3:"249";s:7:"ोत ";s:3:"250";s:9:"्धि";s:3:"251";s:9:"्मी";s:3:"252";s:9:"्रस";s:3:"253";s:7:" दु";s:3:"254";s:7:" पन";s:3:"255";s:7:" बत";s:3:"256";s:7:" बन";s:3:"257";s:7:" भन";s:3:"258";s:9:"ंयु";s:3:"259";s:9:"आरम";s:3:"260";s:7:"खि ";s:3:"261";s:9:"ण्ड";s:3:"262";s:9:"तका";s:3:"263";s:9:"ताल";s:3:"264";s:7:"दी ";s:3:"265";s:9:"देख";s:3:"266";s:9:"निय";s:3:"267";s:9:"पनि";s:3:"268";s:9:"प्त";s:3:"269";s:9:"बता";s:3:"270";s:7:"मी ";s:3:"271";s:9:"म्भ";s:3:"272";s:7:"र स";s:3:"273";s:9:"रम्";s:3:"274";s:9:"लमा";s:3:"275";s:9:"विश";s:3:"276";s:9:"षाक";s:3:"277";s:9:"संय";s:3:"278";s:7:"ा ड";s:3:"279";s:7:"ा म";s:3:"280";s:9:"ानक";s:3:"281";s:9:"ालम";s:3:"282";s:7:"ि भ";s:3:"283";s:7:"ित ";s:3:"284";s:7:"ी प";s:3:"285";s:7:"ी र";s:3:"286";s:7:"ु भ";s:3:"287";s:9:"ुने";s:3:"288";s:7:"े ग";s:3:"289";s:9:"ेखि";s:3:"290";s:7:"ेर ";s:3:"291";s:7:"ो भ";s:3:"292";s:7:"ो व";s:3:"293";s:7:"ो ह";s:3:"294";s:7:"्भ ";s:3:"295";s:7:"्र ";s:3:"296";s:7:" ता";s:3:"297";s:7:" नम";s:3:"298";s:7:" ना";s:3:"299";}s:9:"norwegian";a:300:{s:3:"er ";s:1:"0";s:3:"en ";s:1:"1";s:3:"et ";s:1:"2";s:3:" de";s:1:"3";s:3:"det";s:1:"4";s:3:" i ";s:1:"5";s:3:"for";s:1:"6";s:3:"il ";s:1:"7";s:3:" fo";s:1:"8";s:3:" me";s:1:"9";s:3:"ing";s:2:"10";s:3:"om ";s:2:"11";s:3:" ha";s:2:"12";s:3:" og";s:2:"13";s:3:"ter";s:2:"14";s:3:" er";s:2:"15";s:3:" ti";s:2:"16";s:3:" st";s:2:"17";s:3:"og ";s:2:"18";s:3:"til";s:2:"19";s:3:"ne ";s:2:"20";s:3:" vi";s:2:"21";s:3:"re ";s:2:"22";s:3:" en";s:2:"23";s:3:" se";s:2:"24";s:3:"te ";s:2:"25";s:3:"or ";s:2:"26";s:3:"de ";s:2:"27";s:3:"kke";s:2:"28";s:3:"ke ";s:2:"29";s:3:"ar ";s:2:"30";s:3:"ng ";s:2:"31";s:3:"r s";s:2:"32";s:3:"ene";s:2:"33";s:3:" so";s:2:"34";s:3:"e s";s:2:"35";s:3:"der";s:2:"36";s:3:"an ";s:2:"37";s:3:"som";s:2:"38";s:3:"ste";s:2:"39";s:3:"at ";s:2:"40";s:3:"ed ";s:2:"41";s:3:"r i";s:2:"42";s:3:" av";s:2:"43";s:3:" in";s:2:"44";s:3:"men";s:2:"45";s:3:" at";s:2:"46";s:3:" ko";s:2:"47";s:4:" på";s:2:"48";s:3:"har";s:2:"49";s:3:" si";s:2:"50";s:3:"ere";s:2:"51";s:4:"på ";s:2:"52";s:3:"nde";s:2:"53";s:3:"and";s:2:"54";s:3:"els";s:2:"55";s:3:"ett";s:2:"56";s:3:"tte";s:2:"57";s:3:"lig";s:2:"58";s:3:"t s";s:2:"59";s:3:"den";s:2:"60";s:3:"t i";s:2:"61";s:3:"ikk";s:2:"62";s:3:"med";s:2:"63";s:3:"n s";s:2:"64";s:3:"rt ";s:2:"65";s:3:"ser";s:2:"66";s:3:"ska";s:2:"67";s:3:"t e";s:2:"68";s:3:"ker";s:2:"69";s:3:"sen";s:2:"70";s:3:"av ";s:2:"71";s:3:"ler";s:2:"72";s:3:"r a";s:2:"73";s:3:"ten";s:2:"74";s:3:"e f";s:2:"75";s:3:"r e";s:2:"76";s:3:"r t";s:2:"77";s:3:"ede";s:2:"78";s:3:"ig ";s:2:"79";s:3:" re";s:2:"80";s:3:"han";s:2:"81";s:3:"lle";s:2:"82";s:3:"ner";s:2:"83";s:3:" bl";s:2:"84";s:3:" fr";s:2:"85";s:3:"le ";s:2:"86";s:3:" ve";s:2:"87";s:3:"e t";s:2:"88";s:3:"lan";s:2:"89";s:3:"mme";s:2:"90";s:3:"nge";s:2:"91";s:3:" be";s:2:"92";s:3:" ik";s:2:"93";s:3:" om";s:2:"94";s:4:" å ";s:2:"95";s:3:"ell";s:2:"96";s:3:"sel";s:2:"97";s:3:"sta";s:2:"98";s:3:"ver";s:2:"99";s:3:" et";s:3:"100";s:3:" sk";s:3:"101";s:3:"nte";s:3:"102";s:3:"one";s:3:"103";s:3:"ore";s:3:"104";s:3:"r d";s:3:"105";s:3:"ske";s:3:"106";s:3:" an";s:3:"107";s:3:" la";s:3:"108";s:3:"del";s:3:"109";s:3:"gen";s:3:"110";s:3:"nin";s:3:"111";s:3:"r f";s:3:"112";s:3:"r v";s:3:"113";s:3:"se ";s:3:"114";s:3:" po";s:3:"115";s:3:"ir ";s:3:"116";s:3:"jon";s:3:"117";s:3:"mer";s:3:"118";s:3:"nen";s:3:"119";s:3:"omm";s:3:"120";s:3:"sjo";s:3:"121";s:3:" fl";s:3:"122";s:3:" sa";s:3:"123";s:3:"ern";s:3:"124";s:3:"kom";s:3:"125";s:3:"r m";s:3:"126";s:3:"r o";s:3:"127";s:3:"ren";s:3:"128";s:3:"vil";s:3:"129";s:3:"ale";s:3:"130";s:3:"es ";s:3:"131";s:3:"n a";s:3:"132";s:3:"t f";s:3:"133";s:3:" le";s:3:"134";s:3:"bli";s:3:"135";s:3:"e e";s:3:"136";s:3:"e i";s:3:"137";s:3:"e v";s:3:"138";s:3:"het";s:3:"139";s:3:"ye ";s:3:"140";s:3:" ir";s:3:"141";s:3:"al ";s:3:"142";s:3:"e o";s:3:"143";s:3:"ide";s:3:"144";s:3:"iti";s:3:"145";s:3:"lit";s:3:"146";s:3:"nne";s:3:"147";s:3:"ran";s:3:"148";s:3:"t o";s:3:"149";s:3:"tal";s:3:"150";s:3:"tat";s:3:"151";s:3:"tt ";s:3:"152";s:3:" ka";s:3:"153";s:3:"ans";s:3:"154";s:3:"asj";s:3:"155";s:3:"ge ";s:3:"156";s:3:"inn";s:3:"157";s:3:"kon";s:3:"158";s:3:"lse";s:3:"159";s:3:"pet";s:3:"160";s:3:"t d";s:3:"161";s:3:"vi ";s:3:"162";s:3:" ut";s:3:"163";s:3:"ent";s:3:"164";s:3:"eri";s:3:"165";s:3:"oli";s:3:"166";s:3:"r p";s:3:"167";s:3:"ret";s:3:"168";s:3:"ris";s:3:"169";s:3:"sto";s:3:"170";s:3:"str";s:3:"171";s:3:"t a";s:3:"172";s:3:" ga";s:3:"173";s:3:"all";s:3:"174";s:3:"ape";s:3:"175";s:3:"g s";s:3:"176";s:3:"ill";s:3:"177";s:3:"ira";s:3:"178";s:3:"kap";s:3:"179";s:3:"nn ";s:3:"180";s:3:"opp";s:3:"181";s:3:"r h";s:3:"182";s:3:"rin";s:3:"183";s:3:" br";s:3:"184";s:3:" op";s:3:"185";s:3:"e m";s:3:"186";s:3:"ert";s:3:"187";s:3:"ger";s:3:"188";s:3:"ion";s:3:"189";s:3:"kal";s:3:"190";s:3:"lsk";s:3:"191";s:3:"nes";s:3:"192";s:3:" gj";s:3:"193";s:3:" mi";s:3:"194";s:3:" pr";s:3:"195";s:3:"ang";s:3:"196";s:3:"e h";s:3:"197";s:3:"e r";s:3:"198";s:3:"elt";s:3:"199";s:3:"enn";s:3:"200";s:3:"i s";s:3:"201";s:3:"ist";s:3:"202";s:3:"jen";s:3:"203";s:3:"kan";s:3:"204";s:3:"lt ";s:3:"205";s:3:"nal";s:3:"206";s:3:"res";s:3:"207";s:3:"tor";s:3:"208";s:3:"ass";s:3:"209";s:3:"dre";s:3:"210";s:3:"e b";s:3:"211";s:3:"e p";s:3:"212";s:3:"mel";s:3:"213";s:3:"n t";s:3:"214";s:3:"nse";s:3:"215";s:3:"ort";s:3:"216";s:3:"per";s:3:"217";s:3:"reg";s:3:"218";s:3:"sje";s:3:"219";s:3:"t p";s:3:"220";s:3:"t v";s:3:"221";s:3:" hv";s:3:"222";s:4:" nå";s:3:"223";s:3:" va";s:3:"224";s:3:"ann";s:3:"225";s:3:"ato";s:3:"226";s:3:"e a";s:3:"227";s:3:"est";s:3:"228";s:3:"ise";s:3:"229";s:3:"isk";s:3:"230";s:3:"oil";s:3:"231";s:3:"ord";s:3:"232";s:3:"pol";s:3:"233";s:3:"ra ";s:3:"234";s:3:"rak";s:3:"235";s:3:"sse";s:3:"236";s:3:"toi";s:3:"237";s:3:" gr";s:3:"238";s:3:"ak ";s:3:"239";s:3:"eg ";s:3:"240";s:3:"ele";s:3:"241";s:3:"g a";s:3:"242";s:3:"ige";s:3:"243";s:3:"igh";s:3:"244";s:3:"m e";s:3:"245";s:3:"n f";s:3:"246";s:3:"n v";s:3:"247";s:3:"ndr";s:3:"248";s:3:"nsk";s:3:"249";s:3:"rer";s:3:"250";s:3:"t m";s:3:"251";s:3:"und";s:3:"252";s:3:"var";s:3:"253";s:4:"år ";s:3:"254";s:3:" he";s:3:"255";s:3:" no";s:3:"256";s:3:" ny";s:3:"257";s:3:"end";s:3:"258";s:3:"ete";s:3:"259";s:3:"fly";s:3:"260";s:3:"g i";s:3:"261";s:3:"ghe";s:3:"262";s:3:"ier";s:3:"263";s:3:"ind";s:3:"264";s:3:"int";s:3:"265";s:3:"lin";s:3:"266";s:3:"n d";s:3:"267";s:3:"n p";s:3:"268";s:3:"rne";s:3:"269";s:3:"sak";s:3:"270";s:3:"sie";s:3:"271";s:3:"t b";s:3:"272";s:3:"tid";s:3:"273";s:3:" al";s:3:"274";s:3:" pa";s:3:"275";s:3:" tr";s:3:"276";s:3:"ag ";s:3:"277";s:3:"dig";s:3:"278";s:3:"e d";s:3:"279";s:3:"e k";s:3:"280";s:3:"ess";s:3:"281";s:3:"hol";s:3:"282";s:3:"i d";s:3:"283";s:3:"lag";s:3:"284";s:3:"led";s:3:"285";s:3:"n e";s:3:"286";s:3:"n i";s:3:"287";s:3:"n o";s:3:"288";s:3:"pri";s:3:"289";s:3:"r b";s:3:"290";s:3:"st ";s:3:"291";s:3:" fe";s:3:"292";s:3:" li";s:3:"293";s:3:" ry";s:3:"294";s:3:"air";s:3:"295";s:3:"ake";s:3:"296";s:3:"d s";s:3:"297";s:3:"eas";s:3:"298";s:3:"egi";s:3:"299";}s:6:"pashto";a:300:{s:4:" د ";s:1:"0";s:5:"اؤ ";s:1:"1";s:5:" اؤ";s:1:"2";s:5:"نو ";s:1:"3";s:5:"ې د";s:1:"4";s:5:"ره ";s:1:"5";s:5:" په";s:1:"6";s:5:"نه ";s:1:"7";s:5:"چې ";s:1:"8";s:5:" چې";s:1:"9";s:5:"په ";s:2:"10";s:5:"ه د";s:2:"11";s:5:"ته ";s:2:"12";s:5:"و ا";s:2:"13";s:6:"ونو";s:2:"14";s:5:"و د";s:2:"15";s:5:" او";s:2:"16";s:6:"انو";s:2:"17";s:6:"ونه";s:2:"18";s:5:"ه ک";s:2:"19";s:5:" دا";s:2:"20";s:5:"ه ا";s:2:"21";s:5:"دې ";s:2:"22";s:5:"ښې ";s:2:"23";s:5:" کې";s:2:"24";s:5:"ان ";s:2:"25";s:5:"لو ";s:2:"26";s:5:"هم ";s:2:"27";s:5:"و م";s:2:"28";s:6:"کښې";s:2:"29";s:5:"ه م";s:2:"30";s:5:"ى ا";s:2:"31";s:5:" نو";s:2:"32";s:5:" ته";s:2:"33";s:5:" کښ";s:2:"34";s:6:"رون";s:2:"35";s:5:"کې ";s:2:"36";s:5:"ده ";s:2:"37";s:5:"له ";s:2:"38";s:5:"به ";s:2:"39";s:5:"رو ";s:2:"40";s:5:" هم";s:2:"41";s:5:"ه و";s:2:"42";s:5:"وى ";s:2:"43";s:5:"او ";s:2:"44";s:6:"تون";s:2:"45";s:5:"دا ";s:2:"46";s:5:" کو";s:2:"47";s:5:" کړ";s:2:"48";s:6:"قام";s:2:"49";s:5:" تر";s:2:"50";s:6:"ران";s:2:"51";s:5:"ه پ";s:2:"52";s:5:"ې و";s:2:"53";s:5:"ې پ";s:2:"54";s:5:" به";s:2:"55";s:5:" خو";s:2:"56";s:5:"تو ";s:2:"57";s:5:"د د";s:2:"58";s:5:"د ا";s:2:"59";s:5:"ه ت";s:2:"60";s:5:"و پ";s:2:"61";s:5:"يا ";s:2:"62";s:5:" خپ";s:2:"63";s:5:" دو";s:2:"64";s:5:" را";s:2:"65";s:5:" مش";s:2:"66";s:5:" پر";s:2:"67";s:6:"ارو";s:2:"68";s:5:"رې ";s:2:"69";s:5:"م د";s:2:"70";s:6:"مشر";s:2:"71";s:5:" شو";s:2:"72";s:5:" ور";s:2:"73";s:5:"ار ";s:2:"74";s:5:"دى ";s:2:"75";s:5:" اد";s:2:"76";s:5:" دى";s:2:"77";s:5:" مو";s:2:"78";s:5:"د پ";s:2:"79";s:5:"لي ";s:2:"80";s:5:"و ک";s:2:"81";s:5:" مق";s:2:"82";s:5:" يو";s:2:"83";s:5:"ؤ د";s:2:"84";s:6:"خپل";s:2:"85";s:6:"سره";s:2:"86";s:5:"ه چ";s:2:"87";s:5:"ور ";s:2:"88";s:5:" تا";s:2:"89";s:5:" دې";s:2:"90";s:5:" رو";s:2:"91";s:5:" سر";s:2:"92";s:5:" مل";s:2:"93";s:5:" کا";s:2:"94";s:5:"ؤ ا";s:2:"95";s:6:"اره";s:2:"96";s:6:"برو";s:2:"97";s:5:"مه ";s:2:"98";s:5:"ه ب";s:2:"99";s:5:"و ت";s:3:"100";s:6:"پښت";s:3:"101";s:5:" با";s:3:"102";s:5:" دغ";s:3:"103";s:5:" قب";s:3:"104";s:5:" له";s:3:"105";s:5:" وا";s:3:"106";s:5:" پا";s:3:"107";s:5:" پښ";s:3:"108";s:5:"د م";s:3:"109";s:5:"د ه";s:3:"110";s:5:"لې ";s:3:"111";s:6:"مات";s:3:"112";s:5:"مو ";s:3:"113";s:5:"ه ه";s:3:"114";s:5:"وي ";s:3:"115";s:5:"ې ب";s:3:"116";s:5:"ې ک";s:3:"117";s:5:" ده";s:3:"118";s:5:" قا";s:3:"119";s:5:"ال ";s:3:"120";s:6:"اما";s:3:"121";s:5:"د ن";s:3:"122";s:6:"قبر";s:3:"123";s:5:"ه ن";s:3:"124";s:6:"پار";s:3:"125";s:5:" اث";s:3:"126";s:5:" بي";s:3:"127";s:5:" لا";s:3:"128";s:5:" لر";s:3:"129";s:6:"اثا";s:3:"130";s:5:"د خ";s:3:"131";s:6:"دار";s:3:"132";s:6:"ريخ";s:3:"133";s:6:"شرا";s:3:"134";s:6:"مقا";s:3:"135";s:5:"نۍ ";s:3:"136";s:5:"ه ر";s:3:"137";s:5:"ه ل";s:3:"138";s:6:"ولو";s:3:"139";s:5:"يو ";s:3:"140";s:6:"کوم";s:3:"141";s:5:" دد";s:3:"142";s:5:" لو";s:3:"143";s:5:" مح";s:3:"144";s:5:" مر";s:3:"145";s:5:" وو";s:3:"146";s:6:"اتو";s:3:"147";s:6:"اري";s:3:"148";s:6:"الو";s:3:"149";s:6:"اند";s:3:"150";s:6:"خان";s:3:"151";s:5:"د ت";s:3:"152";s:5:"سې ";s:3:"153";s:5:"لى ";s:3:"154";s:6:"نور";s:3:"155";s:5:"و ل";s:3:"156";s:5:"ي چ";s:3:"157";s:5:"ړي ";s:3:"158";s:6:"ښتو";s:3:"159";s:5:"ې ل";s:3:"160";s:5:" جو";s:3:"161";s:5:" سي";s:3:"162";s:5:"ام ";s:3:"163";s:6:"بان";s:3:"164";s:6:"تار";s:3:"165";s:5:"تر ";s:3:"166";s:6:"ثار";s:3:"167";s:5:"خو ";s:3:"168";s:5:"دو ";s:3:"169";s:5:"ر ک";s:3:"170";s:5:"ل د";s:3:"171";s:6:"مون";s:3:"172";s:6:"ندې";s:3:"173";s:5:"و ن";s:3:"174";s:5:"ول ";s:3:"175";s:5:"وه ";s:3:"176";s:5:"ى و";s:3:"177";s:5:"ي د";s:3:"178";s:5:"ې ا";s:3:"179";s:5:"ې ت";s:3:"180";s:5:"ې ي";s:3:"181";s:5:" حک";s:3:"182";s:5:" خب";s:3:"183";s:5:" نه";s:3:"184";s:5:" پو";s:3:"185";s:5:"ا د";s:3:"186";s:5:"تې ";s:3:"187";s:6:"جوړ";s:3:"188";s:6:"حکم";s:3:"189";s:6:"حکو";s:3:"190";s:6:"خبر";s:3:"191";s:6:"دان";s:3:"192";s:5:"ر د";s:3:"193";s:5:"غه ";s:3:"194";s:6:"قاف";s:3:"195";s:6:"محک";s:3:"196";s:6:"وال";s:3:"197";s:6:"ومت";s:3:"198";s:6:"ويل";s:3:"199";s:5:"ى د";s:3:"200";s:5:"ى م";s:3:"201";s:6:"يره";s:3:"202";s:5:"پر ";s:3:"203";s:6:"کول";s:3:"204";s:5:"ې ه";s:3:"205";s:5:" تي";s:3:"206";s:5:" خا";s:3:"207";s:5:" وک";s:3:"208";s:5:" يا";s:3:"209";s:5:" ځا";s:3:"210";s:5:"ؤ ق";s:3:"211";s:6:"انۍ";s:3:"212";s:5:"بى ";s:3:"213";s:5:"غو ";s:3:"214";s:5:"ه خ";s:3:"215";s:5:"و ب";s:3:"216";s:6:"ودا";s:3:"217";s:6:"يدو";s:3:"218";s:5:"ړې ";s:3:"219";s:6:"کال";s:3:"220";s:5:" بر";s:3:"221";s:5:" قد";s:3:"222";s:5:" مي";s:3:"223";s:5:" وي";s:3:"224";s:5:" کر";s:3:"225";s:5:"ؤ م";s:3:"226";s:5:"ات ";s:3:"227";s:6:"ايي";s:3:"228";s:5:"تى ";s:3:"229";s:6:"تيا";s:3:"230";s:6:"تير";s:3:"231";s:6:"خوا";s:3:"232";s:6:"دغو";s:3:"233";s:5:"دم ";s:3:"234";s:6:"ديم";s:3:"235";s:5:"ر و";s:3:"236";s:6:"قدي";s:3:"237";s:5:"م خ";s:3:"238";s:6:"مان";s:3:"239";s:5:"مې ";s:3:"240";s:6:"نيو";s:3:"241";s:5:"نږ ";s:3:"242";s:5:"ه ي";s:3:"243";s:5:"و س";s:3:"244";s:5:"و چ";s:3:"245";s:6:"وان";s:3:"246";s:6:"ورو";s:3:"247";s:6:"ونږ";s:3:"248";s:6:"پور";s:3:"249";s:5:"ړه ";s:3:"250";s:5:"ړو ";s:3:"251";s:5:"ۍ د";s:3:"252";s:5:"ې ن";s:3:"253";s:5:" اه";s:3:"254";s:5:" زي";s:3:"255";s:5:" سو";s:3:"256";s:5:" شي";s:3:"257";s:5:" هر";s:3:"258";s:5:" هغ";s:3:"259";s:5:" ښا";s:3:"260";s:6:"اتل";s:3:"261";s:5:"اق ";s:3:"262";s:6:"اني";s:3:"263";s:6:"بري";s:3:"264";s:5:"بې ";s:3:"265";s:5:"ت ا";s:3:"266";s:5:"د ب";s:3:"267";s:5:"د س";s:3:"268";s:5:"ر م";s:3:"269";s:5:"رى ";s:3:"270";s:6:"عرا";s:3:"271";s:6:"لان";s:3:"272";s:5:"مى ";s:3:"273";s:5:"نى ";s:3:"274";s:5:"و خ";s:3:"275";s:5:"وئ ";s:3:"276";s:6:"ورک";s:3:"277";s:6:"ورې";s:3:"278";s:5:"ون ";s:3:"279";s:6:"وکړ";s:3:"280";s:5:"ى چ";s:3:"281";s:6:"يمه";s:3:"282";s:5:"يې ";s:3:"283";s:6:"ښتن";s:3:"284";s:5:"که ";s:3:"285";s:6:"کړي";s:3:"286";s:5:"ې خ";s:3:"287";s:5:"ے ش";s:3:"288";s:5:" تح";s:3:"289";s:5:" تو";s:3:"290";s:5:" در";s:3:"291";s:5:" دپ";s:3:"292";s:5:" صو";s:3:"293";s:5:" عر";s:3:"294";s:5:" ول";s:3:"295";s:5:" يؤ";s:3:"296";s:5:" پۀ";s:3:"297";s:5:" څو";s:3:"298";s:5:"ا ا";s:3:"299";}s:6:"pidgin";a:300:{s:3:" de";s:1:"0";s:3:" we";s:1:"1";s:3:" di";s:1:"2";s:3:"di ";s:1:"3";s:3:"dem";s:1:"4";s:3:"em ";s:1:"5";s:3:"ay ";s:1:"6";s:3:" sa";s:1:"7";s:3:"or ";s:1:"8";s:3:"say";s:1:"9";s:3:"ke ";s:2:"10";s:3:"ey ";s:2:"11";s:3:" an";s:2:"12";s:3:" go";s:2:"13";s:3:" e ";s:2:"14";s:3:" to";s:2:"15";s:3:" ma";s:2:"16";s:3:"e d";s:2:"17";s:3:"wey";s:2:"18";s:3:"for";s:2:"19";s:3:"nd ";s:2:"20";s:3:"to ";s:2:"21";s:3:" be";s:2:"22";s:3:" fo";s:2:"23";s:3:"ake";s:2:"24";s:3:"im ";s:2:"25";s:3:" pe";s:2:"26";s:3:"le ";s:2:"27";s:3:"go ";s:2:"28";s:3:"ll ";s:2:"29";s:3:"de ";s:2:"30";s:3:"e s";s:2:"31";s:3:"on ";s:2:"32";s:3:"get";s:2:"33";s:3:"ght";s:2:"34";s:3:"igh";s:2:"35";s:3:" ri";s:2:"36";s:3:"et ";s:2:"37";s:3:"rig";s:2:"38";s:3:" ge";s:2:"39";s:3:"y d";s:2:"40";s:3:" na";s:2:"41";s:3:"mak";s:2:"42";s:3:"t t";s:2:"43";s:3:" no";s:2:"44";s:3:"and";s:2:"45";s:3:"tin";s:2:"46";s:3:"ing";s:2:"47";s:3:"eve";s:2:"48";s:3:"ri ";s:2:"49";s:3:" im";s:2:"50";s:3:" am";s:2:"51";s:3:" or";s:2:"52";s:3:"am ";s:2:"53";s:3:"be ";s:2:"54";s:3:" ev";s:2:"55";s:3:" ta";s:2:"56";s:3:"ht ";s:2:"57";s:3:"e w";s:2:"58";s:3:" li";s:2:"59";s:3:"eri";s:2:"60";s:3:"ng ";s:2:"61";s:3:"ver";s:2:"62";s:3:"all";s:2:"63";s:3:"e f";s:2:"64";s:3:"ers";s:2:"65";s:3:"ntr";s:2:"66";s:3:"ont";s:2:"67";s:3:" do";s:2:"68";s:3:"r d";s:2:"69";s:3:" ko";s:2:"70";s:3:" ti";s:2:"71";s:3:"an ";s:2:"72";s:3:"kon";s:2:"73";s:3:"per";s:2:"74";s:3:"tri";s:2:"75";s:3:"y e";s:2:"76";s:3:"rso";s:2:"77";s:3:"son";s:2:"78";s:3:"no ";s:2:"79";s:3:"ome";s:2:"80";s:3:"is ";s:2:"81";s:3:"do ";s:2:"82";s:3:"ne ";s:2:"83";s:3:"one";s:2:"84";s:3:"ion";s:2:"85";s:3:"m g";s:2:"86";s:3:"i k";s:2:"87";s:3:" al";s:2:"88";s:3:"bod";s:2:"89";s:3:"i w";s:2:"90";s:3:"odi";s:2:"91";s:3:" so";s:2:"92";s:3:" wo";s:2:"93";s:3:"o d";s:2:"94";s:3:"st ";s:2:"95";s:3:"t r";s:2:"96";s:3:" of";s:2:"97";s:3:"aim";s:2:"98";s:3:"e g";s:2:"99";s:3:"nai";s:3:"100";s:3:" co";s:3:"101";s:3:"dis";s:3:"102";s:3:"me ";s:3:"103";s:3:"of ";s:3:"104";s:3:" wa";s:3:"105";s:3:"e t";s:3:"106";s:3:" ar";s:3:"107";s:3:"e l";s:3:"108";s:3:"ike";s:3:"109";s:3:"lik";s:3:"110";s:3:"t a";s:3:"111";s:3:"wor";s:3:"112";s:3:"alk";s:3:"113";s:3:"ell";s:3:"114";s:3:"eop";s:3:"115";s:3:"lk ";s:3:"116";s:3:"opl";s:3:"117";s:3:"peo";s:3:"118";s:3:"ple";s:3:"119";s:3:"re ";s:3:"120";s:3:"tal";s:3:"121";s:3:"any";s:3:"122";s:3:"e a";s:3:"123";s:3:"o g";s:3:"124";s:3:"art";s:3:"125";s:3:"cle";s:3:"126";s:3:"i p";s:3:"127";s:3:"icl";s:3:"128";s:3:"rti";s:3:"129";s:3:"the";s:3:"130";s:3:"tic";s:3:"131";s:3:"we ";s:3:"132";s:3:"f d";s:3:"133";s:3:"in ";s:3:"134";s:3:" mu";s:3:"135";s:3:"e n";s:3:"136";s:3:"e o";s:3:"137";s:3:"mus";s:3:"138";s:3:"n d";s:3:"139";s:3:"na ";s:3:"140";s:3:"o m";s:3:"141";s:3:"ust";s:3:"142";s:3:"wel";s:3:"143";s:3:"e e";s:3:"144";s:3:"her";s:3:"145";s:3:"m d";s:3:"146";s:3:"nt ";s:3:"147";s:3:" fi";s:3:"148";s:3:"at ";s:3:"149";s:3:"e b";s:3:"150";s:3:"it ";s:3:"151";s:3:"m w";s:3:"152";s:3:"o t";s:3:"153";s:3:"wan";s:3:"154";s:3:"com";s:3:"155";s:3:"da ";s:3:"156";s:3:"fit";s:3:"157";s:3:"m b";s:3:"158";s:3:"so ";s:3:"159";s:3:" fr";s:3:"160";s:3:"ce ";s:3:"161";s:3:"er ";s:3:"162";s:3:"o a";s:3:"163";s:3:" if";s:3:"164";s:3:" on";s:3:"165";s:3:"ent";s:3:"166";s:3:"if ";s:3:"167";s:3:"ind";s:3:"168";s:3:"kin";s:3:"169";s:3:"l d";s:3:"170";s:3:"man";s:3:"171";s:3:"o s";s:3:"172";s:3:" se";s:3:"173";s:3:"y a";s:3:"174";s:3:"y m";s:3:"175";s:3:" re";s:3:"176";s:3:"ee ";s:3:"177";s:3:"k a";s:3:"178";s:3:"t s";s:3:"179";s:3:"ve ";s:3:"180";s:3:"y w";s:3:"181";s:3:" ki";s:3:"182";s:3:"eti";s:3:"183";s:3:"men";s:3:"184";s:3:"ta ";s:3:"185";s:3:"y n";s:3:"186";s:3:"d t";s:3:"187";s:3:"dey";s:3:"188";s:3:"e c";s:3:"189";s:3:"i o";s:3:"190";s:3:"ibo";s:3:"191";s:3:"ld ";s:3:"192";s:3:"m t";s:3:"193";s:3:"n b";s:3:"194";s:3:"o b";s:3:"195";s:3:"ow ";s:3:"196";s:3:"ree";s:3:"197";s:3:"rio";s:3:"198";s:3:"t d";s:3:"199";s:3:" hu";s:3:"200";s:3:" su";s:3:"201";s:3:"en ";s:3:"202";s:3:"hts";s:3:"203";s:3:"ive";s:3:"204";s:3:"m n";s:3:"205";s:3:"n g";s:3:"206";s:3:"ny ";s:3:"207";s:3:"oth";s:3:"208";s:3:"ts ";s:3:"209";s:3:" as";s:3:"210";s:3:" wh";s:3:"211";s:3:"as ";s:3:"212";s:3:"gom";s:3:"213";s:3:"hum";s:3:"214";s:3:"k s";s:3:"215";s:3:"oda";s:3:"216";s:3:"ork";s:3:"217";s:3:"se ";s:3:"218";s:3:"uma";s:3:"219";s:3:"ut ";s:3:"220";s:3:" ba";s:3:"221";s:3:" ot";s:3:"222";s:3:"ano";s:3:"223";s:3:"m a";s:3:"224";s:3:"m s";s:3:"225";s:3:"nod";s:3:"226";s:3:"om ";s:3:"227";s:3:"r a";s:3:"228";s:3:"r i";s:3:"229";s:3:"rk ";s:3:"230";s:3:" fa";s:3:"231";s:3:" si";s:3:"232";s:3:" th";s:3:"233";s:3:"ad ";s:3:"234";s:3:"e m";s:3:"235";s:3:"eac";s:3:"236";s:3:"m m";s:3:"237";s:3:"n w";s:3:"238";s:3:"nob";s:3:"239";s:3:"orl";s:3:"240";s:3:"out";s:3:"241";s:3:"own";s:3:"242";s:3:"r s";s:3:"243";s:3:"r w";s:3:"244";s:3:"rib";s:3:"245";s:3:"rld";s:3:"246";s:3:"s w";s:3:"247";s:3:"ure";s:3:"248";s:3:"wn ";s:3:"249";s:3:" ow";s:3:"250";s:3:"a d";s:3:"251";s:3:"bad";s:3:"252";s:3:"ch ";s:3:"253";s:3:"fre";s:3:"254";s:3:"gs ";s:3:"255";s:3:"m k";s:3:"256";s:3:"nce";s:3:"257";s:3:"ngs";s:3:"258";s:3:"o f";s:3:"259";s:3:"obo";s:3:"260";s:3:"rea";s:3:"261";s:3:"sur";s:3:"262";s:3:"y o";s:3:"263";s:3:" ab";s:3:"264";s:3:" un";s:3:"265";s:3:"abo";s:3:"266";s:3:"ach";s:3:"267";s:3:"bou";s:3:"268";s:3:"d m";s:3:"269";s:3:"dat";s:3:"270";s:3:"e p";s:3:"271";s:3:"g w";s:3:"272";s:3:"hol";s:3:"273";s:3:"i m";s:3:"274";s:3:"i r";s:3:"275";s:3:"m f";s:3:"276";s:3:"m o";s:3:"277";s:3:"n o";s:3:"278";s:3:"now";s:3:"279";s:3:"ry ";s:3:"280";s:3:"s a";s:3:"281";s:3:"t o";s:3:"282";s:3:"tay";s:3:"283";s:3:"wet";s:3:"284";s:3:" ag";s:3:"285";s:3:" bo";s:3:"286";s:3:" da";s:3:"287";s:3:" pr";s:3:"288";s:3:"arr";s:3:"289";s:3:"ati";s:3:"290";s:3:"d d";s:3:"291";s:3:"d p";s:3:"292";s:3:"i g";s:3:"293";s:3:"i t";s:3:"294";s:3:"liv";s:3:"295";s:3:"ly ";s:3:"296";s:3:"n a";s:3:"297";s:3:"od ";s:3:"298";s:3:"ok ";s:3:"299";}s:6:"polish";a:300:{s:3:"ie ";s:1:"0";s:3:"nie";s:1:"1";s:3:"em ";s:1:"2";s:3:" ni";s:1:"3";s:3:" po";s:1:"4";s:3:" pr";s:1:"5";s:3:"dzi";s:1:"6";s:3:" na";s:1:"7";s:4:"że ";s:1:"8";s:3:"rze";s:1:"9";s:3:"na ";s:2:"10";s:4:"łem";s:2:"11";s:3:"wie";s:2:"12";s:3:" w ";s:2:"13";s:4:" że";s:2:"14";s:3:"go ";s:2:"15";s:3:" by";s:2:"16";s:3:"prz";s:2:"17";s:3:"owa";s:2:"18";s:4:"ię ";s:2:"19";s:3:" do";s:2:"20";s:3:" si";s:2:"21";s:3:"owi";s:2:"22";s:3:" pa";s:2:"23";s:3:" za";s:2:"24";s:3:"ch ";s:2:"25";s:3:"ego";s:2:"26";s:4:"ał ";s:2:"27";s:4:"się";s:2:"28";s:3:"ej ";s:2:"29";s:4:"wał";s:2:"30";s:3:"ym ";s:2:"31";s:3:"ani";s:2:"32";s:4:"ałe";s:2:"33";s:3:"to ";s:2:"34";s:3:" i ";s:2:"35";s:3:" to";s:2:"36";s:3:" te";s:2:"37";s:3:"e p";s:2:"38";s:3:" je";s:2:"39";s:3:" z ";s:2:"40";s:3:"czy";s:2:"41";s:4:"był";s:2:"42";s:3:"pan";s:2:"43";s:3:"sta";s:2:"44";s:3:"kie";s:2:"45";s:3:" ja";s:2:"46";s:3:"do ";s:2:"47";s:3:" ch";s:2:"48";s:3:" cz";s:2:"49";s:3:" wi";s:2:"50";s:4:"iał";s:2:"51";s:3:"a p";s:2:"52";s:3:"pow";s:2:"53";s:3:" mi";s:2:"54";s:3:"li ";s:2:"55";s:3:"eni";s:2:"56";s:3:"zie";s:2:"57";s:3:" ta";s:2:"58";s:3:" wa";s:2:"59";s:4:"ło ";s:2:"60";s:4:"ać ";s:2:"61";s:3:"dy ";s:2:"62";s:3:"ak ";s:2:"63";s:3:"e w";s:2:"64";s:3:" a ";s:2:"65";s:3:" od";s:2:"66";s:3:" st";s:2:"67";s:3:"nia";s:2:"68";s:3:"rzy";s:2:"69";s:3:"ied";s:2:"70";s:3:" kt";s:2:"71";s:3:"odz";s:2:"72";s:3:"cie";s:2:"73";s:3:"cze";s:2:"74";s:3:"ia ";s:2:"75";s:3:"iel";s:2:"76";s:4:"któ";s:2:"77";s:3:"o p";s:2:"78";s:4:"tór";s:2:"79";s:4:"ści";s:2:"80";s:3:" sp";s:2:"81";s:3:" wy";s:2:"82";s:3:"jak";s:2:"83";s:3:"tak";s:2:"84";s:3:"zy ";s:2:"85";s:3:" mo";s:2:"86";s:5:"ałę";s:2:"87";s:3:"pro";s:2:"88";s:3:"ski";s:2:"89";s:3:"tem";s:2:"90";s:5:"łęs";s:2:"91";s:3:" tr";s:2:"92";s:3:"e m";s:2:"93";s:3:"jes";s:2:"94";s:3:"my ";s:2:"95";s:3:" ro";s:2:"96";s:3:"edz";s:2:"97";s:3:"eli";s:2:"98";s:3:"iej";s:2:"99";s:3:" rz";s:3:"100";s:3:"a n";s:3:"101";s:3:"ale";s:3:"102";s:3:"an ";s:3:"103";s:3:"e s";s:3:"104";s:3:"est";s:3:"105";s:3:"le ";s:3:"106";s:3:"o s";s:3:"107";s:3:"i p";s:3:"108";s:3:"ki ";s:3:"109";s:3:" co";s:3:"110";s:3:"ada";s:3:"111";s:3:"czn";s:3:"112";s:3:"e t";s:3:"113";s:3:"e z";s:3:"114";s:3:"ent";s:3:"115";s:3:"ny ";s:3:"116";s:3:"pre";s:3:"117";s:4:"rzą";s:3:"118";s:3:"y s";s:3:"119";s:3:" ko";s:3:"120";s:3:" o ";s:3:"121";s:3:"ach";s:3:"122";s:3:"am ";s:3:"123";s:3:"e n";s:3:"124";s:3:"o t";s:3:"125";s:3:"oli";s:3:"126";s:3:"pod";s:3:"127";s:3:"zia";s:3:"128";s:3:" go";s:3:"129";s:3:" ka";s:3:"130";s:3:"by ";s:3:"131";s:3:"ieg";s:3:"132";s:3:"ier";s:3:"133";s:4:"noś";s:3:"134";s:3:"roz";s:3:"135";s:3:"spo";s:3:"136";s:3:"ych";s:3:"137";s:4:"ząd";s:3:"138";s:3:" mn";s:3:"139";s:3:"acz";s:3:"140";s:3:"adz";s:3:"141";s:3:"bie";s:3:"142";s:3:"cho";s:3:"143";s:3:"mni";s:3:"144";s:3:"o n";s:3:"145";s:3:"ost";s:3:"146";s:3:"pra";s:3:"147";s:3:"ze ";s:3:"148";s:4:"ła ";s:3:"149";s:3:" so";s:3:"150";s:3:"a m";s:3:"151";s:3:"cza";s:3:"152";s:3:"iem";s:3:"153";s:4:"ić ";s:3:"154";s:3:"obi";s:3:"155";s:4:"ył ";s:3:"156";s:4:"yło";s:3:"157";s:3:" mu";s:3:"158";s:4:" mó";s:3:"159";s:3:"a t";s:3:"160";s:3:"acj";s:3:"161";s:3:"ci ";s:3:"162";s:3:"e b";s:3:"163";s:3:"ich";s:3:"164";s:3:"kan";s:3:"165";s:3:"mi ";s:3:"166";s:3:"mie";s:3:"167";s:4:"ośc";s:3:"168";s:3:"row";s:3:"169";s:3:"zen";s:3:"170";s:3:"zyd";s:3:"171";s:3:" al";s:3:"172";s:3:" re";s:3:"173";s:3:"a w";s:3:"174";s:3:"den";s:3:"175";s:3:"edy";s:3:"176";s:4:"ił ";s:3:"177";s:3:"ko ";s:3:"178";s:3:"o w";s:3:"179";s:3:"rac";s:3:"180";s:4:"śmy";s:3:"181";s:3:" ma";s:3:"182";s:3:" ra";s:3:"183";s:3:" sz";s:3:"184";s:3:" ty";s:3:"185";s:3:"e j";s:3:"186";s:3:"isk";s:3:"187";s:3:"ji ";s:3:"188";s:3:"ka ";s:3:"189";s:3:"m s";s:3:"190";s:3:"no ";s:3:"191";s:3:"o z";s:3:"192";s:3:"rez";s:3:"193";s:3:"wa ";s:3:"194";s:4:"ów ";s:3:"195";s:4:"łow";s:3:"196";s:5:"ść ";s:3:"197";s:3:" ob";s:3:"198";s:3:"ech";s:3:"199";s:3:"ecz";s:3:"200";s:3:"ezy";s:3:"201";s:3:"i w";s:3:"202";s:3:"ja ";s:3:"203";s:3:"kon";s:3:"204";s:4:"mów";s:3:"205";s:3:"ne ";s:3:"206";s:3:"ni ";s:3:"207";s:3:"now";s:3:"208";s:3:"nym";s:3:"209";s:3:"pol";s:3:"210";s:3:"pot";s:3:"211";s:3:"yde";s:3:"212";s:3:" dl";s:3:"213";s:3:" sy";s:3:"214";s:3:"a s";s:3:"215";s:3:"aki";s:3:"216";s:3:"ali";s:3:"217";s:3:"dla";s:3:"218";s:3:"icz";s:3:"219";s:3:"ku ";s:3:"220";s:3:"ocz";s:3:"221";s:3:"st ";s:3:"222";s:3:"str";s:3:"223";s:3:"szy";s:3:"224";s:3:"trz";s:3:"225";s:3:"wia";s:3:"226";s:3:"y p";s:3:"227";s:3:"za ";s:3:"228";s:3:" wt";s:3:"229";s:3:"chc";s:3:"230";s:3:"esz";s:3:"231";s:3:"iec";s:3:"232";s:3:"im ";s:3:"233";s:3:"la ";s:3:"234";s:3:"o m";s:3:"235";s:3:"sa ";s:3:"236";s:4:"wać";s:3:"237";s:3:"y n";s:3:"238";s:3:"zac";s:3:"239";s:3:"zec";s:3:"240";s:3:" gd";s:3:"241";s:3:"a z";s:3:"242";s:3:"ard";s:3:"243";s:3:"co ";s:3:"244";s:3:"dar";s:3:"245";s:3:"e r";s:3:"246";s:3:"ien";s:3:"247";s:3:"m n";s:3:"248";s:3:"m w";s:3:"249";s:3:"mia";s:3:"250";s:4:"moż";s:3:"251";s:3:"raw";s:3:"252";s:3:"rdz";s:3:"253";s:3:"tan";s:3:"254";s:3:"ted";s:3:"255";s:3:"teg";s:3:"256";s:4:"wił";s:3:"257";s:3:"wte";s:3:"258";s:3:"y z";s:3:"259";s:3:"zna";s:3:"260";s:4:"zło";s:3:"261";s:3:"a r";s:3:"262";s:3:"awi";s:3:"263";s:3:"bar";s:3:"264";s:3:"cji";s:3:"265";s:4:"czą";s:3:"266";s:3:"dow";s:3:"267";s:4:"eż ";s:3:"268";s:3:"gdy";s:3:"269";s:3:"iek";s:3:"270";s:3:"je ";s:3:"271";s:3:"o d";s:3:"272";s:4:"tał";s:3:"273";s:3:"wal";s:3:"274";s:3:"wsz";s:3:"275";s:3:"zed";s:3:"276";s:4:"ówi";s:3:"277";s:4:"ęsa";s:3:"278";s:3:" ba";s:3:"279";s:3:" lu";s:3:"280";s:3:" wo";s:3:"281";s:3:"aln";s:3:"282";s:3:"arn";s:3:"283";s:3:"ba ";s:3:"284";s:3:"dzo";s:3:"285";s:3:"e c";s:3:"286";s:3:"hod";s:3:"287";s:3:"igi";s:3:"288";s:3:"lig";s:3:"289";s:3:"m p";s:3:"290";s:4:"myś";s:3:"291";s:3:"o c";s:3:"292";s:3:"oni";s:3:"293";s:3:"rel";s:3:"294";s:3:"sku";s:3:"295";s:3:"ste";s:3:"296";s:3:"y w";s:3:"297";s:3:"yst";s:3:"298";s:3:"z w";s:3:"299";}s:10:"portuguese";a:300:{s:3:"de ";s:1:"0";s:3:" de";s:1:"1";s:3:"os ";s:1:"2";s:3:"as ";s:1:"3";s:3:"que";s:1:"4";s:3:" co";s:1:"5";s:4:"ão ";s:1:"6";s:3:"o d";s:1:"7";s:3:" qu";s:1:"8";s:3:"ue ";s:1:"9";s:3:" a ";s:2:"10";s:3:"do ";s:2:"11";s:3:"ent";s:2:"12";s:3:" se";s:2:"13";s:3:"a d";s:2:"14";s:3:"s d";s:2:"15";s:3:"e a";s:2:"16";s:3:"es ";s:2:"17";s:3:" pr";s:2:"18";s:3:"ra ";s:2:"19";s:3:"da ";s:2:"20";s:3:" es";s:2:"21";s:3:" pa";s:2:"22";s:3:"to ";s:2:"23";s:3:" o ";s:2:"24";s:3:"em ";s:2:"25";s:3:"con";s:2:"26";s:3:"o p";s:2:"27";s:3:" do";s:2:"28";s:3:"est";s:2:"29";s:3:"nte";s:2:"30";s:5:"ção";s:2:"31";s:3:" da";s:2:"32";s:3:" re";s:2:"33";s:3:"ma ";s:2:"34";s:3:"par";s:2:"35";s:3:" te";s:2:"36";s:3:"ara";s:2:"37";s:3:"ida";s:2:"38";s:3:" e ";s:2:"39";s:3:"ade";s:2:"40";s:3:"is ";s:2:"41";s:3:" um";s:2:"42";s:3:" po";s:2:"43";s:3:"a a";s:2:"44";s:3:"a p";s:2:"45";s:3:"dad";s:2:"46";s:3:"no ";s:2:"47";s:3:"te ";s:2:"48";s:3:" no";s:2:"49";s:5:"açã";s:2:"50";s:3:"pro";s:2:"51";s:3:"al ";s:2:"52";s:3:"com";s:2:"53";s:3:"e d";s:2:"54";s:3:"s a";s:2:"55";s:3:" as";s:2:"56";s:3:"a c";s:2:"57";s:3:"er ";s:2:"58";s:3:"men";s:2:"59";s:3:"s e";s:2:"60";s:3:"ais";s:2:"61";s:3:"nto";s:2:"62";s:3:"res";s:2:"63";s:3:"a s";s:2:"64";s:3:"ado";s:2:"65";s:3:"ist";s:2:"66";s:3:"s p";s:2:"67";s:3:"tem";s:2:"68";s:3:"e c";s:2:"69";s:3:"e s";s:2:"70";s:3:"ia ";s:2:"71";s:3:"o s";s:2:"72";s:3:"o a";s:2:"73";s:3:"o c";s:2:"74";s:3:"e p";s:2:"75";s:3:"sta";s:2:"76";s:3:"ta ";s:2:"77";s:3:"tra";s:2:"78";s:3:"ura";s:2:"79";s:3:" di";s:2:"80";s:3:" pe";s:2:"81";s:3:"ar ";s:2:"82";s:3:"e e";s:2:"83";s:3:"ser";s:2:"84";s:3:"uma";s:2:"85";s:3:"mos";s:2:"86";s:3:"se ";s:2:"87";s:3:" ca";s:2:"88";s:3:"o e";s:2:"89";s:3:" na";s:2:"90";s:3:"a e";s:2:"91";s:3:"des";s:2:"92";s:3:"ont";s:2:"93";s:3:"por";s:2:"94";s:3:" in";s:2:"95";s:3:" ma";s:2:"96";s:3:"ect";s:2:"97";s:3:"o q";s:2:"98";s:3:"ria";s:2:"99";s:3:"s c";s:3:"100";s:3:"ste";s:3:"101";s:3:"ver";s:3:"102";s:3:"cia";s:3:"103";s:3:"dos";s:3:"104";s:3:"ica";s:3:"105";s:3:"str";s:3:"106";s:3:" ao";s:3:"107";s:3:" em";s:3:"108";s:3:"das";s:3:"109";s:3:"e t";s:3:"110";s:3:"ito";s:3:"111";s:3:"iza";s:3:"112";s:3:"pre";s:3:"113";s:3:"tos";s:3:"114";s:4:" nã";s:3:"115";s:3:"ada";s:3:"116";s:4:"não";s:3:"117";s:3:"ess";s:3:"118";s:3:"eve";s:3:"119";s:3:"or ";s:3:"120";s:3:"ran";s:3:"121";s:3:"s n";s:3:"122";s:3:"s t";s:3:"123";s:3:"tur";s:3:"124";s:3:" ac";s:3:"125";s:3:" fa";s:3:"126";s:3:"a r";s:3:"127";s:3:"ens";s:3:"128";s:3:"eri";s:3:"129";s:3:"na ";s:3:"130";s:3:"sso";s:3:"131";s:3:" si";s:3:"132";s:4:" é ";s:3:"133";s:3:"bra";s:3:"134";s:3:"esp";s:3:"135";s:3:"mo ";s:3:"136";s:3:"nos";s:3:"137";s:3:"ro ";s:3:"138";s:3:"um ";s:3:"139";s:3:"a n";s:3:"140";s:3:"ao ";s:3:"141";s:3:"ico";s:3:"142";s:3:"liz";s:3:"143";s:3:"min";s:3:"144";s:3:"o n";s:3:"145";s:3:"ons";s:3:"146";s:3:"pri";s:3:"147";s:3:"ten";s:3:"148";s:3:"tic";s:3:"149";s:4:"ões";s:3:"150";s:3:" tr";s:3:"151";s:3:"a m";s:3:"152";s:3:"aga";s:3:"153";s:3:"e n";s:3:"154";s:3:"ili";s:3:"155";s:3:"ime";s:3:"156";s:3:"m a";s:3:"157";s:3:"nci";s:3:"158";s:3:"nha";s:3:"159";s:3:"nta";s:3:"160";s:3:"spe";s:3:"161";s:3:"tiv";s:3:"162";s:3:"am ";s:3:"163";s:3:"ano";s:3:"164";s:3:"arc";s:3:"165";s:3:"ass";s:3:"166";s:3:"cer";s:3:"167";s:3:"e o";s:3:"168";s:3:"ece";s:3:"169";s:3:"emo";s:3:"170";s:3:"ga ";s:3:"171";s:3:"o m";s:3:"172";s:3:"rag";s:3:"173";s:3:"so ";s:3:"174";s:4:"são";s:3:"175";s:3:" au";s:3:"176";s:3:" os";s:3:"177";s:3:" sa";s:3:"178";s:3:"ali";s:3:"179";s:3:"ca ";s:3:"180";s:3:"ema";s:3:"181";s:3:"emp";s:3:"182";s:3:"ici";s:3:"183";s:3:"ido";s:3:"184";s:3:"inh";s:3:"185";s:3:"iss";s:3:"186";s:3:"l d";s:3:"187";s:3:"la ";s:3:"188";s:3:"lic";s:3:"189";s:3:"m c";s:3:"190";s:3:"mai";s:3:"191";s:3:"onc";s:3:"192";s:3:"pec";s:3:"193";s:3:"ram";s:3:"194";s:3:"s q";s:3:"195";s:3:" ci";s:3:"196";s:3:" en";s:3:"197";s:3:" fo";s:3:"198";s:3:"a o";s:3:"199";s:3:"ame";s:3:"200";s:3:"car";s:3:"201";s:3:"co ";s:3:"202";s:3:"der";s:3:"203";s:3:"eir";s:3:"204";s:3:"ho ";s:3:"205";s:3:"io ";s:3:"206";s:3:"om ";s:3:"207";s:3:"ora";s:3:"208";s:3:"r a";s:3:"209";s:3:"sen";s:3:"210";s:3:"ter";s:3:"211";s:3:" br";s:3:"212";s:3:" ex";s:3:"213";s:3:"a u";s:3:"214";s:3:"cul";s:3:"215";s:3:"dev";s:3:"216";s:3:"e u";s:3:"217";s:3:"ha ";s:3:"218";s:3:"mpr";s:3:"219";s:3:"nce";s:3:"220";s:3:"oca";s:3:"221";s:3:"ove";s:3:"222";s:3:"rio";s:3:"223";s:3:"s o";s:3:"224";s:3:"sa ";s:3:"225";s:3:"sem";s:3:"226";s:3:"tes";s:3:"227";s:3:"uni";s:3:"228";s:3:"ven";s:3:"229";s:4:"zaç";s:3:"230";s:5:"çõe";s:3:"231";s:3:" ad";s:3:"232";s:3:" al";s:3:"233";s:3:" an";s:3:"234";s:3:" mi";s:3:"235";s:3:" mo";s:3:"236";s:3:" ve";s:3:"237";s:4:" à ";s:3:"238";s:3:"a i";s:3:"239";s:3:"a q";s:3:"240";s:3:"ala";s:3:"241";s:3:"amo";s:3:"242";s:3:"bli";s:3:"243";s:3:"cen";s:3:"244";s:3:"col";s:3:"245";s:3:"cos";s:3:"246";s:3:"cto";s:3:"247";s:3:"e m";s:3:"248";s:3:"e v";s:3:"249";s:3:"ede";s:3:"250";s:4:"gás";s:3:"251";s:3:"ias";s:3:"252";s:3:"ita";s:3:"253";s:3:"iva";s:3:"254";s:3:"ndo";s:3:"255";s:3:"o t";s:3:"256";s:3:"ore";s:3:"257";s:3:"r d";s:3:"258";s:3:"ral";s:3:"259";s:3:"rea";s:3:"260";s:3:"s f";s:3:"261";s:3:"sid";s:3:"262";s:3:"tro";s:3:"263";s:3:"vel";s:3:"264";s:3:"vid";s:3:"265";s:4:"ás ";s:3:"266";s:3:" ap";s:3:"267";s:3:" ar";s:3:"268";s:3:" ce";s:3:"269";s:3:" ou";s:3:"270";s:4:" pú";s:3:"271";s:3:" so";s:3:"272";s:3:" vi";s:3:"273";s:3:"a f";s:3:"274";s:3:"act";s:3:"275";s:3:"arr";s:3:"276";s:3:"bil";s:3:"277";s:3:"cam";s:3:"278";s:3:"e f";s:3:"279";s:3:"e i";s:3:"280";s:3:"el ";s:3:"281";s:3:"for";s:3:"282";s:3:"lem";s:3:"283";s:3:"lid";s:3:"284";s:3:"lo ";s:3:"285";s:3:"m d";s:3:"286";s:3:"mar";s:3:"287";s:3:"nde";s:3:"288";s:3:"o o";s:3:"289";s:3:"omo";s:3:"290";s:3:"ort";s:3:"291";s:3:"per";s:3:"292";s:4:"púb";s:3:"293";s:3:"r u";s:3:"294";s:3:"rei";s:3:"295";s:3:"rem";s:3:"296";s:3:"ros";s:3:"297";s:3:"rre";s:3:"298";s:3:"ssi";s:3:"299";}s:8:"romanian";a:300:{s:3:" de";s:1:"0";s:4:" în";s:1:"1";s:3:"de ";s:1:"2";s:3:" a ";s:1:"3";s:3:"ul ";s:1:"4";s:3:" co";s:1:"5";s:4:"în ";s:1:"6";s:3:"re ";s:1:"7";s:3:"e d";s:1:"8";s:3:"ea ";s:1:"9";s:3:" di";s:2:"10";s:3:" pr";s:2:"11";s:3:"le ";s:2:"12";s:4:"şi ";s:2:"13";s:3:"are";s:2:"14";s:3:"at ";s:2:"15";s:3:"con";s:2:"16";s:3:"ui ";s:2:"17";s:4:" şi";s:2:"18";s:3:"i d";s:2:"19";s:3:"ii ";s:2:"20";s:3:" cu";s:2:"21";s:3:"e a";s:2:"22";s:3:"lui";s:2:"23";s:3:"ern";s:2:"24";s:3:"te ";s:2:"25";s:3:"cu ";s:2:"26";s:3:" la";s:2:"27";s:3:"a c";s:2:"28";s:4:"că ";s:2:"29";s:3:"din";s:2:"30";s:3:"e c";s:2:"31";s:3:"or ";s:2:"32";s:3:"ulu";s:2:"33";s:3:"ne ";s:2:"34";s:3:"ter";s:2:"35";s:3:"la ";s:2:"36";s:4:"să ";s:2:"37";s:3:"tat";s:2:"38";s:3:"tre";s:2:"39";s:3:" ac";s:2:"40";s:4:" să";s:2:"41";s:3:"est";s:2:"42";s:3:"st ";s:2:"43";s:4:"tă ";s:2:"44";s:3:" ca";s:2:"45";s:3:" ma";s:2:"46";s:3:" pe";s:2:"47";s:3:"cur";s:2:"48";s:3:"ist";s:2:"49";s:4:"mân";s:2:"50";s:3:"a d";s:2:"51";s:3:"i c";s:2:"52";s:3:"nat";s:2:"53";s:3:" ce";s:2:"54";s:3:"i a";s:2:"55";s:3:"ia ";s:2:"56";s:3:"in ";s:2:"57";s:3:"scu";s:2:"58";s:3:" mi";s:2:"59";s:3:"ato";s:2:"60";s:4:"aţi";s:2:"61";s:3:"ie ";s:2:"62";s:3:" re";s:2:"63";s:3:" se";s:2:"64";s:3:"a a";s:2:"65";s:3:"int";s:2:"66";s:3:"ntr";s:2:"67";s:3:"tru";s:2:"68";s:3:"uri";s:2:"69";s:4:"ă a";s:2:"70";s:3:" fo";s:2:"71";s:3:" pa";s:2:"72";s:3:"ate";s:2:"73";s:3:"ini";s:2:"74";s:3:"tul";s:2:"75";s:3:"ent";s:2:"76";s:3:"min";s:2:"77";s:3:"pre";s:2:"78";s:3:"pro";s:2:"79";s:3:"a p";s:2:"80";s:3:"e p";s:2:"81";s:3:"e s";s:2:"82";s:3:"ei ";s:2:"83";s:4:"nă ";s:2:"84";s:3:"par";s:2:"85";s:3:"rna";s:2:"86";s:3:"rul";s:2:"87";s:3:"tor";s:2:"88";s:3:" in";s:2:"89";s:3:" ro";s:2:"90";s:3:" tr";s:2:"91";s:3:" un";s:2:"92";s:3:"al ";s:2:"93";s:3:"ale";s:2:"94";s:3:"art";s:2:"95";s:3:"ce ";s:2:"96";s:3:"e e";s:2:"97";s:4:"e î";s:2:"98";s:3:"fos";s:2:"99";s:3:"ita";s:3:"100";s:3:"nte";s:3:"101";s:4:"omâ";s:3:"102";s:3:"ost";s:3:"103";s:3:"rom";s:3:"104";s:3:"ru ";s:3:"105";s:3:"str";s:3:"106";s:3:"ver";s:3:"107";s:3:" ex";s:3:"108";s:3:" na";s:3:"109";s:3:"a f";s:3:"110";s:3:"lor";s:3:"111";s:3:"nis";s:3:"112";s:3:"rea";s:3:"113";s:3:"rit";s:3:"114";s:3:" al";s:3:"115";s:3:" eu";s:3:"116";s:3:" no";s:3:"117";s:3:"ace";s:3:"118";s:3:"cer";s:3:"119";s:3:"ile";s:3:"120";s:3:"nal";s:3:"121";s:3:"pri";s:3:"122";s:3:"ri ";s:3:"123";s:3:"sta";s:3:"124";s:3:"ste";s:3:"125";s:4:"ţie";s:3:"126";s:3:" au";s:3:"127";s:3:" da";s:3:"128";s:3:" ju";s:3:"129";s:3:" po";s:3:"130";s:3:"ar ";s:3:"131";s:3:"au ";s:3:"132";s:3:"ele";s:3:"133";s:3:"ere";s:3:"134";s:3:"eri";s:3:"135";s:3:"ina";s:3:"136";s:3:"n a";s:3:"137";s:3:"n c";s:3:"138";s:3:"res";s:3:"139";s:3:"se ";s:3:"140";s:3:"t a";s:3:"141";s:3:"tea";s:3:"142";s:4:" că";s:3:"143";s:3:" do";s:3:"144";s:3:" fi";s:3:"145";s:3:"a s";s:3:"146";s:4:"ată";s:3:"147";s:3:"com";s:3:"148";s:4:"e ş";s:3:"149";s:3:"eur";s:3:"150";s:3:"guv";s:3:"151";s:3:"i s";s:3:"152";s:3:"ice";s:3:"153";s:3:"ili";s:3:"154";s:3:"na ";s:3:"155";s:3:"rec";s:3:"156";s:3:"rep";s:3:"157";s:3:"ril";s:3:"158";s:3:"rne";s:3:"159";s:3:"rti";s:3:"160";s:3:"uro";s:3:"161";s:3:"uve";s:3:"162";s:4:"ă p";s:3:"163";s:3:" ar";s:3:"164";s:3:" o ";s:3:"165";s:3:" su";s:3:"166";s:3:" vi";s:3:"167";s:3:"dec";s:3:"168";s:3:"dre";s:3:"169";s:3:"oar";s:3:"170";s:3:"ons";s:3:"171";s:3:"pe ";s:3:"172";s:3:"rii";s:3:"173";s:3:" ad";s:3:"174";s:3:" ge";s:3:"175";s:3:"a m";s:3:"176";s:3:"a r";s:3:"177";s:3:"ain";s:3:"178";s:3:"ali";s:3:"179";s:3:"car";s:3:"180";s:3:"cat";s:3:"181";s:3:"ecu";s:3:"182";s:3:"ene";s:3:"183";s:3:"ept";s:3:"184";s:3:"ext";s:3:"185";s:3:"ilo";s:3:"186";s:3:"iu ";s:3:"187";s:3:"n p";s:3:"188";s:3:"ori";s:3:"189";s:3:"sec";s:3:"190";s:3:"u p";s:3:"191";s:3:"une";s:3:"192";s:4:"ă c";s:3:"193";s:4:"şti";s:3:"194";s:4:"ţia";s:3:"195";s:3:" ch";s:3:"196";s:3:" gu";s:3:"197";s:3:"ai ";s:3:"198";s:3:"ani";s:3:"199";s:3:"cea";s:3:"200";s:3:"e f";s:3:"201";s:3:"isc";s:3:"202";s:3:"l a";s:3:"203";s:3:"lic";s:3:"204";s:3:"liu";s:3:"205";s:3:"mar";s:3:"206";s:3:"nic";s:3:"207";s:3:"nt ";s:3:"208";s:3:"nul";s:3:"209";s:3:"ris";s:3:"210";s:3:"t c";s:3:"211";s:3:"t p";s:3:"212";s:3:"tic";s:3:"213";s:3:"tid";s:3:"214";s:3:"u a";s:3:"215";s:3:"ucr";s:3:"216";s:3:" as";s:3:"217";s:3:" dr";s:3:"218";s:3:" fa";s:3:"219";s:3:" nu";s:3:"220";s:3:" pu";s:3:"221";s:3:" to";s:3:"222";s:3:"cra";s:3:"223";s:3:"dis";s:3:"224";s:4:"enţ";s:3:"225";s:3:"esc";s:3:"226";s:3:"gen";s:3:"227";s:3:"it ";s:3:"228";s:3:"ivi";s:3:"229";s:3:"l d";s:3:"230";s:3:"n d";s:3:"231";s:3:"nd ";s:3:"232";s:3:"nu ";s:3:"233";s:3:"ond";s:3:"234";s:3:"pen";s:3:"235";s:3:"ral";s:3:"236";s:3:"riv";s:3:"237";s:3:"rte";s:3:"238";s:3:"sti";s:3:"239";s:3:"t d";s:3:"240";s:3:"ta ";s:3:"241";s:3:"to ";s:3:"242";s:3:"uni";s:3:"243";s:3:"xte";s:3:"244";s:4:"ând";s:3:"245";s:4:"îns";s:3:"246";s:4:"ă s";s:3:"247";s:3:" bl";s:3:"248";s:3:" st";s:3:"249";s:3:" uc";s:3:"250";s:3:"a b";s:3:"251";s:3:"a i";s:3:"252";s:3:"a l";s:3:"253";s:3:"air";s:3:"254";s:3:"ast";s:3:"255";s:3:"bla";s:3:"256";s:3:"bri";s:3:"257";s:3:"che";s:3:"258";s:3:"duc";s:3:"259";s:3:"dul";s:3:"260";s:3:"e m";s:3:"261";s:3:"eas";s:3:"262";s:3:"edi";s:3:"263";s:3:"esp";s:3:"264";s:3:"i l";s:3:"265";s:3:"i p";s:3:"266";s:3:"ica";s:3:"267";s:4:"ică";s:3:"268";s:3:"ir ";s:3:"269";s:3:"iun";s:3:"270";s:3:"jud";s:3:"271";s:3:"lai";s:3:"272";s:3:"lul";s:3:"273";s:3:"mai";s:3:"274";s:3:"men";s:3:"275";s:3:"ni ";s:3:"276";s:3:"pus";s:3:"277";s:3:"put";s:3:"278";s:3:"ra ";s:3:"279";s:3:"rai";s:3:"280";s:3:"rop";s:3:"281";s:3:"sil";s:3:"282";s:3:"ti ";s:3:"283";s:3:"tra";s:3:"284";s:3:"u s";s:3:"285";s:3:"ua ";s:3:"286";s:3:"ude";s:3:"287";s:3:"urs";s:3:"288";s:4:"ân ";s:3:"289";s:4:"înt";s:3:"290";s:5:"ţă ";s:3:"291";s:3:" lu";s:3:"292";s:3:" mo";s:3:"293";s:3:" s ";s:3:"294";s:3:" sa";s:3:"295";s:3:" sc";s:3:"296";s:3:"a u";s:3:"297";s:3:"an ";s:3:"298";s:3:"atu";s:3:"299";}s:7:"russian";a:300:{s:5:" на";s:1:"0";s:5:" пр";s:1:"1";s:5:"то ";s:1:"2";s:5:" не";s:1:"3";s:5:"ли ";s:1:"4";s:5:" по";s:1:"5";s:5:"но ";s:1:"6";s:4:" в ";s:1:"7";s:5:"на ";s:1:"8";s:5:"ть ";s:1:"9";s:5:"не ";s:2:"10";s:4:" и ";s:2:"11";s:5:" ко";s:2:"12";s:5:"ом ";s:2:"13";s:6:"про";s:2:"14";s:5:" то";s:2:"15";s:5:"их ";s:2:"16";s:5:" ка";s:2:"17";s:6:"ать";s:2:"18";s:6:"ото";s:2:"19";s:5:" за";s:2:"20";s:5:"ие ";s:2:"21";s:6:"ова";s:2:"22";s:6:"тел";s:2:"23";s:6:"тор";s:2:"24";s:5:" де";s:2:"25";s:5:"ой ";s:2:"26";s:6:"сти";s:2:"27";s:5:" от";s:2:"28";s:5:"ах ";s:2:"29";s:5:"ми ";s:2:"30";s:6:"стр";s:2:"31";s:5:" бе";s:2:"32";s:5:" во";s:2:"33";s:5:" ра";s:2:"34";s:5:"ая ";s:2:"35";s:6:"ват";s:2:"36";s:5:"ей ";s:2:"37";s:5:"ет ";s:2:"38";s:5:"же ";s:2:"39";s:6:"иче";s:2:"40";s:5:"ия ";s:2:"41";s:5:"ов ";s:2:"42";s:6:"сто";s:2:"43";s:5:" об";s:2:"44";s:6:"вер";s:2:"45";s:5:"го ";s:2:"46";s:5:"и в";s:2:"47";s:5:"и п";s:2:"48";s:5:"и с";s:2:"49";s:5:"ии ";s:2:"50";s:6:"ист";s:2:"51";s:5:"о в";s:2:"52";s:6:"ост";s:2:"53";s:6:"тра";s:2:"54";s:5:" те";s:2:"55";s:6:"ели";s:2:"56";s:6:"ере";s:2:"57";s:6:"кот";s:2:"58";s:6:"льн";s:2:"59";s:6:"ник";s:2:"60";s:6:"нти";s:2:"61";s:5:"о с";s:2:"62";s:6:"рор";s:2:"63";s:6:"ств";s:2:"64";s:6:"чес";s:2:"65";s:5:" бо";s:2:"66";s:5:" ве";s:2:"67";s:5:" да";s:2:"68";s:5:" ин";s:2:"69";s:5:" но";s:2:"70";s:4:" с ";s:2:"71";s:5:" со";s:2:"72";s:5:" сп";s:2:"73";s:5:" ст";s:2:"74";s:5:" чт";s:2:"75";s:6:"али";s:2:"76";s:6:"ами";s:2:"77";s:6:"вид";s:2:"78";s:6:"дет";s:2:"79";s:5:"е н";s:2:"80";s:6:"ель";s:2:"81";s:6:"еск";s:2:"82";s:6:"ест";s:2:"83";s:6:"зал";s:2:"84";s:5:"и н";s:2:"85";s:6:"ива";s:2:"86";s:6:"кон";s:2:"87";s:6:"ого";s:2:"88";s:6:"одн";s:2:"89";s:6:"ожн";s:2:"90";s:6:"оль";s:2:"91";s:6:"ори";s:2:"92";s:6:"ров";s:2:"93";s:6:"ско";s:2:"94";s:5:"ся ";s:2:"95";s:6:"тер";s:2:"96";s:6:"что";s:2:"97";s:5:" мо";s:2:"98";s:5:" са";s:2:"99";s:5:" эт";s:3:"100";s:6:"ант";s:3:"101";s:6:"все";s:3:"102";s:6:"ерр";s:3:"103";s:6:"есл";s:3:"104";s:6:"иде";s:3:"105";s:6:"ина";s:3:"106";s:6:"ино";s:3:"107";s:6:"иро";s:3:"108";s:6:"ите";s:3:"109";s:5:"ка ";s:3:"110";s:5:"ко ";s:3:"111";s:6:"кол";s:3:"112";s:6:"ком";s:3:"113";s:5:"ла ";s:3:"114";s:6:"ния";s:3:"115";s:5:"о т";s:3:"116";s:6:"оло";s:3:"117";s:6:"ран";s:3:"118";s:6:"ред";s:3:"119";s:5:"сь ";s:3:"120";s:6:"тив";s:3:"121";s:6:"тич";s:3:"122";s:5:"ых ";s:3:"123";s:5:" ви";s:3:"124";s:5:" вс";s:3:"125";s:5:" го";s:3:"126";s:5:" ма";s:3:"127";s:5:" сл";s:3:"128";s:6:"ако";s:3:"129";s:6:"ани";s:3:"130";s:6:"аст";s:3:"131";s:6:"без";s:3:"132";s:6:"дел";s:3:"133";s:5:"е д";s:3:"134";s:5:"е п";s:3:"135";s:5:"ем ";s:3:"136";s:6:"жно";s:3:"137";s:5:"и д";s:3:"138";s:6:"ика";s:3:"139";s:6:"каз";s:3:"140";s:6:"как";s:3:"141";s:5:"ки ";s:3:"142";s:6:"нос";s:3:"143";s:5:"о н";s:3:"144";s:6:"опа";s:3:"145";s:6:"при";s:3:"146";s:6:"рро";s:3:"147";s:6:"ски";s:3:"148";s:5:"ти ";s:3:"149";s:6:"тов";s:3:"150";s:5:"ые ";s:3:"151";s:5:" вы";s:3:"152";s:5:" до";s:3:"153";s:5:" ме";s:3:"154";s:5:" ни";s:3:"155";s:5:" од";s:3:"156";s:5:" ро";s:3:"157";s:5:" св";s:3:"158";s:5:" чи";s:3:"159";s:5:"а н";s:3:"160";s:6:"ает";s:3:"161";s:6:"аза";s:3:"162";s:6:"ате";s:3:"163";s:6:"бес";s:3:"164";s:5:"в п";s:3:"165";s:5:"ва ";s:3:"166";s:5:"е в";s:3:"167";s:5:"е м";s:3:"168";s:5:"е с";s:3:"169";s:5:"ез ";s:3:"170";s:6:"ени";s:3:"171";s:5:"за ";s:3:"172";s:6:"зна";s:3:"173";s:6:"ини";s:3:"174";s:6:"кам";s:3:"175";s:6:"ках";s:3:"176";s:6:"кто";s:3:"177";s:6:"лов";s:3:"178";s:6:"мер";s:3:"179";s:6:"мож";s:3:"180";s:6:"нал";s:3:"181";s:6:"ниц";s:3:"182";s:5:"ны ";s:3:"183";s:6:"ным";s:3:"184";s:6:"ора";s:3:"185";s:6:"оро";s:3:"186";s:5:"от ";s:3:"187";s:6:"пор";s:3:"188";s:6:"рав";s:3:"189";s:6:"рес";s:3:"190";s:6:"рис";s:3:"191";s:6:"рос";s:3:"192";s:6:"ска";s:3:"193";s:5:"т н";s:3:"194";s:6:"том";s:3:"195";s:6:"чит";s:3:"196";s:6:"шко";s:3:"197";s:5:" бы";s:3:"198";s:4:" о ";s:3:"199";s:5:" тр";s:3:"200";s:5:" уж";s:3:"201";s:5:" чу";s:3:"202";s:5:" шк";s:3:"203";s:5:"а б";s:3:"204";s:5:"а в";s:3:"205";s:5:"а р";s:3:"206";s:6:"аби";s:3:"207";s:6:"ала";s:3:"208";s:6:"ало";s:3:"209";s:6:"аль";s:3:"210";s:6:"анн";s:3:"211";s:6:"ати";s:3:"212";s:6:"бин";s:3:"213";s:6:"вес";s:3:"214";s:6:"вно";s:3:"215";s:5:"во ";s:3:"216";s:6:"вши";s:3:"217";s:6:"дал";s:3:"218";s:6:"дат";s:3:"219";s:6:"дно";s:3:"220";s:5:"е з";s:3:"221";s:6:"его";s:3:"222";s:6:"еле";s:3:"223";s:6:"енн";s:3:"224";s:6:"ент";s:3:"225";s:6:"ете";s:3:"226";s:5:"и о";s:3:"227";s:6:"или";s:3:"228";s:6:"ись";s:3:"229";s:5:"ит ";s:3:"230";s:6:"ици";s:3:"231";s:6:"ков";s:3:"232";s:6:"лен";s:3:"233";s:6:"льк";s:3:"234";s:6:"мен";s:3:"235";s:5:"мы ";s:3:"236";s:6:"нет";s:3:"237";s:5:"ни ";s:3:"238";s:6:"нны";s:3:"239";s:6:"ног";s:3:"240";s:6:"ной";s:3:"241";s:6:"ном";s:3:"242";s:5:"о п";s:3:"243";s:6:"обн";s:3:"244";s:6:"ове";s:3:"245";s:6:"овн";s:3:"246";s:6:"оры";s:3:"247";s:6:"пер";s:3:"248";s:5:"по ";s:3:"249";s:6:"пра";s:3:"250";s:6:"пре";s:3:"251";s:6:"раз";s:3:"252";s:6:"роп";s:3:"253";s:5:"ры ";s:3:"254";s:5:"се ";s:3:"255";s:6:"сли";s:3:"256";s:6:"сов";s:3:"257";s:6:"тре";s:3:"258";s:6:"тся";s:3:"259";s:6:"уро";s:3:"260";s:6:"цел";s:3:"261";s:6:"чно";s:3:"262";s:5:"ь в";s:3:"263";s:6:"ько";s:3:"264";s:6:"ьно";s:3:"265";s:6:"это";s:3:"266";s:5:"ют ";s:3:"267";s:5:"я н";s:3:"268";s:5:" ан";s:3:"269";s:5:" ес";s:3:"270";s:5:" же";s:3:"271";s:5:" из";s:3:"272";s:5:" кт";s:3:"273";s:5:" ми";s:3:"274";s:5:" мы";s:3:"275";s:5:" пе";s:3:"276";s:5:" се";s:3:"277";s:5:" це";s:3:"278";s:5:"а м";s:3:"279";s:5:"а п";s:3:"280";s:5:"а т";s:3:"281";s:6:"авш";s:3:"282";s:6:"аже";s:3:"283";s:5:"ак ";s:3:"284";s:5:"ал ";s:3:"285";s:6:"але";s:3:"286";s:6:"ане";s:3:"287";s:6:"ачи";s:3:"288";s:6:"ают";s:3:"289";s:6:"бна";s:3:"290";s:6:"бол";s:3:"291";s:5:"бы ";s:3:"292";s:5:"в и";s:3:"293";s:5:"в с";s:3:"294";s:6:"ван";s:3:"295";s:6:"гра";s:3:"296";s:6:"даж";s:3:"297";s:6:"ден";s:3:"298";s:5:"е к";s:3:"299";}s:7:"serbian";a:300:{s:5:" на";s:1:"0";s:5:" је";s:1:"1";s:5:" по";s:1:"2";s:5:"је ";s:1:"3";s:4:" и ";s:1:"4";s:5:" не";s:1:"5";s:5:" пр";s:1:"6";s:5:"га ";s:1:"7";s:5:" св";s:1:"8";s:5:"ог ";s:1:"9";s:5:"а с";s:2:"10";s:5:"их ";s:2:"11";s:5:"на ";s:2:"12";s:6:"кој";s:2:"13";s:6:"ога";s:2:"14";s:4:" у ";s:2:"15";s:5:"а п";s:2:"16";s:5:"не ";s:2:"17";s:5:"ни ";s:2:"18";s:5:"ти ";s:2:"19";s:5:" да";s:2:"20";s:5:"ом ";s:2:"21";s:5:" ве";s:2:"22";s:5:" ср";s:2:"23";s:5:"и с";s:2:"24";s:6:"ско";s:2:"25";s:5:" об";s:2:"26";s:5:"а н";s:2:"27";s:5:"да ";s:2:"28";s:5:"е н";s:2:"29";s:5:"но ";s:2:"30";s:6:"ног";s:2:"31";s:5:"о ј";s:2:"32";s:5:"ој ";s:2:"33";s:5:" за";s:2:"34";s:5:"ва ";s:2:"35";s:5:"е с";s:2:"36";s:5:"и п";s:2:"37";s:5:"ма ";s:2:"38";s:6:"ник";s:2:"39";s:6:"обр";s:2:"40";s:6:"ова";s:2:"41";s:5:" ко";s:2:"42";s:5:"а и";s:2:"43";s:6:"диј";s:2:"44";s:5:"е п";s:2:"45";s:5:"ка ";s:2:"46";s:5:"ко ";s:2:"47";s:6:"ког";s:2:"48";s:6:"ост";s:2:"49";s:6:"све";s:2:"50";s:6:"ств";s:2:"51";s:6:"сти";s:2:"52";s:6:"тра";s:2:"53";s:6:"еди";s:2:"54";s:6:"има";s:2:"55";s:6:"пок";s:2:"56";s:6:"пра";s:2:"57";s:6:"раз";s:2:"58";s:5:"те ";s:2:"59";s:5:" бо";s:2:"60";s:5:" ви";s:2:"61";s:5:" са";s:2:"62";s:6:"аво";s:2:"63";s:6:"бра";s:2:"64";s:6:"гос";s:2:"65";s:5:"е и";s:2:"66";s:6:"ели";s:2:"67";s:6:"ени";s:2:"68";s:5:"за ";s:2:"69";s:6:"ики";s:2:"70";s:5:"ио ";s:2:"71";s:6:"пре";s:2:"72";s:6:"рав";s:2:"73";s:6:"рад";s:2:"74";s:5:"у с";s:2:"75";s:5:"ју ";s:2:"76";s:5:"ња ";s:2:"77";s:5:" би";s:2:"78";s:5:" до";s:2:"79";s:5:" ст";s:2:"80";s:6:"аст";s:2:"81";s:6:"бој";s:2:"82";s:6:"ебо";s:2:"83";s:5:"и н";s:2:"84";s:5:"им ";s:2:"85";s:5:"ку ";s:2:"86";s:6:"лан";s:2:"87";s:6:"неб";s:2:"88";s:6:"ово";s:2:"89";s:6:"ого";s:2:"90";s:6:"осл";s:2:"91";s:6:"ојш";s:2:"92";s:6:"пед";s:2:"93";s:6:"стр";s:2:"94";s:6:"час";s:2:"95";s:5:" го";s:2:"96";s:5:" кр";s:2:"97";s:5:" мо";s:2:"98";s:5:" чл";s:2:"99";s:5:"а м";s:3:"100";s:5:"а о";s:3:"101";s:6:"ако";s:3:"102";s:6:"ача";s:3:"103";s:6:"вел";s:3:"104";s:6:"вет";s:3:"105";s:6:"вог";s:3:"106";s:6:"еда";s:3:"107";s:6:"ист";s:3:"108";s:6:"ити";s:3:"109";s:6:"ије";s:3:"110";s:6:"око";s:3:"111";s:6:"сло";s:3:"112";s:6:"срб";s:3:"113";s:6:"чла";s:3:"114";s:5:" бе";s:3:"115";s:5:" ос";s:3:"116";s:5:" от";s:3:"117";s:5:" ре";s:3:"118";s:5:" се";s:3:"119";s:5:"а в";s:3:"120";s:5:"ан ";s:3:"121";s:6:"бог";s:3:"122";s:6:"бро";s:3:"123";s:6:"вен";s:3:"124";s:6:"гра";s:3:"125";s:5:"е о";s:3:"126";s:6:"ика";s:3:"127";s:6:"ија";s:3:"128";s:6:"ких";s:3:"129";s:6:"ком";s:3:"130";s:5:"ли ";s:3:"131";s:5:"ну ";s:3:"132";s:6:"ота";s:3:"133";s:6:"ојн";s:3:"134";s:6:"под";s:3:"135";s:6:"рбс";s:3:"136";s:6:"ред";s:3:"137";s:6:"рој";s:3:"138";s:5:"са ";s:3:"139";s:6:"сни";s:3:"140";s:6:"тач";s:3:"141";s:6:"тва";s:3:"142";s:5:"ја ";s:3:"143";s:5:"ји ";s:3:"144";s:5:" ка";s:3:"145";s:5:" ов";s:3:"146";s:5:" тр";s:3:"147";s:5:"а ј";s:3:"148";s:6:"ави";s:3:"149";s:5:"аз ";s:3:"150";s:6:"ано";s:3:"151";s:6:"био";s:3:"152";s:6:"вик";s:3:"153";s:5:"во ";s:3:"154";s:6:"гов";s:3:"155";s:6:"дни";s:3:"156";s:5:"е ч";s:3:"157";s:6:"его";s:3:"158";s:5:"и о";s:3:"159";s:6:"ива";s:3:"160";s:6:"иво";s:3:"161";s:5:"ик ";s:3:"162";s:6:"ине";s:3:"163";s:6:"ини";s:3:"164";s:6:"ипе";s:3:"165";s:6:"кип";s:3:"166";s:6:"лик";s:3:"167";s:5:"ло ";s:3:"168";s:6:"наш";s:3:"169";s:6:"нос";s:3:"170";s:5:"о т";s:3:"171";s:5:"од ";s:3:"172";s:6:"оди";s:3:"173";s:6:"она";s:3:"174";s:6:"оји";s:3:"175";s:6:"поч";s:3:"176";s:6:"про";s:3:"177";s:5:"ра ";s:3:"178";s:6:"рис";s:3:"179";s:6:"род";s:3:"180";s:6:"рст";s:3:"181";s:5:"се ";s:3:"182";s:6:"спо";s:3:"183";s:6:"ста";s:3:"184";s:6:"тић";s:3:"185";s:5:"у д";s:3:"186";s:5:"у н";s:3:"187";s:5:"у о";s:3:"188";s:6:"чин";s:3:"189";s:5:"ша ";s:3:"190";s:6:"јед";s:3:"191";s:6:"јни";s:3:"192";s:5:"ће ";s:3:"193";s:4:" м ";s:3:"194";s:5:" ме";s:3:"195";s:5:" ни";s:3:"196";s:5:" он";s:3:"197";s:5:" па";s:3:"198";s:5:" сл";s:3:"199";s:5:" те";s:3:"200";s:5:"а у";s:3:"201";s:6:"ава";s:3:"202";s:6:"аве";s:3:"203";s:6:"авн";s:3:"204";s:6:"ана";s:3:"205";s:5:"ао ";s:3:"206";s:6:"ати";s:3:"207";s:6:"аци";s:3:"208";s:6:"ају";s:3:"209";s:6:"ања";s:3:"210";s:6:"бск";s:3:"211";s:6:"вор";s:3:"212";s:6:"вос";s:3:"213";s:6:"вск";s:3:"214";s:6:"дин";s:3:"215";s:5:"е у";s:3:"216";s:6:"едн";s:3:"217";s:6:"ези";s:3:"218";s:6:"ека";s:3:"219";s:6:"ено";s:3:"220";s:6:"ето";s:3:"221";s:6:"ења";s:3:"222";s:6:"жив";s:3:"223";s:5:"и г";s:3:"224";s:5:"и и";s:3:"225";s:5:"и к";s:3:"226";s:5:"и т";s:3:"227";s:6:"ику";s:3:"228";s:6:"ичк";s:3:"229";s:5:"ки ";s:3:"230";s:6:"крс";s:3:"231";s:5:"ла ";s:3:"232";s:6:"лав";s:3:"233";s:6:"лит";s:3:"234";s:5:"ме ";s:3:"235";s:6:"мен";s:3:"236";s:6:"нац";s:3:"237";s:5:"о н";s:3:"238";s:5:"о п";s:3:"239";s:5:"о у";s:3:"240";s:6:"одн";s:3:"241";s:6:"оли";s:3:"242";s:6:"орн";s:3:"243";s:6:"осн";s:3:"244";s:6:"осп";s:3:"245";s:6:"оче";s:3:"246";s:6:"пск";s:3:"247";s:6:"реч";s:3:"248";s:6:"рпс";s:3:"249";s:6:"сво";s:3:"250";s:6:"ски";s:3:"251";s:6:"сла";s:3:"252";s:6:"срп";s:3:"253";s:5:"су ";s:3:"254";s:5:"та ";s:3:"255";s:6:"тав";s:3:"256";s:6:"тве";s:3:"257";s:5:"у б";s:3:"258";s:6:"јез";s:3:"259";s:5:"ћи ";s:3:"260";s:5:" ен";s:3:"261";s:5:" жи";s:3:"262";s:5:" им";s:3:"263";s:5:" му";s:3:"264";s:5:" од";s:3:"265";s:5:" су";s:3:"266";s:5:" та";s:3:"267";s:5:" хр";s:3:"268";s:5:" ча";s:3:"269";s:5:" шт";s:3:"270";s:5:" ње";s:3:"271";s:5:"а д";s:3:"272";s:5:"а з";s:3:"273";s:5:"а к";s:3:"274";s:5:"а т";s:3:"275";s:6:"аду";s:3:"276";s:6:"ало";s:3:"277";s:6:"ани";s:3:"278";s:6:"асо";s:3:"279";s:6:"ван";s:3:"280";s:6:"вач";s:3:"281";s:6:"вањ";s:3:"282";s:6:"вед";s:3:"283";s:5:"ви ";s:3:"284";s:6:"вно";s:3:"285";s:6:"вот";s:3:"286";s:6:"вој";s:3:"287";s:5:"ву ";s:3:"288";s:6:"доб";s:3:"289";s:6:"дру";s:3:"290";s:6:"дсе";s:3:"291";s:5:"ду ";s:3:"292";s:5:"е б";s:3:"293";s:5:"е д";s:3:"294";s:5:"е м";s:3:"295";s:5:"ем ";s:3:"296";s:6:"ема";s:3:"297";s:6:"ент";s:3:"298";s:6:"енц";s:3:"299";}s:6:"slovak";a:300:{s:3:" pr";s:1:"0";s:3:" po";s:1:"1";s:3:" ne";s:1:"2";s:3:" a ";s:1:"3";s:3:"ch ";s:1:"4";s:3:" na";s:1:"5";s:3:" je";s:1:"6";s:4:"ní ";s:1:"7";s:3:"je ";s:1:"8";s:3:" do";s:1:"9";s:3:"na ";s:2:"10";s:3:"ova";s:2:"11";s:3:" v ";s:2:"12";s:3:"to ";s:2:"13";s:3:"ho ";s:2:"14";s:3:"ou ";s:2:"15";s:3:" to";s:2:"16";s:3:"ick";s:2:"17";s:3:"ter";s:2:"18";s:4:"že ";s:2:"19";s:3:" st";s:2:"20";s:3:" za";s:2:"21";s:3:"ost";s:2:"22";s:4:"ých";s:2:"23";s:3:" se";s:2:"24";s:3:"pro";s:2:"25";s:3:" te";s:2:"26";s:3:"e s";s:2:"27";s:4:" že";s:2:"28";s:3:"a p";s:2:"29";s:3:" kt";s:2:"30";s:3:"pre";s:2:"31";s:3:" by";s:2:"32";s:3:" o ";s:2:"33";s:3:"se ";s:2:"34";s:3:"kon";s:2:"35";s:4:" př";s:2:"36";s:3:"a s";s:2:"37";s:4:"né ";s:2:"38";s:4:"ně ";s:2:"39";s:3:"sti";s:2:"40";s:3:"ako";s:2:"41";s:3:"ist";s:2:"42";s:3:"mu ";s:2:"43";s:3:"ame";s:2:"44";s:3:"ent";s:2:"45";s:3:"ky ";s:2:"46";s:3:"la ";s:2:"47";s:3:"pod";s:2:"48";s:3:" ve";s:2:"49";s:3:" ob";s:2:"50";s:3:"om ";s:2:"51";s:3:"vat";s:2:"52";s:3:" ko";s:2:"53";s:3:"sta";s:2:"54";s:3:"em ";s:2:"55";s:3:"le ";s:2:"56";s:3:"a v";s:2:"57";s:3:"by ";s:2:"58";s:3:"e p";s:2:"59";s:3:"ko ";s:2:"60";s:3:"eri";s:2:"61";s:3:"kte";s:2:"62";s:3:"sa ";s:2:"63";s:4:"ého";s:2:"64";s:3:"e v";s:2:"65";s:3:"mer";s:2:"66";s:3:"tel";s:2:"67";s:3:" ak";s:2:"68";s:3:" sv";s:2:"69";s:4:" zá";s:2:"70";s:3:"hla";s:2:"71";s:3:"las";s:2:"72";s:3:"lo ";s:2:"73";s:3:" ta";s:2:"74";s:3:"a n";s:2:"75";s:3:"ej ";s:2:"76";s:3:"li ";s:2:"77";s:3:"ne ";s:2:"78";s:3:" sa";s:2:"79";s:3:"ak ";s:2:"80";s:3:"ani";s:2:"81";s:3:"ate";s:2:"82";s:3:"ia ";s:2:"83";s:3:"sou";s:2:"84";s:3:" so";s:2:"85";s:4:"ení";s:2:"86";s:3:"ie ";s:2:"87";s:3:" re";s:2:"88";s:3:"ce ";s:2:"89";s:3:"e n";s:2:"90";s:3:"ori";s:2:"91";s:3:"tic";s:2:"92";s:3:" vy";s:2:"93";s:3:"a t";s:2:"94";s:4:"ké ";s:2:"95";s:3:"nos";s:2:"96";s:3:"o s";s:2:"97";s:3:"str";s:2:"98";s:3:"ti ";s:2:"99";s:3:"uje";s:3:"100";s:3:" sp";s:3:"101";s:3:"lov";s:3:"102";s:3:"o p";s:3:"103";s:3:"oli";s:3:"104";s:4:"ová";s:3:"105";s:4:" ná";s:3:"106";s:3:"ale";s:3:"107";s:3:"den";s:3:"108";s:3:"e o";s:3:"109";s:3:"ku ";s:3:"110";s:3:"val";s:3:"111";s:3:" am";s:3:"112";s:3:" ro";s:3:"113";s:3:" si";s:3:"114";s:3:"nie";s:3:"115";s:3:"pol";s:3:"116";s:3:"tra";s:3:"117";s:3:" al";s:3:"118";s:3:"ali";s:3:"119";s:3:"o v";s:3:"120";s:3:"tor";s:3:"121";s:3:" mo";s:3:"122";s:3:" ni";s:3:"123";s:3:"ci ";s:3:"124";s:3:"o n";s:3:"125";s:4:"ím ";s:3:"126";s:3:" le";s:3:"127";s:3:" pa";s:3:"128";s:3:" s ";s:3:"129";s:3:"al ";s:3:"130";s:3:"ati";s:3:"131";s:3:"ero";s:3:"132";s:3:"ove";s:3:"133";s:3:"rov";s:3:"134";s:4:"ván";s:3:"135";s:4:"ích";s:3:"136";s:3:" ja";s:3:"137";s:3:" z ";s:3:"138";s:4:"cké";s:3:"139";s:3:"e z";s:3:"140";s:3:" od";s:3:"141";s:3:"byl";s:3:"142";s:3:"de ";s:3:"143";s:3:"dob";s:3:"144";s:3:"nep";s:3:"145";s:3:"pra";s:3:"146";s:3:"ric";s:3:"147";s:3:"spo";s:3:"148";s:3:"tak";s:3:"149";s:4:" vš";s:3:"150";s:3:"a a";s:3:"151";s:3:"e t";s:3:"152";s:3:"lit";s:3:"153";s:3:"me ";s:3:"154";s:3:"nej";s:3:"155";s:3:"no ";s:3:"156";s:4:"nýc";s:3:"157";s:3:"o t";s:3:"158";s:3:"a j";s:3:"159";s:3:"e a";s:3:"160";s:3:"en ";s:3:"161";s:3:"est";s:3:"162";s:4:"jí ";s:3:"163";s:3:"mi ";s:3:"164";s:3:"slo";s:3:"165";s:4:"stá";s:3:"166";s:3:"u v";s:3:"167";s:3:"for";s:3:"168";s:3:"nou";s:3:"169";s:3:"pos";s:3:"170";s:4:"pře";s:3:"171";s:3:"si ";s:3:"172";s:3:"tom";s:3:"173";s:3:" vl";s:3:"174";s:3:"a z";s:3:"175";s:3:"ly ";s:3:"176";s:3:"orm";s:3:"177";s:3:"ris";s:3:"178";s:3:"za ";s:3:"179";s:4:"zák";s:3:"180";s:3:" k ";s:3:"181";s:3:"at ";s:3:"182";s:4:"cký";s:3:"183";s:3:"dno";s:3:"184";s:3:"dos";s:3:"185";s:3:"dy ";s:3:"186";s:3:"jak";s:3:"187";s:3:"kov";s:3:"188";s:3:"ny ";s:3:"189";s:3:"res";s:3:"190";s:3:"ror";s:3:"191";s:3:"sto";s:3:"192";s:3:"van";s:3:"193";s:3:" op";s:3:"194";s:3:"da ";s:3:"195";s:3:"do ";s:3:"196";s:3:"e j";s:3:"197";s:3:"hod";s:3:"198";s:3:"len";s:3:"199";s:4:"ný ";s:3:"200";s:3:"o z";s:3:"201";s:3:"poz";s:3:"202";s:3:"pri";s:3:"203";s:3:"ran";s:3:"204";s:3:"u s";s:3:"205";s:3:" ab";s:3:"206";s:3:"aj ";s:3:"207";s:3:"ast";s:3:"208";s:3:"it ";s:3:"209";s:3:"kto";s:3:"210";s:3:"o o";s:3:"211";s:3:"oby";s:3:"212";s:3:"odo";s:3:"213";s:3:"u p";s:3:"214";s:3:"va ";s:3:"215";s:5:"ání";s:3:"216";s:4:"í p";s:3:"217";s:4:"ým ";s:3:"218";s:3:" in";s:3:"219";s:3:" mi";s:3:"220";s:4:"ať ";s:3:"221";s:3:"dov";s:3:"222";s:3:"ka ";s:3:"223";s:3:"nsk";s:3:"224";s:4:"áln";s:3:"225";s:3:" an";s:3:"226";s:3:" bu";s:3:"227";s:3:" sl";s:3:"228";s:3:" tr";s:3:"229";s:3:"e m";s:3:"230";s:3:"ech";s:3:"231";s:3:"edn";s:3:"232";s:3:"i n";s:3:"233";s:4:"kýc";s:3:"234";s:4:"níc";s:3:"235";s:3:"ov ";s:3:"236";s:5:"pří";s:3:"237";s:4:"í a";s:3:"238";s:3:" aj";s:3:"239";s:3:" bo";s:3:"240";s:3:"a d";s:3:"241";s:3:"ide";s:3:"242";s:3:"o a";s:3:"243";s:3:"o d";s:3:"244";s:3:"och";s:3:"245";s:3:"pov";s:3:"246";s:3:"svo";s:3:"247";s:4:"é s";s:3:"248";s:3:" kd";s:3:"249";s:3:" vo";s:3:"250";s:4:" vý";s:3:"251";s:3:"bud";s:3:"252";s:3:"ich";s:3:"253";s:3:"il ";s:3:"254";s:3:"ili";s:3:"255";s:3:"ni ";s:3:"256";s:4:"ním";s:3:"257";s:3:"od ";s:3:"258";s:3:"osl";s:3:"259";s:3:"ouh";s:3:"260";s:3:"rav";s:3:"261";s:3:"roz";s:3:"262";s:3:"st ";s:3:"263";s:3:"stv";s:3:"264";s:3:"tu ";s:3:"265";s:3:"u a";s:3:"266";s:4:"vál";s:3:"267";s:3:"y s";s:3:"268";s:4:"í s";s:3:"269";s:4:"í v";s:3:"270";s:3:" hl";s:3:"271";s:3:" li";s:3:"272";s:3:" me";s:3:"273";s:3:"a m";s:3:"274";s:3:"e b";s:3:"275";s:3:"h s";s:3:"276";s:3:"i p";s:3:"277";s:3:"i s";s:3:"278";s:3:"iti";s:3:"279";s:4:"lád";s:3:"280";s:3:"nem";s:3:"281";s:3:"nov";s:3:"282";s:3:"opo";s:3:"283";s:3:"uhl";s:3:"284";s:3:"eno";s:3:"285";s:3:"ens";s:3:"286";s:3:"men";s:3:"287";s:3:"nes";s:3:"288";s:3:"obo";s:3:"289";s:3:"te ";s:3:"290";s:3:"ved";s:3:"291";s:4:"vlá";s:3:"292";s:3:"y n";s:3:"293";s:3:" ma";s:3:"294";s:3:" mu";s:3:"295";s:4:" vá";s:3:"296";s:3:"bez";s:3:"297";s:3:"byv";s:3:"298";s:3:"cho";s:3:"299";}s:7:"slovene";a:300:{s:3:"je ";s:1:"0";s:3:" pr";s:1:"1";s:3:" po";s:1:"2";s:3:" je";s:1:"3";s:3:" v ";s:1:"4";s:3:" za";s:1:"5";s:3:" na";s:1:"6";s:3:"pre";s:1:"7";s:3:"da ";s:1:"8";s:3:" da";s:1:"9";s:3:"ki ";s:2:"10";s:3:"ti ";s:2:"11";s:3:"ja ";s:2:"12";s:3:"ne ";s:2:"13";s:3:" in";s:2:"14";s:3:"in ";s:2:"15";s:3:"li ";s:2:"16";s:3:"no ";s:2:"17";s:3:"na ";s:2:"18";s:3:"ni ";s:2:"19";s:3:" bi";s:2:"20";s:3:"jo ";s:2:"21";s:3:" ne";s:2:"22";s:3:"nje";s:2:"23";s:3:"e p";s:2:"24";s:3:"i p";s:2:"25";s:3:"pri";s:2:"26";s:3:"o p";s:2:"27";s:3:"red";s:2:"28";s:3:" do";s:2:"29";s:3:"anj";s:2:"30";s:3:"em ";s:2:"31";s:3:"ih ";s:2:"32";s:3:" bo";s:2:"33";s:3:" ki";s:2:"34";s:3:" iz";s:2:"35";s:3:" se";s:2:"36";s:3:" so";s:2:"37";s:3:"al ";s:2:"38";s:3:" de";s:2:"39";s:3:"e v";s:2:"40";s:3:"i s";s:2:"41";s:3:"ko ";s:2:"42";s:3:"bil";s:2:"43";s:3:"ira";s:2:"44";s:3:"ove";s:2:"45";s:3:" br";s:2:"46";s:3:" ob";s:2:"47";s:3:"e b";s:2:"48";s:3:"i n";s:2:"49";s:3:"ova";s:2:"50";s:3:"se ";s:2:"51";s:3:"za ";s:2:"52";s:3:"la ";s:2:"53";s:3:" ja";s:2:"54";s:3:"ati";s:2:"55";s:3:"so ";s:2:"56";s:3:"ter";s:2:"57";s:3:" ta";s:2:"58";s:3:"a s";s:2:"59";s:3:"del";s:2:"60";s:3:"e d";s:2:"61";s:3:" dr";s:2:"62";s:3:" od";s:2:"63";s:3:"a n";s:2:"64";s:3:"ar ";s:2:"65";s:3:"jal";s:2:"66";s:3:"ji ";s:2:"67";s:3:"rit";s:2:"68";s:3:" ka";s:2:"69";s:3:" ko";s:2:"70";s:3:" pa";s:2:"71";s:3:"a b";s:2:"72";s:3:"ani";s:2:"73";s:3:"e s";s:2:"74";s:3:"er ";s:2:"75";s:3:"ili";s:2:"76";s:3:"lov";s:2:"77";s:3:"o v";s:2:"78";s:3:"tov";s:2:"79";s:3:" ir";s:2:"80";s:3:" ni";s:2:"81";s:3:" vo";s:2:"82";s:3:"a j";s:2:"83";s:3:"bi ";s:2:"84";s:3:"bri";s:2:"85";s:3:"iti";s:2:"86";s:3:"let";s:2:"87";s:3:"o n";s:2:"88";s:3:"tan";s:2:"89";s:4:"še ";s:2:"90";s:3:" le";s:2:"91";s:3:" te";s:2:"92";s:3:"eni";s:2:"93";s:3:"eri";s:2:"94";s:3:"ita";s:2:"95";s:3:"kat";s:2:"96";s:3:"por";s:2:"97";s:3:"pro";s:2:"98";s:3:"ali";s:2:"99";s:3:"ke ";s:3:"100";s:3:"oli";s:3:"101";s:3:"ov ";s:3:"102";s:3:"pra";s:3:"103";s:3:"ri ";s:3:"104";s:3:"uar";s:3:"105";s:3:"ve ";s:3:"106";s:3:" to";s:3:"107";s:3:"a i";s:3:"108";s:3:"a v";s:3:"109";s:3:"ako";s:3:"110";s:3:"arj";s:3:"111";s:3:"ate";s:3:"112";s:3:"di ";s:3:"113";s:3:"do ";s:3:"114";s:3:"ga ";s:3:"115";s:3:"le ";s:3:"116";s:3:"lo ";s:3:"117";s:3:"mer";s:3:"118";s:3:"o s";s:3:"119";s:3:"oda";s:3:"120";s:3:"oro";s:3:"121";s:3:"pod";s:3:"122";s:3:" ma";s:3:"123";s:3:" mo";s:3:"124";s:3:" si";s:3:"125";s:3:"a p";s:3:"126";s:3:"bod";s:3:"127";s:3:"e n";s:3:"128";s:3:"ega";s:3:"129";s:3:"ju ";s:3:"130";s:3:"ka ";s:3:"131";s:3:"lje";s:3:"132";s:3:"rav";s:3:"133";s:3:"ta ";s:3:"134";s:3:"a o";s:3:"135";s:3:"e t";s:3:"136";s:3:"e z";s:3:"137";s:3:"i d";s:3:"138";s:3:"i v";s:3:"139";s:3:"ila";s:3:"140";s:3:"lit";s:3:"141";s:3:"nih";s:3:"142";s:3:"odo";s:3:"143";s:3:"sti";s:3:"144";s:3:"to ";s:3:"145";s:3:"var";s:3:"146";s:3:"ved";s:3:"147";s:3:"vol";s:3:"148";s:3:" la";s:3:"149";s:3:" no";s:3:"150";s:3:" vs";s:3:"151";s:3:"a d";s:3:"152";s:3:"agu";s:3:"153";s:3:"aja";s:3:"154";s:3:"dej";s:3:"155";s:3:"dnj";s:3:"156";s:3:"eda";s:3:"157";s:3:"gov";s:3:"158";s:3:"gua";s:3:"159";s:3:"jag";s:3:"160";s:3:"jem";s:3:"161";s:3:"kon";s:3:"162";s:3:"ku ";s:3:"163";s:3:"nij";s:3:"164";s:3:"omo";s:3:"165";s:4:"oči";s:3:"166";s:3:"pov";s:3:"167";s:3:"rak";s:3:"168";s:3:"rja";s:3:"169";s:3:"sta";s:3:"170";s:3:"tev";s:3:"171";s:3:"a t";s:3:"172";s:3:"aj ";s:3:"173";s:3:"ed ";s:3:"174";s:3:"eja";s:3:"175";s:3:"ent";s:3:"176";s:3:"ev ";s:3:"177";s:3:"i i";s:3:"178";s:3:"i o";s:3:"179";s:3:"ijo";s:3:"180";s:3:"ist";s:3:"181";s:3:"ost";s:3:"182";s:3:"ske";s:3:"183";s:3:"str";s:3:"184";s:3:" ra";s:3:"185";s:3:" s ";s:3:"186";s:3:" tr";s:3:"187";s:4:" še";s:3:"188";s:3:"arn";s:3:"189";s:3:"bo ";s:3:"190";s:4:"drž";s:3:"191";s:3:"i j";s:3:"192";s:3:"ilo";s:3:"193";s:3:"izv";s:3:"194";s:3:"jen";s:3:"195";s:3:"lja";s:3:"196";s:3:"nsk";s:3:"197";s:3:"o d";s:3:"198";s:3:"o i";s:3:"199";s:3:"om ";s:3:"200";s:3:"ora";s:3:"201";s:3:"ovo";s:3:"202";s:3:"raz";s:3:"203";s:4:"rža";s:3:"204";s:3:"tak";s:3:"205";s:3:"va ";s:3:"206";s:3:"ven";s:3:"207";s:4:"žav";s:3:"208";s:3:" me";s:3:"209";s:4:" če";s:3:"210";s:3:"ame";s:3:"211";s:3:"avi";s:3:"212";s:3:"e i";s:3:"213";s:3:"e o";s:3:"214";s:3:"eka";s:3:"215";s:3:"gre";s:3:"216";s:3:"i t";s:3:"217";s:3:"ija";s:3:"218";s:3:"il ";s:3:"219";s:3:"ite";s:3:"220";s:3:"kra";s:3:"221";s:3:"lju";s:3:"222";s:3:"mor";s:3:"223";s:3:"nik";s:3:"224";s:3:"o t";s:3:"225";s:3:"obi";s:3:"226";s:3:"odn";s:3:"227";s:3:"ran";s:3:"228";s:3:"re ";s:3:"229";s:3:"sto";s:3:"230";s:3:"stv";s:3:"231";s:3:"udi";s:3:"232";s:3:"v i";s:3:"233";s:3:"van";s:3:"234";s:3:" am";s:3:"235";s:3:" sp";s:3:"236";s:3:" st";s:3:"237";s:3:" tu";s:3:"238";s:3:" ve";s:3:"239";s:4:" že";s:3:"240";s:3:"ajo";s:3:"241";s:3:"ale";s:3:"242";s:3:"apo";s:3:"243";s:3:"dal";s:3:"244";s:3:"dru";s:3:"245";s:3:"e j";s:3:"246";s:3:"edn";s:3:"247";s:3:"ejo";s:3:"248";s:3:"elo";s:3:"249";s:3:"est";s:3:"250";s:3:"etj";s:3:"251";s:3:"eva";s:3:"252";s:3:"iji";s:3:"253";s:3:"ik ";s:3:"254";s:3:"im ";s:3:"255";s:3:"itv";s:3:"256";s:3:"mob";s:3:"257";s:3:"nap";s:3:"258";s:3:"nek";s:3:"259";s:3:"pol";s:3:"260";s:3:"pos";s:3:"261";s:3:"rat";s:3:"262";s:3:"ski";s:3:"263";s:4:"tič";s:3:"264";s:3:"tom";s:3:"265";s:3:"ton";s:3:"266";s:3:"tra";s:3:"267";s:3:"tud";s:3:"268";s:3:"tve";s:3:"269";s:3:"v b";s:3:"270";s:3:"vil";s:3:"271";s:3:"vse";s:3:"272";s:4:"čit";s:3:"273";s:3:" av";s:3:"274";s:3:" gr";s:3:"275";s:3:"a z";s:3:"276";s:3:"ans";s:3:"277";s:3:"ast";s:3:"278";s:3:"avt";s:3:"279";s:3:"dan";s:3:"280";s:3:"e m";s:3:"281";s:3:"eds";s:3:"282";s:3:"for";s:3:"283";s:3:"i z";s:3:"284";s:3:"kot";s:3:"285";s:3:"mi ";s:3:"286";s:3:"nim";s:3:"287";s:3:"o b";s:3:"288";s:3:"o o";s:3:"289";s:3:"od ";s:3:"290";s:3:"odl";s:3:"291";s:3:"oiz";s:3:"292";s:3:"ot ";s:3:"293";s:3:"par";s:3:"294";s:3:"pot";s:3:"295";s:3:"rje";s:3:"296";s:3:"roi";s:3:"297";s:3:"tem";s:3:"298";s:3:"val";s:3:"299";}s:6:"somali";a:300:{s:3:"ka ";s:1:"0";s:3:"ay ";s:1:"1";s:3:"da ";s:1:"2";s:3:" ay";s:1:"3";s:3:"aal";s:1:"4";s:3:"oo ";s:1:"5";s:3:"aan";s:1:"6";s:3:" ka";s:1:"7";s:3:"an ";s:1:"8";s:3:"in ";s:1:"9";s:3:" in";s:2:"10";s:3:"ada";s:2:"11";s:3:"maa";s:2:"12";s:3:"aba";s:2:"13";s:3:" so";s:2:"14";s:3:"ali";s:2:"15";s:3:"bad";s:2:"16";s:3:"add";s:2:"17";s:3:"soo";s:2:"18";s:3:" na";s:2:"19";s:3:"aha";s:2:"20";s:3:"ku ";s:2:"21";s:3:"ta ";s:2:"22";s:3:" wa";s:2:"23";s:3:"yo ";s:2:"24";s:3:"a s";s:2:"25";s:3:"oma";s:2:"26";s:3:"yaa";s:2:"27";s:3:" ba";s:2:"28";s:3:" ku";s:2:"29";s:3:" la";s:2:"30";s:3:" oo";s:2:"31";s:3:"iya";s:2:"32";s:3:"sha";s:2:"33";s:3:"a a";s:2:"34";s:3:"dda";s:2:"35";s:3:"nab";s:2:"36";s:3:"nta";s:2:"37";s:3:" da";s:2:"38";s:3:" ma";s:2:"39";s:3:"nka";s:2:"40";s:3:"uu ";s:2:"41";s:3:"y i";s:2:"42";s:3:"aya";s:2:"43";s:3:"ha ";s:2:"44";s:3:"raa";s:2:"45";s:3:" dh";s:2:"46";s:3:" qa";s:2:"47";s:3:"a k";s:2:"48";s:3:"ala";s:2:"49";s:3:"baa";s:2:"50";s:3:"doo";s:2:"51";s:3:"had";s:2:"52";s:3:"liy";s:2:"53";s:3:"oom";s:2:"54";s:3:" ha";s:2:"55";s:3:" sh";s:2:"56";s:3:"a d";s:2:"57";s:3:"a i";s:2:"58";s:3:"a n";s:2:"59";s:3:"aar";s:2:"60";s:3:"ee ";s:2:"61";s:3:"ey ";s:2:"62";s:3:"y k";s:2:"63";s:3:"ya ";s:2:"64";s:3:" ee";s:2:"65";s:3:" iy";s:2:"66";s:3:"aa ";s:2:"67";s:3:"aaq";s:2:"68";s:3:"gaa";s:2:"69";s:3:"lam";s:2:"70";s:3:" bu";s:2:"71";s:3:"a b";s:2:"72";s:3:"a m";s:2:"73";s:3:"ad ";s:2:"74";s:3:"aga";s:2:"75";s:3:"ama";s:2:"76";s:3:"iyo";s:2:"77";s:3:"la ";s:2:"78";s:3:"a c";s:2:"79";s:3:"a l";s:2:"80";s:3:"een";s:2:"81";s:3:"int";s:2:"82";s:3:"she";s:2:"83";s:3:"wax";s:2:"84";s:3:"yee";s:2:"85";s:3:" si";s:2:"86";s:3:" uu";s:2:"87";s:3:"a h";s:2:"88";s:3:"aas";s:2:"89";s:3:"alk";s:2:"90";s:3:"dha";s:2:"91";s:3:"gu ";s:2:"92";s:3:"hee";s:2:"93";s:3:"ii ";s:2:"94";s:3:"ira";s:2:"95";s:3:"mad";s:2:"96";s:3:"o a";s:2:"97";s:3:"o k";s:2:"98";s:3:"qay";s:2:"99";s:3:" ah";s:3:"100";s:3:" ca";s:3:"101";s:3:" wu";s:3:"102";s:3:"ank";s:3:"103";s:3:"ash";s:3:"104";s:3:"axa";s:3:"105";s:3:"eed";s:3:"106";s:3:"en ";s:3:"107";s:3:"ga ";s:3:"108";s:3:"haa";s:3:"109";s:3:"n a";s:3:"110";s:3:"n s";s:3:"111";s:3:"naa";s:3:"112";s:3:"nay";s:3:"113";s:3:"o d";s:3:"114";s:3:"taa";s:3:"115";s:3:"u b";s:3:"116";s:3:"uxu";s:3:"117";s:3:"wux";s:3:"118";s:3:"xuu";s:3:"119";s:3:" ci";s:3:"120";s:3:" do";s:3:"121";s:3:" ho";s:3:"122";s:3:" ta";s:3:"123";s:3:"a g";s:3:"124";s:3:"a u";s:3:"125";s:3:"ana";s:3:"126";s:3:"ayo";s:3:"127";s:3:"dhi";s:3:"128";s:3:"iin";s:3:"129";s:3:"lag";s:3:"130";s:3:"lin";s:3:"131";s:3:"lka";s:3:"132";s:3:"o i";s:3:"133";s:3:"san";s:3:"134";s:3:"u s";s:3:"135";s:3:"una";s:3:"136";s:3:"uun";s:3:"137";s:3:" ga";s:3:"138";s:3:" xa";s:3:"139";s:3:" xu";s:3:"140";s:3:"aab";s:3:"141";s:3:"abt";s:3:"142";s:3:"aq ";s:3:"143";s:3:"aqa";s:3:"144";s:3:"ara";s:3:"145";s:3:"arl";s:3:"146";s:3:"caa";s:3:"147";s:3:"cir";s:3:"148";s:3:"eeg";s:3:"149";s:3:"eel";s:3:"150";s:3:"isa";s:3:"151";s:3:"kal";s:3:"152";s:3:"lah";s:3:"153";s:3:"ney";s:3:"154";s:3:"qaa";s:3:"155";s:3:"rla";s:3:"156";s:3:"sad";s:3:"157";s:3:"sii";s:3:"158";s:3:"u d";s:3:"159";s:3:"wad";s:3:"160";s:3:" ad";s:3:"161";s:3:" ar";s:3:"162";s:3:" di";s:3:"163";s:3:" jo";s:3:"164";s:3:" ra";s:3:"165";s:3:" sa";s:3:"166";s:3:" u ";s:3:"167";s:3:" yi";s:3:"168";s:3:"a j";s:3:"169";s:3:"a q";s:3:"170";s:3:"aad";s:3:"171";s:3:"aat";s:3:"172";s:3:"aay";s:3:"173";s:3:"ah ";s:3:"174";s:3:"ale";s:3:"175";s:3:"amk";s:3:"176";s:3:"ari";s:3:"177";s:3:"as ";s:3:"178";s:3:"aye";s:3:"179";s:3:"bus";s:3:"180";s:3:"dal";s:3:"181";s:3:"ddu";s:3:"182";s:3:"dii";s:3:"183";s:3:"du ";s:3:"184";s:3:"duu";s:3:"185";s:3:"ed ";s:3:"186";s:3:"ege";s:3:"187";s:3:"gey";s:3:"188";s:3:"hay";s:3:"189";s:3:"hii";s:3:"190";s:3:"ida";s:3:"191";s:3:"ine";s:3:"192";s:3:"joo";s:3:"193";s:3:"laa";s:3:"194";s:3:"lay";s:3:"195";s:3:"mar";s:3:"196";s:3:"mee";s:3:"197";s:3:"n b";s:3:"198";s:3:"n d";s:3:"199";s:3:"n m";s:3:"200";s:3:"no ";s:3:"201";s:3:"o b";s:3:"202";s:3:"o l";s:3:"203";s:3:"oog";s:3:"204";s:3:"oon";s:3:"205";s:3:"rga";s:3:"206";s:3:"sh ";s:3:"207";s:3:"sid";s:3:"208";s:3:"u q";s:3:"209";s:3:"unk";s:3:"210";s:3:"ush";s:3:"211";s:3:"xa ";s:3:"212";s:3:"y d";s:3:"213";s:3:" bi";s:3:"214";s:3:" gu";s:3:"215";s:3:" is";s:3:"216";s:3:" ke";s:3:"217";s:3:" lo";s:3:"218";s:3:" me";s:3:"219";s:3:" mu";s:3:"220";s:3:" qo";s:3:"221";s:3:" ug";s:3:"222";s:3:"a e";s:3:"223";s:3:"a o";s:3:"224";s:3:"a w";s:3:"225";s:3:"adi";s:3:"226";s:3:"ado";s:3:"227";s:3:"agu";s:3:"228";s:3:"al ";s:3:"229";s:3:"ant";s:3:"230";s:3:"ark";s:3:"231";s:3:"asa";s:3:"232";s:3:"awi";s:3:"233";s:3:"bta";s:3:"234";s:3:"bul";s:3:"235";s:3:"d a";s:3:"236";s:3:"dag";s:3:"237";s:3:"dan";s:3:"238";s:3:"do ";s:3:"239";s:3:"e s";s:3:"240";s:3:"gal";s:3:"241";s:3:"gay";s:3:"242";s:3:"guu";s:3:"243";s:3:"h e";s:3:"244";s:3:"hal";s:3:"245";s:3:"iga";s:3:"246";s:3:"ihi";s:3:"247";s:3:"iri";s:3:"248";s:3:"iye";s:3:"249";s:3:"ken";s:3:"250";s:3:"lad";s:3:"251";s:3:"lid";s:3:"252";s:3:"lsh";s:3:"253";s:3:"mag";s:3:"254";s:3:"mun";s:3:"255";s:3:"n h";s:3:"256";s:3:"n i";s:3:"257";s:3:"na ";s:3:"258";s:3:"o n";s:3:"259";s:3:"o w";s:3:"260";s:3:"ood";s:3:"261";s:3:"oor";s:3:"262";s:3:"ora";s:3:"263";s:3:"qab";s:3:"264";s:3:"qor";s:3:"265";s:3:"rab";s:3:"266";s:3:"rit";s:3:"267";s:3:"rta";s:3:"268";s:3:"s o";s:3:"269";s:3:"sab";s:3:"270";s:3:"ska";s:3:"271";s:3:"to ";s:3:"272";s:3:"u a";s:3:"273";s:3:"u h";s:3:"274";s:3:"u u";s:3:"275";s:3:"ud ";s:3:"276";s:3:"ugu";s:3:"277";s:3:"uls";s:3:"278";s:3:"uud";s:3:"279";s:3:"waa";s:3:"280";s:3:"xus";s:3:"281";s:3:"y b";s:3:"282";s:3:"y q";s:3:"283";s:3:"y s";s:3:"284";s:3:"yad";s:3:"285";s:3:"yay";s:3:"286";s:3:"yih";s:3:"287";s:3:" aa";s:3:"288";s:3:" bo";s:3:"289";s:3:" br";s:3:"290";s:3:" go";s:3:"291";s:3:" ji";s:3:"292";s:3:" mi";s:3:"293";s:3:" of";s:3:"294";s:3:" ti";s:3:"295";s:3:" um";s:3:"296";s:3:" wi";s:3:"297";s:3:" xo";s:3:"298";s:3:"a x";s:3:"299";}s:7:"spanish";a:300:{s:3:" de";s:1:"0";s:3:"de ";s:1:"1";s:3:" la";s:1:"2";s:3:"os ";s:1:"3";s:3:"la ";s:1:"4";s:3:"el ";s:1:"5";s:3:"es ";s:1:"6";s:3:" qu";s:1:"7";s:3:" co";s:1:"8";s:3:"e l";s:1:"9";s:3:"as ";s:2:"10";s:3:"que";s:2:"11";s:3:" el";s:2:"12";s:3:"ue ";s:2:"13";s:3:"en ";s:2:"14";s:3:"ent";s:2:"15";s:3:" en";s:2:"16";s:3:" se";s:2:"17";s:3:"nte";s:2:"18";s:3:"res";s:2:"19";s:3:"con";s:2:"20";s:3:"est";s:2:"21";s:3:" es";s:2:"22";s:3:"s d";s:2:"23";s:3:" lo";s:2:"24";s:3:" pr";s:2:"25";s:3:"los";s:2:"26";s:3:" y ";s:2:"27";s:3:"do ";s:2:"28";s:4:"ón ";s:2:"29";s:4:"ión";s:2:"30";s:3:" un";s:2:"31";s:4:"ció";s:2:"32";s:3:"del";s:2:"33";s:3:"o d";s:2:"34";s:3:" po";s:2:"35";s:3:"a d";s:2:"36";s:3:"aci";s:2:"37";s:3:"sta";s:2:"38";s:3:"te ";s:2:"39";s:3:"ado";s:2:"40";s:3:"pre";s:2:"41";s:3:"to ";s:2:"42";s:3:"par";s:2:"43";s:3:"a e";s:2:"44";s:3:"a l";s:2:"45";s:3:"ra ";s:2:"46";s:3:"al ";s:2:"47";s:3:"e e";s:2:"48";s:3:"se ";s:2:"49";s:3:"pro";s:2:"50";s:3:"ar ";s:2:"51";s:3:"ia ";s:2:"52";s:3:"o e";s:2:"53";s:3:" re";s:2:"54";s:3:"ida";s:2:"55";s:3:"dad";s:2:"56";s:3:"tra";s:2:"57";s:3:"por";s:2:"58";s:3:"s p";s:2:"59";s:3:" a ";s:2:"60";s:3:"a p";s:2:"61";s:3:"ara";s:2:"62";s:3:"cia";s:2:"63";s:3:" pa";s:2:"64";s:3:"com";s:2:"65";s:3:"no ";s:2:"66";s:3:" di";s:2:"67";s:3:" in";s:2:"68";s:3:"ien";s:2:"69";s:3:"n l";s:2:"70";s:3:"ad ";s:2:"71";s:3:"ant";s:2:"72";s:3:"e s";s:2:"73";s:3:"men";s:2:"74";s:3:"a c";s:2:"75";s:3:"on ";s:2:"76";s:3:"un ";s:2:"77";s:3:"las";s:2:"78";s:3:"nci";s:2:"79";s:3:" tr";s:2:"80";s:3:"cio";s:2:"81";s:3:"ier";s:2:"82";s:3:"nto";s:2:"83";s:3:"tiv";s:2:"84";s:3:"n d";s:2:"85";s:3:"n e";s:2:"86";s:3:"or ";s:2:"87";s:3:"s c";s:2:"88";s:3:"enc";s:2:"89";s:3:"ern";s:2:"90";s:3:"io ";s:2:"91";s:3:"a s";s:2:"92";s:3:"ici";s:2:"93";s:3:"s e";s:2:"94";s:3:" ma";s:2:"95";s:3:"dos";s:2:"96";s:3:"e a";s:2:"97";s:3:"e c";s:2:"98";s:3:"emp";s:2:"99";s:3:"ica";s:3:"100";s:3:"ivo";s:3:"101";s:3:"l p";s:3:"102";s:3:"n c";s:3:"103";s:3:"r e";s:3:"104";s:3:"ta ";s:3:"105";s:3:"ter";s:3:"106";s:3:"e d";s:3:"107";s:3:"esa";s:3:"108";s:3:"ez ";s:3:"109";s:3:"mpr";s:3:"110";s:3:"o a";s:3:"111";s:3:"s a";s:3:"112";s:3:" ca";s:3:"113";s:3:" su";s:3:"114";s:3:"ion";s:3:"115";s:3:" cu";s:3:"116";s:3:" ju";s:3:"117";s:3:"an ";s:3:"118";s:3:"da ";s:3:"119";s:3:"ene";s:3:"120";s:3:"ero";s:3:"121";s:3:"na ";s:3:"122";s:3:"rec";s:3:"123";s:3:"ro ";s:3:"124";s:3:"tar";s:3:"125";s:3:" al";s:3:"126";s:3:" an";s:3:"127";s:3:"bie";s:3:"128";s:3:"e p";s:3:"129";s:3:"er ";s:3:"130";s:3:"l c";s:3:"131";s:3:"n p";s:3:"132";s:3:"omp";s:3:"133";s:3:"ten";s:3:"134";s:3:" em";s:3:"135";s:3:"ist";s:3:"136";s:3:"nes";s:3:"137";s:3:"nta";s:3:"138";s:3:"o c";s:3:"139";s:3:"so ";s:3:"140";s:3:"tes";s:3:"141";s:3:"era";s:3:"142";s:3:"l d";s:3:"143";s:3:"l m";s:3:"144";s:3:"les";s:3:"145";s:3:"ntr";s:3:"146";s:3:"o s";s:3:"147";s:3:"ore";s:3:"148";s:4:"rá ";s:3:"149";s:3:"s q";s:3:"150";s:3:"s y";s:3:"151";s:3:"sto";s:3:"152";s:3:"a a";s:3:"153";s:3:"a r";s:3:"154";s:3:"ari";s:3:"155";s:3:"des";s:3:"156";s:3:"e q";s:3:"157";s:3:"ivi";s:3:"158";s:3:"lic";s:3:"159";s:3:"lo ";s:3:"160";s:3:"n a";s:3:"161";s:3:"one";s:3:"162";s:3:"ora";s:3:"163";s:3:"per";s:3:"164";s:3:"pue";s:3:"165";s:3:"r l";s:3:"166";s:3:"re ";s:3:"167";s:3:"ren";s:3:"168";s:3:"una";s:3:"169";s:4:"ía ";s:3:"170";s:3:"ada";s:3:"171";s:3:"cas";s:3:"172";s:3:"ere";s:3:"173";s:3:"ide";s:3:"174";s:3:"min";s:3:"175";s:3:"n s";s:3:"176";s:3:"ndo";s:3:"177";s:3:"ran";s:3:"178";s:3:"rno";s:3:"179";s:3:" ac";s:3:"180";s:3:" ex";s:3:"181";s:3:" go";s:3:"182";s:3:" no";s:3:"183";s:3:"a t";s:3:"184";s:3:"aba";s:3:"185";s:3:"ble";s:3:"186";s:3:"ece";s:3:"187";s:3:"ect";s:3:"188";s:3:"l a";s:3:"189";s:3:"l g";s:3:"190";s:3:"lid";s:3:"191";s:3:"nsi";s:3:"192";s:3:"ons";s:3:"193";s:3:"rac";s:3:"194";s:3:"rio";s:3:"195";s:3:"str";s:3:"196";s:3:"uer";s:3:"197";s:3:"ust";s:3:"198";s:3:" ha";s:3:"199";s:3:" le";s:3:"200";s:3:" mi";s:3:"201";s:3:" mu";s:3:"202";s:3:" ob";s:3:"203";s:3:" pe";s:3:"204";s:3:" pu";s:3:"205";s:3:" so";s:3:"206";s:3:"a i";s:3:"207";s:3:"ale";s:3:"208";s:3:"ca ";s:3:"209";s:3:"cto";s:3:"210";s:3:"e i";s:3:"211";s:3:"e u";s:3:"212";s:3:"eso";s:3:"213";s:3:"fer";s:3:"214";s:3:"fic";s:3:"215";s:3:"gob";s:3:"216";s:3:"jo ";s:3:"217";s:3:"ma ";s:3:"218";s:3:"mpl";s:3:"219";s:3:"o p";s:3:"220";s:3:"obi";s:3:"221";s:3:"s m";s:3:"222";s:3:"sa ";s:3:"223";s:3:"sep";s:3:"224";s:3:"ste";s:3:"225";s:3:"sti";s:3:"226";s:3:"tad";s:3:"227";s:3:"tod";s:3:"228";s:3:"y s";s:3:"229";s:3:" ci";s:3:"230";s:3:"and";s:3:"231";s:3:"ces";s:3:"232";s:4:"có ";s:3:"233";s:3:"dor";s:3:"234";s:3:"e m";s:3:"235";s:3:"eci";s:3:"236";s:3:"eco";s:3:"237";s:3:"esi";s:3:"238";s:3:"int";s:3:"239";s:3:"iza";s:3:"240";s:3:"l e";s:3:"241";s:3:"lar";s:3:"242";s:3:"mie";s:3:"243";s:3:"ner";s:3:"244";s:3:"orc";s:3:"245";s:3:"rci";s:3:"246";s:3:"ria";s:3:"247";s:3:"tic";s:3:"248";s:3:"tor";s:3:"249";s:3:" as";s:3:"250";s:3:" si";s:3:"251";s:3:"ce ";s:3:"252";s:3:"den";s:3:"253";s:3:"e r";s:3:"254";s:3:"e t";s:3:"255";s:3:"end";s:3:"256";s:3:"eri";s:3:"257";s:3:"esp";s:3:"258";s:3:"ial";s:3:"259";s:3:"ido";s:3:"260";s:3:"ina";s:3:"261";s:3:"inc";s:3:"262";s:3:"mit";s:3:"263";s:3:"o l";s:3:"264";s:3:"ome";s:3:"265";s:3:"pli";s:3:"266";s:3:"ras";s:3:"267";s:3:"s t";s:3:"268";s:3:"sid";s:3:"269";s:3:"sup";s:3:"270";s:3:"tab";s:3:"271";s:3:"uen";s:3:"272";s:3:"ues";s:3:"273";s:3:"ura";s:3:"274";s:3:"vo ";s:3:"275";s:3:"vor";s:3:"276";s:3:" sa";s:3:"277";s:3:" ti";s:3:"278";s:3:"abl";s:3:"279";s:3:"ali";s:3:"280";s:3:"aso";s:3:"281";s:3:"ast";s:3:"282";s:3:"cor";s:3:"283";s:3:"cti";s:3:"284";s:3:"cue";s:3:"285";s:3:"div";s:3:"286";s:3:"duc";s:3:"287";s:3:"ens";s:3:"288";s:3:"eti";s:3:"289";s:3:"imi";s:3:"290";s:3:"ini";s:3:"291";s:3:"lec";s:3:"292";s:3:"o q";s:3:"293";s:3:"oce";s:3:"294";s:3:"ort";s:3:"295";s:3:"ral";s:3:"296";s:3:"rma";s:3:"297";s:3:"roc";s:3:"298";s:3:"rod";s:3:"299";}s:7:"swahili";a:300:{s:3:" wa";s:1:"0";s:3:"wa ";s:1:"1";s:3:"a k";s:1:"2";s:3:"a m";s:1:"3";s:3:" ku";s:1:"4";s:3:" ya";s:1:"5";s:3:"a w";s:1:"6";s:3:"ya ";s:1:"7";s:3:"ni ";s:1:"8";s:3:" ma";s:1:"9";s:3:"ka ";s:2:"10";s:3:"a u";s:2:"11";s:3:"na ";s:2:"12";s:3:"za ";s:2:"13";s:3:"ia ";s:2:"14";s:3:" na";s:2:"15";s:3:"ika";s:2:"16";s:3:"ma ";s:2:"17";s:3:"ali";s:2:"18";s:3:"a n";s:2:"19";s:3:" am";s:2:"20";s:3:"ili";s:2:"21";s:3:"kwa";s:2:"22";s:3:" kw";s:2:"23";s:3:"ini";s:2:"24";s:3:" ha";s:2:"25";s:3:"ame";s:2:"26";s:3:"ana";s:2:"27";s:3:"i n";s:2:"28";s:3:" za";s:2:"29";s:3:"a h";s:2:"30";s:3:"ema";s:2:"31";s:3:"i m";s:2:"32";s:3:"i y";s:2:"33";s:3:"kuw";s:2:"34";s:3:"la ";s:2:"35";s:3:"o w";s:2:"36";s:3:"a y";s:2:"37";s:3:"ata";s:2:"38";s:3:"sem";s:2:"39";s:3:" la";s:2:"40";s:3:"ati";s:2:"41";s:3:"chi";s:2:"42";s:3:"i w";s:2:"43";s:3:"uwa";s:2:"44";s:3:"aki";s:2:"45";s:3:"li ";s:2:"46";s:3:"eka";s:2:"47";s:3:"ira";s:2:"48";s:3:" nc";s:2:"49";s:3:"a s";s:2:"50";s:3:"iki";s:2:"51";s:3:"kat";s:2:"52";s:3:"nch";s:2:"53";s:3:" ka";s:2:"54";s:3:" ki";s:2:"55";s:3:"a b";s:2:"56";s:3:"aji";s:2:"57";s:3:"amb";s:2:"58";s:3:"ra ";s:2:"59";s:3:"ri ";s:2:"60";s:3:"rik";s:2:"61";s:3:"ada";s:2:"62";s:3:"mat";s:2:"63";s:3:"mba";s:2:"64";s:3:"mes";s:2:"65";s:3:"yo ";s:2:"66";s:3:"zi ";s:2:"67";s:3:"da ";s:2:"68";s:3:"hi ";s:2:"69";s:3:"i k";s:2:"70";s:3:"ja ";s:2:"71";s:3:"kut";s:2:"72";s:3:"tek";s:2:"73";s:3:"wan";s:2:"74";s:3:" bi";s:2:"75";s:3:"a a";s:2:"76";s:3:"aka";s:2:"77";s:3:"ao ";s:2:"78";s:3:"asi";s:2:"79";s:3:"cha";s:2:"80";s:3:"ese";s:2:"81";s:3:"eza";s:2:"82";s:3:"ke ";s:2:"83";s:3:"moj";s:2:"84";s:3:"oja";s:2:"85";s:3:" hi";s:2:"86";s:3:"a z";s:2:"87";s:3:"end";s:2:"88";s:3:"ha ";s:2:"89";s:3:"ji ";s:2:"90";s:3:"mu ";s:2:"91";s:3:"shi";s:2:"92";s:3:"wat";s:2:"93";s:3:" bw";s:2:"94";s:3:"ake";s:2:"95";s:3:"ara";s:2:"96";s:3:"bw ";s:2:"97";s:3:"i h";s:2:"98";s:3:"imb";s:2:"99";s:3:"tik";s:3:"100";s:3:"wak";s:3:"101";s:3:"wal";s:3:"102";s:3:" hu";s:3:"103";s:3:" mi";s:3:"104";s:3:" mk";s:3:"105";s:3:" ni";s:3:"106";s:3:" ra";s:3:"107";s:3:" um";s:3:"108";s:3:"a l";s:3:"109";s:3:"ate";s:3:"110";s:3:"esh";s:3:"111";s:3:"ina";s:3:"112";s:3:"ish";s:3:"113";s:3:"kim";s:3:"114";s:3:"o k";s:3:"115";s:3:" ir";s:3:"116";s:3:"a i";s:3:"117";s:3:"ala";s:3:"118";s:3:"ani";s:3:"119";s:3:"aq ";s:3:"120";s:3:"azi";s:3:"121";s:3:"hin";s:3:"122";s:3:"i a";s:3:"123";s:3:"idi";s:3:"124";s:3:"ima";s:3:"125";s:3:"ita";s:3:"126";s:3:"rai";s:3:"127";s:3:"raq";s:3:"128";s:3:"sha";s:3:"129";s:3:" ms";s:3:"130";s:3:" se";s:3:"131";s:3:"afr";s:3:"132";s:3:"ama";s:3:"133";s:3:"ano";s:3:"134";s:3:"ea ";s:3:"135";s:3:"ele";s:3:"136";s:3:"fri";s:3:"137";s:3:"go ";s:3:"138";s:3:"i i";s:3:"139";s:3:"ifa";s:3:"140";s:3:"iwa";s:3:"141";s:3:"iyo";s:3:"142";s:3:"kus";s:3:"143";s:3:"lia";s:3:"144";s:3:"lio";s:3:"145";s:3:"maj";s:3:"146";s:3:"mku";s:3:"147";s:3:"no ";s:3:"148";s:3:"tan";s:3:"149";s:3:"uli";s:3:"150";s:3:"uta";s:3:"151";s:3:"wen";s:3:"152";s:3:" al";s:3:"153";s:3:"a j";s:3:"154";s:3:"aad";s:3:"155";s:3:"aid";s:3:"156";s:3:"ari";s:3:"157";s:3:"awa";s:3:"158";s:3:"ba ";s:3:"159";s:3:"fa ";s:3:"160";s:3:"nde";s:3:"161";s:3:"nge";s:3:"162";s:3:"nya";s:3:"163";s:3:"o y";s:3:"164";s:3:"u w";s:3:"165";s:3:"ua ";s:3:"166";s:3:"umo";s:3:"167";s:3:"waz";s:3:"168";s:3:"ye ";s:3:"169";s:3:" ut";s:3:"170";s:3:" vi";s:3:"171";s:3:"a d";s:3:"172";s:3:"a t";s:3:"173";s:3:"aif";s:3:"174";s:3:"di ";s:3:"175";s:3:"ere";s:3:"176";s:3:"ing";s:3:"177";s:3:"kin";s:3:"178";s:3:"nda";s:3:"179";s:3:"o n";s:3:"180";s:3:"oa ";s:3:"181";s:3:"tai";s:3:"182";s:3:"toa";s:3:"183";s:3:"usa";s:3:"184";s:3:"uto";s:3:"185";s:3:"was";s:3:"186";s:3:"yak";s:3:"187";s:3:"zo ";s:3:"188";s:3:" ji";s:3:"189";s:3:" mw";s:3:"190";s:3:"a p";s:3:"191";s:3:"aia";s:3:"192";s:3:"amu";s:3:"193";s:3:"ang";s:3:"194";s:3:"bik";s:3:"195";s:3:"bo ";s:3:"196";s:3:"del";s:3:"197";s:3:"e w";s:3:"198";s:3:"ene";s:3:"199";s:3:"eng";s:3:"200";s:3:"ich";s:3:"201";s:3:"iri";s:3:"202";s:3:"iti";s:3:"203";s:3:"ito";s:3:"204";s:3:"ki ";s:3:"205";s:3:"kir";s:3:"206";s:3:"ko ";s:3:"207";s:3:"kuu";s:3:"208";s:3:"mar";s:3:"209";s:3:"mbo";s:3:"210";s:3:"mil";s:3:"211";s:3:"ngi";s:3:"212";s:3:"ngo";s:3:"213";s:3:"o l";s:3:"214";s:3:"ong";s:3:"215";s:3:"si ";s:3:"216";s:3:"ta ";s:3:"217";s:3:"tak";s:3:"218";s:3:"u y";s:3:"219";s:3:"umu";s:3:"220";s:3:"usi";s:3:"221";s:3:"uu ";s:3:"222";s:3:"wam";s:3:"223";s:3:" af";s:3:"224";s:3:" ba";s:3:"225";s:3:" li";s:3:"226";s:3:" si";s:3:"227";s:3:" zi";s:3:"228";s:3:"a v";s:3:"229";s:3:"ami";s:3:"230";s:3:"atu";s:3:"231";s:3:"awi";s:3:"232";s:3:"eri";s:3:"233";s:3:"fan";s:3:"234";s:3:"fur";s:3:"235";s:3:"ger";s:3:"236";s:3:"i z";s:3:"237";s:3:"isi";s:3:"238";s:3:"izo";s:3:"239";s:3:"lea";s:3:"240";s:3:"mbi";s:3:"241";s:3:"mwa";s:3:"242";s:3:"nye";s:3:"243";s:3:"o h";s:3:"244";s:3:"o m";s:3:"245";s:3:"oni";s:3:"246";s:3:"rez";s:3:"247";s:3:"saa";s:3:"248";s:3:"ser";s:3:"249";s:3:"sin";s:3:"250";s:3:"tat";s:3:"251";s:3:"tis";s:3:"252";s:3:"tu ";s:3:"253";s:3:"uin";s:3:"254";s:3:"uki";s:3:"255";s:3:"ur ";s:3:"256";s:3:"wi ";s:3:"257";s:3:"yar";s:3:"258";s:3:" da";s:3:"259";s:3:" en";s:3:"260";s:3:" mp";s:3:"261";s:3:" ny";s:3:"262";s:3:" ta";s:3:"263";s:3:" ul";s:3:"264";s:3:" we";s:3:"265";s:3:"a c";s:3:"266";s:3:"a f";s:3:"267";s:3:"ais";s:3:"268";s:3:"apo";s:3:"269";s:3:"ayo";s:3:"270";s:3:"bar";s:3:"271";s:3:"dhi";s:3:"272";s:3:"e a";s:3:"273";s:3:"eke";s:3:"274";s:3:"eny";s:3:"275";s:3:"eon";s:3:"276";s:3:"hai";s:3:"277";s:3:"han";s:3:"278";s:3:"hiy";s:3:"279";s:3:"hur";s:3:"280";s:3:"i s";s:3:"281";s:3:"imw";s:3:"282";s:3:"kal";s:3:"283";s:3:"kwe";s:3:"284";s:3:"lak";s:3:"285";s:3:"lam";s:3:"286";s:3:"mak";s:3:"287";s:3:"msa";s:3:"288";s:3:"ne ";s:3:"289";s:3:"ngu";s:3:"290";s:3:"ru ";s:3:"291";s:3:"sal";s:3:"292";s:3:"swa";s:3:"293";s:3:"te ";s:3:"294";s:3:"ti ";s:3:"295";s:3:"uku";s:3:"296";s:3:"uma";s:3:"297";s:3:"una";s:3:"298";s:3:"uru";s:3:"299";}s:7:"swedish";a:300:{s:3:"en ";s:1:"0";s:3:" de";s:1:"1";s:3:"et ";s:1:"2";s:3:"er ";s:1:"3";s:3:"tt ";s:1:"4";s:3:"om ";s:1:"5";s:4:"för";s:1:"6";s:3:"ar ";s:1:"7";s:3:"de ";s:1:"8";s:3:"att";s:1:"9";s:4:" fö";s:2:"10";s:3:"ing";s:2:"11";s:3:" in";s:2:"12";s:3:" at";s:2:"13";s:3:" i ";s:2:"14";s:3:"det";s:2:"15";s:3:"ch ";s:2:"16";s:3:"an ";s:2:"17";s:3:"gen";s:2:"18";s:3:" an";s:2:"19";s:3:"t s";s:2:"20";s:3:"som";s:2:"21";s:3:"te ";s:2:"22";s:3:" oc";s:2:"23";s:3:"ter";s:2:"24";s:3:" ha";s:2:"25";s:3:"lle";s:2:"26";s:3:"och";s:2:"27";s:3:" sk";s:2:"28";s:3:" so";s:2:"29";s:3:"ra ";s:2:"30";s:3:"r a";s:2:"31";s:3:" me";s:2:"32";s:3:"var";s:2:"33";s:3:"nde";s:2:"34";s:4:"är ";s:2:"35";s:3:" ko";s:2:"36";s:3:"on ";s:2:"37";s:3:"ans";s:2:"38";s:3:"int";s:2:"39";s:3:"n s";s:2:"40";s:3:"na ";s:2:"41";s:3:" en";s:2:"42";s:3:" fr";s:2:"43";s:4:" på";s:2:"44";s:3:" st";s:2:"45";s:3:" va";s:2:"46";s:3:"and";s:2:"47";s:3:"nte";s:2:"48";s:4:"på ";s:2:"49";s:3:"ska";s:2:"50";s:3:"ta ";s:2:"51";s:3:" vi";s:2:"52";s:3:"der";s:2:"53";s:4:"äll";s:2:"54";s:4:"örs";s:2:"55";s:3:" om";s:2:"56";s:3:"da ";s:2:"57";s:3:"kri";s:2:"58";s:3:"ka ";s:2:"59";s:3:"nst";s:2:"60";s:3:" ho";s:2:"61";s:3:"as ";s:2:"62";s:4:"stä";s:2:"63";s:3:"r d";s:2:"64";s:3:"t f";s:2:"65";s:3:"upp";s:2:"66";s:3:" be";s:2:"67";s:3:"nge";s:2:"68";s:3:"r s";s:2:"69";s:3:"tal";s:2:"70";s:4:"täl";s:2:"71";s:4:"ör ";s:2:"72";s:3:" av";s:2:"73";s:3:"ger";s:2:"74";s:3:"ill";s:2:"75";s:3:"ng ";s:2:"76";s:3:"e s";s:2:"77";s:3:"ekt";s:2:"78";s:3:"ade";s:2:"79";s:3:"era";s:2:"80";s:3:"ers";s:2:"81";s:3:"har";s:2:"82";s:3:"ll ";s:2:"83";s:3:"lld";s:2:"84";s:3:"rin";s:2:"85";s:3:"rna";s:2:"86";s:4:"säk";s:2:"87";s:3:"und";s:2:"88";s:3:"inn";s:2:"89";s:3:"lig";s:2:"90";s:3:"ns ";s:2:"91";s:3:" ma";s:2:"92";s:3:" pr";s:2:"93";s:3:" up";s:2:"94";s:3:"age";s:2:"95";s:3:"av ";s:2:"96";s:3:"iva";s:2:"97";s:3:"kti";s:2:"98";s:3:"lda";s:2:"99";s:3:"orn";s:3:"100";s:3:"son";s:3:"101";s:3:"ts ";s:3:"102";s:3:"tta";s:3:"103";s:4:"äkr";s:3:"104";s:3:" sj";s:3:"105";s:3:" ti";s:3:"106";s:3:"avt";s:3:"107";s:3:"ber";s:3:"108";s:3:"els";s:3:"109";s:3:"eta";s:3:"110";s:3:"kol";s:3:"111";s:3:"men";s:3:"112";s:3:"n d";s:3:"113";s:3:"t k";s:3:"114";s:3:"vta";s:3:"115";s:4:"år ";s:3:"116";s:3:"juk";s:3:"117";s:3:"man";s:3:"118";s:3:"n f";s:3:"119";s:3:"nin";s:3:"120";s:3:"r i";s:3:"121";s:4:"rsä";s:3:"122";s:3:"sju";s:3:"123";s:3:"sso";s:3:"124";s:4:" är";s:3:"125";s:3:"a s";s:3:"126";s:3:"ach";s:3:"127";s:3:"ag ";s:3:"128";s:3:"bac";s:3:"129";s:3:"den";s:3:"130";s:3:"ett";s:3:"131";s:3:"fte";s:3:"132";s:3:"hor";s:3:"133";s:3:"nba";s:3:"134";s:3:"oll";s:3:"135";s:3:"rnb";s:3:"136";s:3:"ste";s:3:"137";s:3:"til";s:3:"138";s:3:" ef";s:3:"139";s:3:" si";s:3:"140";s:3:"a a";s:3:"141";s:3:"e h";s:3:"142";s:3:"ed ";s:3:"143";s:3:"eft";s:3:"144";s:3:"ga ";s:3:"145";s:3:"ig ";s:3:"146";s:3:"it ";s:3:"147";s:3:"ler";s:3:"148";s:3:"med";s:3:"149";s:3:"n i";s:3:"150";s:3:"nd ";s:3:"151";s:4:"så ";s:3:"152";s:3:"tiv";s:3:"153";s:3:" bl";s:3:"154";s:3:" et";s:3:"155";s:3:" fi";s:3:"156";s:4:" sä";s:3:"157";s:3:"at ";s:3:"158";s:3:"des";s:3:"159";s:3:"e a";s:3:"160";s:3:"gar";s:3:"161";s:3:"get";s:3:"162";s:3:"lan";s:3:"163";s:3:"lss";s:3:"164";s:3:"ost";s:3:"165";s:3:"r b";s:3:"166";s:3:"r e";s:3:"167";s:3:"re ";s:3:"168";s:3:"ret";s:3:"169";s:3:"sta";s:3:"170";s:3:"t i";s:3:"171";s:3:" ge";s:3:"172";s:3:" he";s:3:"173";s:3:" re";s:3:"174";s:3:"a f";s:3:"175";s:3:"all";s:3:"176";s:3:"bos";s:3:"177";s:3:"ets";s:3:"178";s:3:"lek";s:3:"179";s:3:"let";s:3:"180";s:3:"ner";s:3:"181";s:3:"nna";s:3:"182";s:3:"nne";s:3:"183";s:3:"r f";s:3:"184";s:3:"rit";s:3:"185";s:3:"s s";s:3:"186";s:3:"sen";s:3:"187";s:3:"sto";s:3:"188";s:3:"tor";s:3:"189";s:3:"vav";s:3:"190";s:3:"ygg";s:3:"191";s:3:" ka";s:3:"192";s:4:" så";s:3:"193";s:3:" tr";s:3:"194";s:3:" ut";s:3:"195";s:3:"ad ";s:3:"196";s:3:"al ";s:3:"197";s:3:"are";s:3:"198";s:3:"e o";s:3:"199";s:3:"gon";s:3:"200";s:3:"kom";s:3:"201";s:3:"n a";s:3:"202";s:3:"n h";s:3:"203";s:3:"nga";s:3:"204";s:3:"r h";s:3:"205";s:3:"ren";s:3:"206";s:3:"t d";s:3:"207";s:3:"tag";s:3:"208";s:3:"tar";s:3:"209";s:3:"tre";s:3:"210";s:4:"ätt";s:3:"211";s:4:" få";s:3:"212";s:4:" hä";s:3:"213";s:3:" se";s:3:"214";s:3:"a d";s:3:"215";s:3:"a i";s:3:"216";s:3:"a p";s:3:"217";s:3:"ale";s:3:"218";s:3:"ann";s:3:"219";s:3:"ara";s:3:"220";s:3:"byg";s:3:"221";s:3:"gt ";s:3:"222";s:3:"han";s:3:"223";s:3:"igt";s:3:"224";s:3:"kan";s:3:"225";s:3:"la ";s:3:"226";s:3:"n o";s:3:"227";s:3:"nom";s:3:"228";s:3:"nsk";s:3:"229";s:3:"omm";s:3:"230";s:3:"r k";s:3:"231";s:3:"r p";s:3:"232";s:3:"r v";s:3:"233";s:3:"s f";s:3:"234";s:3:"s k";s:3:"235";s:3:"t a";s:3:"236";s:3:"t p";s:3:"237";s:3:"ver";s:3:"238";s:3:" bo";s:3:"239";s:3:" br";s:3:"240";s:3:" ku";s:3:"241";s:4:" nå";s:3:"242";s:3:"a b";s:3:"243";s:3:"a e";s:3:"244";s:3:"del";s:3:"245";s:3:"ens";s:3:"246";s:3:"es ";s:3:"247";s:3:"fin";s:3:"248";s:3:"ige";s:3:"249";s:3:"m s";s:3:"250";s:3:"n p";s:3:"251";s:4:"någ";s:3:"252";s:3:"or ";s:3:"253";s:3:"r o";s:3:"254";s:3:"rbe";s:3:"255";s:3:"rs ";s:3:"256";s:3:"rt ";s:3:"257";s:3:"s a";s:3:"258";s:3:"s n";s:3:"259";s:3:"skr";s:3:"260";s:3:"t o";s:3:"261";s:3:"ten";s:3:"262";s:3:"tio";s:3:"263";s:3:"ven";s:3:"264";s:3:" al";s:3:"265";s:3:" ja";s:3:"266";s:3:" p ";s:3:"267";s:3:" r ";s:3:"268";s:3:" sa";s:3:"269";s:3:"a h";s:3:"270";s:3:"bet";s:3:"271";s:3:"cke";s:3:"272";s:3:"dra";s:3:"273";s:3:"e f";s:3:"274";s:3:"e i";s:3:"275";s:3:"eda";s:3:"276";s:3:"eno";s:3:"277";s:4:"erä";s:3:"278";s:3:"ess";s:3:"279";s:3:"ion";s:3:"280";s:3:"jag";s:3:"281";s:3:"m f";s:3:"282";s:3:"ne ";s:3:"283";s:3:"nns";s:3:"284";s:3:"pro";s:3:"285";s:3:"r t";s:3:"286";s:3:"rar";s:3:"287";s:3:"riv";s:3:"288";s:4:"rät";s:3:"289";s:3:"t e";s:3:"290";s:3:"t t";s:3:"291";s:3:"ust";s:3:"292";s:3:"vad";s:3:"293";s:4:"öre";s:3:"294";s:3:" ar";s:3:"295";s:3:" by";s:3:"296";s:3:" kr";s:3:"297";s:3:" mi";s:3:"298";s:3:"arb";s:3:"299";}s:7:"tagalog";a:300:{s:3:"ng ";s:1:"0";s:3:"ang";s:1:"1";s:3:" na";s:1:"2";s:3:" sa";s:1:"3";s:3:"an ";s:1:"4";s:3:"nan";s:1:"5";s:3:"sa ";s:1:"6";s:3:"na ";s:1:"7";s:3:" ma";s:1:"8";s:3:" ca";s:1:"9";s:3:"ay ";s:2:"10";s:3:"n g";s:2:"11";s:3:" an";s:2:"12";s:3:"ong";s:2:"13";s:3:" ga";s:2:"14";s:3:"at ";s:2:"15";s:3:" pa";s:2:"16";s:3:"ala";s:2:"17";s:3:" si";s:2:"18";s:3:"a n";s:2:"19";s:3:"ga ";s:2:"20";s:3:"g n";s:2:"21";s:3:"g m";s:2:"22";s:3:"ito";s:2:"23";s:3:"g c";s:2:"24";s:3:"man";s:2:"25";s:3:"san";s:2:"26";s:3:"g s";s:2:"27";s:3:"ing";s:2:"28";s:3:"to ";s:2:"29";s:3:"ila";s:2:"30";s:3:"ina";s:2:"31";s:3:" di";s:2:"32";s:3:" ta";s:2:"33";s:3:"aga";s:2:"34";s:3:"iya";s:2:"35";s:3:"aca";s:2:"36";s:3:"g t";s:2:"37";s:3:" at";s:2:"38";s:3:"aya";s:2:"39";s:3:"ama";s:2:"40";s:3:"lan";s:2:"41";s:3:"a a";s:2:"42";s:3:"qui";s:2:"43";s:3:"a c";s:2:"44";s:3:"a s";s:2:"45";s:3:"nag";s:2:"46";s:3:" ba";s:2:"47";s:3:"g i";s:2:"48";s:3:"tan";s:2:"49";s:3:"'t ";s:2:"50";s:3:" cu";s:2:"51";s:3:"aua";s:2:"52";s:3:"g p";s:2:"53";s:3:" ni";s:2:"54";s:3:"os ";s:2:"55";s:3:"'y ";s:2:"56";s:3:"a m";s:2:"57";s:3:" n ";s:2:"58";s:3:"la ";s:2:"59";s:3:" la";s:2:"60";s:3:"o n";s:2:"61";s:3:"yan";s:2:"62";s:3:" ay";s:2:"63";s:3:"usa";s:2:"64";s:3:"cay";s:2:"65";s:3:"on ";s:2:"66";s:3:"ya ";s:2:"67";s:3:" it";s:2:"68";s:3:"al ";s:2:"69";s:3:"apa";s:2:"70";s:3:"ata";s:2:"71";s:3:"t n";s:2:"72";s:3:"uan";s:2:"73";s:3:"aha";s:2:"74";s:3:"asa";s:2:"75";s:3:"pag";s:2:"76";s:3:" gu";s:2:"77";s:3:"g l";s:2:"78";s:3:"di ";s:2:"79";s:3:"mag";s:2:"80";s:3:"aba";s:2:"81";s:3:"g a";s:2:"82";s:3:"ara";s:2:"83";s:3:"a p";s:2:"84";s:3:"in ";s:2:"85";s:3:"ana";s:2:"86";s:3:"it ";s:2:"87";s:3:"si ";s:2:"88";s:3:"cus";s:2:"89";s:3:"g b";s:2:"90";s:3:"uin";s:2:"91";s:3:"a t";s:2:"92";s:3:"as ";s:2:"93";s:3:"n n";s:2:"94";s:3:"hin";s:2:"95";s:3:" hi";s:2:"96";s:3:"a't";s:2:"97";s:3:"ali";s:2:"98";s:3:" bu";s:2:"99";s:3:"gan";s:3:"100";s:3:"uma";s:3:"101";s:3:"a d";s:3:"102";s:3:"agc";s:3:"103";s:3:"aqu";s:3:"104";s:3:"g d";s:3:"105";s:3:" tu";s:3:"106";s:3:"aon";s:3:"107";s:3:"ari";s:3:"108";s:3:"cas";s:3:"109";s:3:"i n";s:3:"110";s:3:"niy";s:3:"111";s:3:"pin";s:3:"112";s:3:"a i";s:3:"113";s:3:"gca";s:3:"114";s:3:"siy";s:3:"115";s:3:"a'y";s:3:"116";s:3:"yao";s:3:"117";s:3:"ag ";s:3:"118";s:3:"ca ";s:3:"119";s:3:"han";s:3:"120";s:3:"ili";s:3:"121";s:3:"pan";s:3:"122";s:3:"sin";s:3:"123";s:3:"ual";s:3:"124";s:3:"n s";s:3:"125";s:3:"nam";s:3:"126";s:3:" lu";s:3:"127";s:3:"can";s:3:"128";s:3:"dit";s:3:"129";s:3:"gui";s:3:"130";s:3:"y n";s:3:"131";s:3:"gal";s:3:"132";s:3:"hat";s:3:"133";s:3:"nal";s:3:"134";s:3:" is";s:3:"135";s:3:"bag";s:3:"136";s:3:"fra";s:3:"137";s:3:" fr";s:3:"138";s:3:" su";s:3:"139";s:3:"a l";s:3:"140";s:3:" co";s:3:"141";s:3:"ani";s:3:"142";s:3:" bi";s:3:"143";s:3:" da";s:3:"144";s:3:"alo";s:3:"145";s:3:"isa";s:3:"146";s:3:"ita";s:3:"147";s:3:"may";s:3:"148";s:3:"o s";s:3:"149";s:3:"sil";s:3:"150";s:3:"una";s:3:"151";s:3:" in";s:3:"152";s:3:" pi";s:3:"153";s:3:"l n";s:3:"154";s:3:"nil";s:3:"155";s:3:"o a";s:3:"156";s:3:"pat";s:3:"157";s:3:"sac";s:3:"158";s:3:"t s";s:3:"159";s:3:" ua";s:3:"160";s:3:"agu";s:3:"161";s:3:"ail";s:3:"162";s:3:"bin";s:3:"163";s:3:"dal";s:3:"164";s:3:"g h";s:3:"165";s:3:"ndi";s:3:"166";s:3:"oon";s:3:"167";s:3:"ua ";s:3:"168";s:3:" ha";s:3:"169";s:3:"ind";s:3:"170";s:3:"ran";s:3:"171";s:3:"s n";s:3:"172";s:3:"tin";s:3:"173";s:3:"ulo";s:3:"174";s:3:"eng";s:3:"175";s:3:"g f";s:3:"176";s:3:"ini";s:3:"177";s:3:"lah";s:3:"178";s:3:"lo ";s:3:"179";s:3:"rai";s:3:"180";s:3:"rin";s:3:"181";s:3:"ton";s:3:"182";s:3:"g u";s:3:"183";s:3:"inu";s:3:"184";s:3:"lon";s:3:"185";s:3:"o'y";s:3:"186";s:3:"t a";s:3:"187";s:3:" ar";s:3:"188";s:3:"a b";s:3:"189";s:3:"ad ";s:3:"190";s:3:"bay";s:3:"191";s:3:"cal";s:3:"192";s:3:"gya";s:3:"193";s:3:"ile";s:3:"194";s:3:"mat";s:3:"195";s:3:"n a";s:3:"196";s:3:"pau";s:3:"197";s:3:"ra ";s:3:"198";s:3:"tay";s:3:"199";s:3:"y m";s:3:"200";s:3:"ant";s:3:"201";s:3:"ban";s:3:"202";s:3:"i m";s:3:"203";s:3:"nas";s:3:"204";s:3:"nay";s:3:"205";s:3:"no ";s:3:"206";s:3:"sti";s:3:"207";s:3:" ti";s:3:"208";s:3:"ags";s:3:"209";s:3:"g g";s:3:"210";s:3:"ta ";s:3:"211";s:3:"uit";s:3:"212";s:3:"uno";s:3:"213";s:3:" ib";s:3:"214";s:3:" ya";s:3:"215";s:3:"a u";s:3:"216";s:3:"abi";s:3:"217";s:3:"ati";s:3:"218";s:3:"cap";s:3:"219";s:3:"ig ";s:3:"220";s:3:"is ";s:3:"221";s:3:"la'";s:3:"222";s:3:" do";s:3:"223";s:3:" pu";s:3:"224";s:3:"api";s:3:"225";s:3:"ayo";s:3:"226";s:3:"gos";s:3:"227";s:3:"gul";s:3:"228";s:3:"lal";s:3:"229";s:3:"tag";s:3:"230";s:3:"til";s:3:"231";s:3:"tun";s:3:"232";s:3:"y c";s:3:"233";s:3:"y s";s:3:"234";s:3:"yon";s:3:"235";s:3:"ano";s:3:"236";s:3:"bur";s:3:"237";s:3:"iba";s:3:"238";s:3:"isi";s:3:"239";s:3:"lam";s:3:"240";s:3:"nac";s:3:"241";s:3:"nat";s:3:"242";s:3:"ni ";s:3:"243";s:3:"nto";s:3:"244";s:3:"od ";s:3:"245";s:3:"pa ";s:3:"246";s:3:"rgo";s:3:"247";s:3:"urg";s:3:"248";s:3:" m ";s:3:"249";s:3:"adr";s:3:"250";s:3:"ast";s:3:"251";s:3:"cag";s:3:"252";s:3:"gay";s:3:"253";s:3:"gsi";s:3:"254";s:3:"i p";s:3:"255";s:3:"ino";s:3:"256";s:3:"len";s:3:"257";s:3:"lin";s:3:"258";s:3:"m g";s:3:"259";s:3:"mar";s:3:"260";s:3:"nah";s:3:"261";s:3:"to'";s:3:"262";s:3:" de";s:3:"263";s:3:"a h";s:3:"264";s:3:"cat";s:3:"265";s:3:"cau";s:3:"266";s:3:"con";s:3:"267";s:3:"iqu";s:3:"268";s:3:"lac";s:3:"269";s:3:"mab";s:3:"270";s:3:"min";s:3:"271";s:3:"og ";s:3:"272";s:3:"par";s:3:"273";s:3:"sal";s:3:"274";s:3:" za";s:3:"275";s:3:"ao ";s:3:"276";s:3:"doo";s:3:"277";s:3:"ipi";s:3:"278";s:3:"nod";s:3:"279";s:3:"nte";s:3:"280";s:3:"uha";s:3:"281";s:3:"ula";s:3:"282";s:3:" re";s:3:"283";s:3:"ill";s:3:"284";s:3:"lit";s:3:"285";s:3:"mac";s:3:"286";s:3:"nit";s:3:"287";s:3:"o't";s:3:"288";s:3:"or ";s:3:"289";s:3:"ora";s:3:"290";s:3:"sum";s:3:"291";s:3:"y p";s:3:"292";s:3:" al";s:3:"293";s:3:" mi";s:3:"294";s:3:" um";s:3:"295";s:3:"aco";s:3:"296";s:3:"ada";s:3:"297";s:3:"agd";s:3:"298";s:3:"cab";s:3:"299";}s:7:"turkish";a:300:{s:3:"lar";s:1:"0";s:3:"en ";s:1:"1";s:3:"ler";s:1:"2";s:3:"an ";s:1:"3";s:3:"in ";s:1:"4";s:3:" bi";s:1:"5";s:3:" ya";s:1:"6";s:3:"eri";s:1:"7";s:3:"de ";s:1:"8";s:3:" ka";s:1:"9";s:3:"ir ";s:2:"10";s:4:"arı";s:2:"11";s:3:" ba";s:2:"12";s:3:" de";s:2:"13";s:3:" ha";s:2:"14";s:4:"ın ";s:2:"15";s:3:"ara";s:2:"16";s:3:"bir";s:2:"17";s:3:" ve";s:2:"18";s:3:" sa";s:2:"19";s:3:"ile";s:2:"20";s:3:"le ";s:2:"21";s:3:"nde";s:2:"22";s:3:"da ";s:2:"23";s:3:" bu";s:2:"24";s:3:"ana";s:2:"25";s:3:"ini";s:2:"26";s:5:"ını";s:2:"27";s:3:"er ";s:2:"28";s:3:"ve ";s:2:"29";s:4:" yı";s:2:"30";s:3:"lma";s:2:"31";s:4:"yıl";s:2:"32";s:3:" ol";s:2:"33";s:3:"ar ";s:2:"34";s:3:"n b";s:2:"35";s:3:"nda";s:2:"36";s:3:"aya";s:2:"37";s:3:"li ";s:2:"38";s:4:"ası";s:2:"39";s:3:" ge";s:2:"40";s:3:"ind";s:2:"41";s:3:"n k";s:2:"42";s:3:"esi";s:2:"43";s:3:"lan";s:2:"44";s:3:"nla";s:2:"45";s:3:"ak ";s:2:"46";s:4:"anı";s:2:"47";s:3:"eni";s:2:"48";s:3:"ni ";s:2:"49";s:4:"nı ";s:2:"50";s:4:"rın";s:2:"51";s:3:"san";s:2:"52";s:3:" ko";s:2:"53";s:3:" ye";s:2:"54";s:3:"maz";s:2:"55";s:4:"baş";s:2:"56";s:3:"ili";s:2:"57";s:3:"rin";s:2:"58";s:4:"alı";s:2:"59";s:3:"az ";s:2:"60";s:3:"hal";s:2:"61";s:4:"ınd";s:2:"62";s:3:" da";s:2:"63";s:4:" gü";s:2:"64";s:3:"ele";s:2:"65";s:4:"ılm";s:2:"66";s:6:"ığı";s:2:"67";s:3:"eki";s:2:"68";s:4:"gün";s:2:"69";s:3:"i b";s:2:"70";s:4:"içi";s:2:"71";s:3:"den";s:2:"72";s:3:"kar";s:2:"73";s:3:"si ";s:2:"74";s:3:" il";s:2:"75";s:3:"e y";s:2:"76";s:3:"na ";s:2:"77";s:3:"yor";s:2:"78";s:3:"ek ";s:2:"79";s:3:"n s";s:2:"80";s:4:" iç";s:2:"81";s:3:"bu ";s:2:"82";s:3:"e b";s:2:"83";s:3:"im ";s:2:"84";s:3:"ki ";s:2:"85";s:3:"len";s:2:"86";s:3:"ri ";s:2:"87";s:4:"sın";s:2:"88";s:3:" so";s:2:"89";s:4:"ün ";s:2:"90";s:3:" ta";s:2:"91";s:3:"nin";s:2:"92";s:4:"iği";s:2:"93";s:3:"tan";s:2:"94";s:3:"yan";s:2:"95";s:3:" si";s:2:"96";s:3:"nat";s:2:"97";s:4:"nın";s:2:"98";s:3:"kan";s:2:"99";s:4:"rı ";s:3:"100";s:4:"çin";s:3:"101";s:5:"ğı ";s:3:"102";s:3:"eli";s:3:"103";s:3:"n a";s:3:"104";s:4:"ır ";s:3:"105";s:3:" an";s:3:"106";s:3:"ine";s:3:"107";s:3:"n y";s:3:"108";s:3:"ola";s:3:"109";s:3:" ar";s:3:"110";s:3:"al ";s:3:"111";s:3:"e s";s:3:"112";s:3:"lik";s:3:"113";s:3:"n d";s:3:"114";s:3:"sin";s:3:"115";s:3:" al";s:3:"116";s:4:" dü";s:3:"117";s:3:"anl";s:3:"118";s:3:"ne ";s:3:"119";s:3:"ya ";s:3:"120";s:4:"ım ";s:3:"121";s:4:"ına";s:3:"122";s:3:" be";s:3:"123";s:3:"ada";s:3:"124";s:3:"ala";s:3:"125";s:3:"ama";s:3:"126";s:3:"ilm";s:3:"127";s:3:"or ";s:3:"128";s:4:"sı ";s:3:"129";s:3:"yen";s:3:"130";s:3:" me";s:3:"131";s:4:"atı";s:3:"132";s:3:"di ";s:3:"133";s:3:"eti";s:3:"134";s:3:"ken";s:3:"135";s:3:"la ";s:3:"136";s:4:"lı ";s:3:"137";s:3:"oru";s:3:"138";s:4:" gö";s:3:"139";s:3:" in";s:3:"140";s:3:"and";s:3:"141";s:3:"e d";s:3:"142";s:3:"men";s:3:"143";s:3:"un ";s:3:"144";s:4:"öne";s:3:"145";s:3:"a d";s:3:"146";s:3:"at ";s:3:"147";s:3:"e a";s:3:"148";s:3:"e g";s:3:"149";s:3:"yar";s:3:"150";s:3:" ku";s:3:"151";s:4:"ayı";s:3:"152";s:3:"dan";s:3:"153";s:3:"edi";s:3:"154";s:3:"iri";s:3:"155";s:5:"ünü";s:3:"156";s:4:"ği ";s:3:"157";s:5:"ılı";s:3:"158";s:3:"eme";s:3:"159";s:4:"eği";s:3:"160";s:3:"i k";s:3:"161";s:3:"i y";s:3:"162";s:4:"ıla";s:3:"163";s:4:" ça";s:3:"164";s:3:"a y";s:3:"165";s:3:"alk";s:3:"166";s:4:"dı ";s:3:"167";s:3:"ede";s:3:"168";s:3:"el ";s:3:"169";s:4:"ndı";s:3:"170";s:3:"ra ";s:3:"171";s:4:"üne";s:3:"172";s:4:" sü";s:3:"173";s:4:"dır";s:3:"174";s:3:"e k";s:3:"175";s:3:"ere";s:3:"176";s:3:"ik ";s:3:"177";s:3:"imi";s:3:"178";s:4:"işi";s:3:"179";s:3:"mas";s:3:"180";s:3:"n h";s:3:"181";s:4:"sür";s:3:"182";s:3:"yle";s:3:"183";s:3:" ad";s:3:"184";s:3:" fi";s:3:"185";s:3:" gi";s:3:"186";s:3:" se";s:3:"187";s:3:"a k";s:3:"188";s:3:"arl";s:3:"189";s:5:"aşı";s:3:"190";s:3:"iyo";s:3:"191";s:3:"kla";s:3:"192";s:5:"lığ";s:3:"193";s:3:"nem";s:3:"194";s:3:"ney";s:3:"195";s:3:"rme";s:3:"196";s:3:"ste";s:3:"197";s:4:"tı ";s:3:"198";s:3:"unl";s:3:"199";s:3:"ver";s:3:"200";s:4:" sı";s:3:"201";s:3:" te";s:3:"202";s:3:" to";s:3:"203";s:3:"a s";s:3:"204";s:4:"aşk";s:3:"205";s:3:"ekl";s:3:"206";s:3:"end";s:3:"207";s:3:"kal";s:3:"208";s:4:"liğ";s:3:"209";s:3:"min";s:3:"210";s:4:"tır";s:3:"211";s:3:"ulu";s:3:"212";s:3:"unu";s:3:"213";s:3:"yap";s:3:"214";s:3:"ye ";s:3:"215";s:4:"ı i";s:3:"216";s:4:"şka";s:3:"217";s:5:"ştı";s:3:"218";s:4:" bü";s:3:"219";s:3:" ke";s:3:"220";s:3:" ki";s:3:"221";s:3:"ard";s:3:"222";s:3:"art";s:3:"223";s:4:"aşa";s:3:"224";s:3:"n i";s:3:"225";s:3:"ndi";s:3:"226";s:3:"ti ";s:3:"227";s:3:"top";s:3:"228";s:4:"ı b";s:3:"229";s:3:" va";s:3:"230";s:4:" ön";s:3:"231";s:3:"aki";s:3:"232";s:3:"cak";s:3:"233";s:3:"ey ";s:3:"234";s:3:"fil";s:3:"235";s:3:"isi";s:3:"236";s:3:"kle";s:3:"237";s:3:"kur";s:3:"238";s:3:"man";s:3:"239";s:3:"nce";s:3:"240";s:3:"nle";s:3:"241";s:3:"nun";s:3:"242";s:3:"rak";s:3:"243";s:4:"ık ";s:3:"244";s:3:" en";s:3:"245";s:3:" yo";s:3:"246";s:3:"a g";s:3:"247";s:3:"lis";s:3:"248";s:3:"mak";s:3:"249";s:3:"n g";s:3:"250";s:3:"tir";s:3:"251";s:3:"yas";s:3:"252";s:4:" iş";s:3:"253";s:4:" yö";s:3:"254";s:3:"ale";s:3:"255";s:3:"bil";s:3:"256";s:3:"bul";s:3:"257";s:3:"et ";s:3:"258";s:3:"i d";s:3:"259";s:3:"iye";s:3:"260";s:3:"kil";s:3:"261";s:3:"ma ";s:3:"262";s:3:"n e";s:3:"263";s:3:"n t";s:3:"264";s:3:"nu ";s:3:"265";s:3:"olu";s:3:"266";s:3:"rla";s:3:"267";s:3:"te ";s:3:"268";s:4:"yön";s:3:"269";s:5:"çık";s:3:"270";s:3:" ay";s:3:"271";s:4:" mü";s:3:"272";s:4:" ço";s:3:"273";s:5:" çı";s:3:"274";s:3:"a a";s:3:"275";s:3:"a b";s:3:"276";s:3:"ata";s:3:"277";s:3:"der";s:3:"278";s:3:"gel";s:3:"279";s:3:"i g";s:3:"280";s:3:"i i";s:3:"281";s:3:"ill";s:3:"282";s:3:"ist";s:3:"283";s:4:"ldı";s:3:"284";s:3:"lu ";s:3:"285";s:3:"mek";s:3:"286";s:3:"mle";s:3:"287";s:4:"n ç";s:3:"288";s:3:"onu";s:3:"289";s:3:"opl";s:3:"290";s:3:"ran";s:3:"291";s:3:"rat";s:3:"292";s:4:"rdı";s:3:"293";s:3:"rke";s:3:"294";s:3:"siy";s:3:"295";s:3:"son";s:3:"296";s:3:"ta ";s:3:"297";s:5:"tçı";s:3:"298";s:4:"tın";s:3:"299";}s:9:"ukrainian";a:300:{s:5:" на";s:1:"0";s:5:" за";s:1:"1";s:6:"ння";s:1:"2";s:5:"ня ";s:1:"3";s:5:"на ";s:1:"4";s:5:" пр";s:1:"5";s:6:"ого";s:1:"6";s:5:"го ";s:1:"7";s:6:"ськ";s:1:"8";s:5:" по";s:1:"9";s:4:" у ";s:2:"10";s:6:"від";s:2:"11";s:6:"ере";s:2:"12";s:5:" мі";s:2:"13";s:5:" не";s:2:"14";s:5:"их ";s:2:"15";s:5:"ть ";s:2:"16";s:6:"пер";s:2:"17";s:5:" ві";s:2:"18";s:5:"ів ";s:2:"19";s:5:" пе";s:2:"20";s:5:" що";s:2:"21";s:6:"льн";s:2:"22";s:5:"ми ";s:2:"23";s:5:"ні ";s:2:"24";s:5:"не ";s:2:"25";s:5:"ти ";s:2:"26";s:6:"ати";s:2:"27";s:6:"енн";s:2:"28";s:6:"міс";s:2:"29";s:6:"пра";s:2:"30";s:6:"ува";s:2:"31";s:6:"ник";s:2:"32";s:6:"про";s:2:"33";s:6:"рав";s:2:"34";s:6:"івн";s:2:"35";s:5:" та";s:2:"36";s:6:"буд";s:2:"37";s:6:"влі";s:2:"38";s:6:"рів";s:2:"39";s:5:" ко";s:2:"40";s:5:" рі";s:2:"41";s:6:"аль";s:2:"42";s:5:"но ";s:2:"43";s:6:"ому";s:2:"44";s:5:"що ";s:2:"45";s:5:" ви";s:2:"46";s:5:"му ";s:2:"47";s:6:"рев";s:2:"48";s:5:"ся ";s:2:"49";s:6:"інн";s:2:"50";s:5:" до";s:2:"51";s:5:" уп";s:2:"52";s:6:"авл";s:2:"53";s:6:"анн";s:2:"54";s:6:"ком";s:2:"55";s:5:"ли ";s:2:"56";s:6:"лін";s:2:"57";s:6:"ног";s:2:"58";s:6:"упр";s:2:"59";s:5:" бу";s:2:"60";s:4:" з ";s:2:"61";s:5:" ро";s:2:"62";s:5:"за ";s:2:"63";s:5:"и н";s:2:"64";s:6:"нов";s:2:"65";s:6:"оро";s:2:"66";s:6:"ост";s:2:"67";s:6:"ста";s:2:"68";s:5:"ті ";s:2:"69";s:6:"ють";s:2:"70";s:5:" мо";s:2:"71";s:5:" ні";s:2:"72";s:5:" як";s:2:"73";s:6:"бор";s:2:"74";s:5:"ва ";s:2:"75";s:6:"ван";s:2:"76";s:6:"ень";s:2:"77";s:5:"и п";s:2:"78";s:5:"нь ";s:2:"79";s:6:"ові";s:2:"80";s:6:"рон";s:2:"81";s:6:"сті";s:2:"82";s:5:"та ";s:2:"83";s:5:"у в";s:2:"84";s:6:"ько";s:2:"85";s:6:"іст";s:2:"86";s:4:" в ";s:2:"87";s:5:" ре";s:2:"88";s:5:"до ";s:2:"89";s:5:"е п";s:2:"90";s:6:"заб";s:2:"91";s:5:"ий ";s:2:"92";s:6:"нсь";s:2:"93";s:5:"о в";s:2:"94";s:5:"о п";s:2:"95";s:6:"при";s:2:"96";s:5:"і п";s:2:"97";s:5:" ку";s:2:"98";s:5:" пі";s:2:"99";s:5:" сп";s:3:"100";s:5:"а п";s:3:"101";s:6:"або";s:3:"102";s:6:"анс";s:3:"103";s:6:"аці";s:3:"104";s:6:"ват";s:3:"105";s:6:"вни";s:3:"106";s:5:"и в";s:3:"107";s:6:"ими";s:3:"108";s:5:"ка ";s:3:"109";s:6:"нен";s:3:"110";s:6:"ніч";s:3:"111";s:6:"она";s:3:"112";s:5:"ої ";s:3:"113";s:6:"пов";s:3:"114";s:6:"ьки";s:3:"115";s:6:"ьно";s:3:"116";s:6:"ізн";s:3:"117";s:6:"ічн";s:3:"118";s:5:" ав";s:3:"119";s:5:" ма";s:3:"120";s:5:" ор";s:3:"121";s:5:" су";s:3:"122";s:5:" чи";s:3:"123";s:5:" ін";s:3:"124";s:5:"а з";s:3:"125";s:5:"ам ";s:3:"126";s:5:"ає ";s:3:"127";s:6:"вне";s:3:"128";s:6:"вто";s:3:"129";s:6:"дом";s:3:"130";s:6:"ент";s:3:"131";s:6:"жит";s:3:"132";s:6:"зни";s:3:"133";s:5:"им ";s:3:"134";s:6:"итл";s:3:"135";s:5:"ла ";s:3:"136";s:6:"них";s:3:"137";s:6:"ниц";s:3:"138";s:6:"ова";s:3:"139";s:6:"ови";s:3:"140";s:5:"ом ";s:3:"141";s:6:"пор";s:3:"142";s:6:"тьс";s:3:"143";s:5:"у р";s:3:"144";s:6:"ься";s:3:"145";s:6:"ідо";s:3:"146";s:6:"іль";s:3:"147";s:6:"ісь";s:3:"148";s:5:" ва";s:3:"149";s:5:" ді";s:3:"150";s:5:" жи";s:3:"151";s:5:" че";s:3:"152";s:4:" і ";s:3:"153";s:5:"а в";s:3:"154";s:5:"а н";s:3:"155";s:6:"али";s:3:"156";s:6:"вез";s:3:"157";s:6:"вно";s:3:"158";s:6:"еве";s:3:"159";s:6:"езе";s:3:"160";s:6:"зен";s:3:"161";s:6:"ицт";s:3:"162";s:5:"ки ";s:3:"163";s:6:"ких";s:3:"164";s:6:"кон";s:3:"165";s:5:"ку ";s:3:"166";s:6:"лас";s:3:"167";s:5:"ля ";s:3:"168";s:6:"мож";s:3:"169";s:6:"нач";s:3:"170";s:6:"ним";s:3:"171";s:6:"ної";s:3:"172";s:5:"о б";s:3:"173";s:6:"ову";s:3:"174";s:6:"оди";s:3:"175";s:5:"ою ";s:3:"176";s:5:"ро ";s:3:"177";s:6:"рок";s:3:"178";s:6:"сно";s:3:"179";s:6:"спо";s:3:"180";s:6:"так";s:3:"181";s:6:"тва";s:3:"182";s:5:"ту ";s:3:"183";s:5:"у п";s:3:"184";s:6:"цтв";s:3:"185";s:6:"ьни";s:3:"186";s:5:"я з";s:3:"187";s:5:"і м";s:3:"188";s:5:"ії ";s:3:"189";s:5:" вс";s:3:"190";s:5:" гр";s:3:"191";s:5:" де";s:3:"192";s:5:" но";s:3:"193";s:5:" па";s:3:"194";s:5:" се";s:3:"195";s:5:" ук";s:3:"196";s:5:" їх";s:3:"197";s:5:"а о";s:3:"198";s:6:"авт";s:3:"199";s:6:"аст";s:3:"200";s:6:"ают";s:3:"201";s:6:"вар";s:3:"202";s:6:"ден";s:3:"203";s:5:"ди ";s:3:"204";s:5:"ду ";s:3:"205";s:6:"зна";s:3:"206";s:5:"и з";s:3:"207";s:6:"ико";s:3:"208";s:6:"ися";s:3:"209";s:6:"ити";s:3:"210";s:6:"ког";s:3:"211";s:6:"мен";s:3:"212";s:6:"ном";s:3:"213";s:5:"ну ";s:3:"214";s:5:"о н";s:3:"215";s:5:"о с";s:3:"216";s:6:"обу";s:3:"217";s:6:"ово";s:3:"218";s:6:"пла";s:3:"219";s:6:"ран";s:3:"220";s:6:"рив";s:3:"221";s:6:"роб";s:3:"222";s:6:"ска";s:3:"223";s:6:"тан";s:3:"224";s:6:"тим";s:3:"225";s:6:"тис";s:3:"226";s:5:"то ";s:3:"227";s:6:"тра";s:3:"228";s:6:"удо";s:3:"229";s:6:"чин";s:3:"230";s:6:"чни";s:3:"231";s:5:"і в";s:3:"232";s:5:"ію ";s:3:"233";s:4:" а ";s:3:"234";s:5:" во";s:3:"235";s:5:" да";s:3:"236";s:5:" кв";s:3:"237";s:5:" ме";s:3:"238";s:5:" об";s:3:"239";s:5:" ск";s:3:"240";s:5:" ти";s:3:"241";s:5:" фі";s:3:"242";s:4:" є ";s:3:"243";s:5:"а р";s:3:"244";s:5:"а с";s:3:"245";s:5:"а у";s:3:"246";s:5:"ак ";s:3:"247";s:6:"ані";s:3:"248";s:6:"арт";s:3:"249";s:6:"асн";s:3:"250";s:5:"в у";s:3:"251";s:6:"вик";s:3:"252";s:6:"віз";s:3:"253";s:6:"дов";s:3:"254";s:6:"дпо";s:3:"255";s:6:"дів";s:3:"256";s:6:"еві";s:3:"257";s:6:"енс";s:3:"258";s:5:"же ";s:3:"259";s:5:"и м";s:3:"260";s:5:"и с";s:3:"261";s:6:"ика";s:3:"262";s:6:"ичн";s:3:"263";s:5:"кі ";s:3:"264";s:6:"ків";s:3:"265";s:6:"між";s:3:"266";s:6:"нан";s:3:"267";s:6:"нос";s:3:"268";s:5:"о у";s:3:"269";s:6:"обл";s:3:"270";s:6:"одн";s:3:"271";s:5:"ок ";s:3:"272";s:6:"оло";s:3:"273";s:6:"отр";s:3:"274";s:6:"рен";s:3:"275";s:6:"рим";s:3:"276";s:6:"роз";s:3:"277";s:5:"сь ";s:3:"278";s:5:"сі ";s:3:"279";s:6:"тла";s:3:"280";s:6:"тів";s:3:"281";s:5:"у з";s:3:"282";s:6:"уго";s:3:"283";s:6:"уді";s:3:"284";s:5:"чи ";s:3:"285";s:5:"ше ";s:3:"286";s:5:"я н";s:3:"287";s:5:"я у";s:3:"288";s:6:"ідп";s:3:"289";s:5:"ій ";s:3:"290";s:6:"іна";s:3:"291";s:5:"ія ";s:3:"292";s:5:" ка";s:3:"293";s:5:" ни";s:3:"294";s:5:" ос";s:3:"295";s:5:" си";s:3:"296";s:5:" то";s:3:"297";s:5:" тр";s:3:"298";s:5:" уг";s:3:"299";}s:4:"urdu";a:300:{s:5:"یں ";s:1:"0";s:5:" کی";s:1:"1";s:5:"کے ";s:1:"2";s:5:" کے";s:1:"3";s:5:"نے ";s:1:"4";s:5:" کہ";s:1:"5";s:5:"ے ک";s:1:"6";s:5:"کی ";s:1:"7";s:6:"میں";s:1:"8";s:5:" می";s:1:"9";s:5:"ہے ";s:2:"10";s:5:"وں ";s:2:"11";s:5:"کہ ";s:2:"12";s:5:" ہے";s:2:"13";s:5:"ان ";s:2:"14";s:6:"ہیں";s:2:"15";s:5:"ور ";s:2:"16";s:5:" کو";s:2:"17";s:5:"یا ";s:2:"18";s:5:" ان";s:2:"19";s:5:" نے";s:2:"20";s:5:"سے ";s:2:"21";s:5:" سے";s:2:"22";s:5:" کر";s:2:"23";s:6:"ستا";s:2:"24";s:5:" او";s:2:"25";s:6:"اور";s:2:"26";s:6:"تان";s:2:"27";s:5:"ر ک";s:2:"28";s:5:"ی ک";s:2:"29";s:5:" اس";s:2:"30";s:5:"ے ا";s:2:"31";s:5:" پا";s:2:"32";s:5:" ہو";s:2:"33";s:5:" پر";s:2:"34";s:5:"رف ";s:2:"35";s:5:" کا";s:2:"36";s:5:"ا ک";s:2:"37";s:5:"ی ا";s:2:"38";s:5:" ہی";s:2:"39";s:5:"در ";s:2:"40";s:5:"کو ";s:2:"41";s:5:" ای";s:2:"42";s:5:"ں ک";s:2:"43";s:5:" مش";s:2:"44";s:5:" مل";s:2:"45";s:5:"ات ";s:2:"46";s:6:"صدر";s:2:"47";s:6:"اکس";s:2:"48";s:6:"شرف";s:2:"49";s:6:"مشر";s:2:"50";s:6:"پاک";s:2:"51";s:6:"کست";s:2:"52";s:5:"ی م";s:2:"53";s:5:" دی";s:2:"54";s:5:" صد";s:2:"55";s:5:" یہ";s:2:"56";s:5:"ا ہ";s:2:"57";s:5:"ن ک";s:2:"58";s:6:"وال";s:2:"59";s:5:"یہ ";s:2:"60";s:5:"ے و";s:2:"61";s:5:" بھ";s:2:"62";s:5:" دو";s:2:"63";s:5:"اس ";s:2:"64";s:5:"ر ا";s:2:"65";s:6:"نہی";s:2:"66";s:5:"کا ";s:2:"67";s:5:"ے س";s:2:"68";s:5:"ئی ";s:2:"69";s:5:"ہ ا";s:2:"70";s:5:"یت ";s:2:"71";s:5:"ے ہ";s:2:"72";s:5:"ت ک";s:2:"73";s:5:" سا";s:2:"74";s:5:"لے ";s:2:"75";s:5:"ہا ";s:2:"76";s:5:"ے ب";s:2:"77";s:5:" وا";s:2:"78";s:5:"ار ";s:2:"79";s:5:"نی ";s:2:"80";s:6:"کہا";s:2:"81";s:5:"ی ہ";s:2:"82";s:5:"ے م";s:2:"83";s:5:" سی";s:2:"84";s:5:" لی";s:2:"85";s:6:"انہ";s:2:"86";s:6:"انی";s:2:"87";s:5:"ر م";s:2:"88";s:5:"ر پ";s:2:"89";s:6:"ریت";s:2:"90";s:5:"ن م";s:2:"91";s:5:"ھا ";s:2:"92";s:5:"یر ";s:2:"93";s:5:" جا";s:2:"94";s:5:" جن";s:2:"95";s:5:"ئے ";s:2:"96";s:5:"پر ";s:2:"97";s:5:"ں ن";s:2:"98";s:5:"ہ ک";s:2:"99";s:5:"ی و";s:3:"100";s:5:"ے د";s:3:"101";s:5:" تو";s:3:"102";s:5:" تھ";s:3:"103";s:5:" گی";s:3:"104";s:6:"ایک";s:3:"105";s:5:"ل ک";s:3:"106";s:5:"نا ";s:3:"107";s:5:"کر ";s:3:"108";s:5:"ں م";s:3:"109";s:5:"یک ";s:3:"110";s:5:" با";s:3:"111";s:5:"ا ت";s:3:"112";s:5:"دی ";s:3:"113";s:5:"ن س";s:3:"114";s:6:"کیا";s:3:"115";s:6:"یوں";s:3:"116";s:5:"ے ج";s:3:"117";s:5:"ال ";s:3:"118";s:5:"تو ";s:3:"119";s:5:"ں ا";s:3:"120";s:5:"ے پ";s:3:"121";s:5:" چا";s:3:"122";s:5:"ام ";s:3:"123";s:6:"بھی";s:3:"124";s:5:"تی ";s:3:"125";s:5:"تے ";s:3:"126";s:6:"دوس";s:3:"127";s:5:"س ک";s:3:"128";s:6:"ملک";s:3:"129";s:5:"ن ا";s:3:"130";s:6:"ہور";s:3:"131";s:5:"یے ";s:3:"132";s:5:" مو";s:3:"133";s:5:" وک";s:3:"134";s:6:"ائی";s:3:"135";s:6:"ارت";s:3:"136";s:6:"الے";s:3:"137";s:6:"بھا";s:3:"138";s:6:"ردی";s:3:"139";s:5:"ری ";s:3:"140";s:5:"وہ ";s:3:"141";s:6:"ویز";s:3:"142";s:5:"ں د";s:3:"143";s:5:"ھی ";s:3:"144";s:5:"ی س";s:3:"145";s:5:" رہ";s:3:"146";s:5:" من";s:3:"147";s:5:" نہ";s:3:"148";s:5:" ور";s:3:"149";s:5:" وہ";s:3:"150";s:5:" ہن";s:3:"151";s:5:"ا ا";s:3:"152";s:6:"است";s:3:"153";s:5:"ت ا";s:3:"154";s:5:"ت پ";s:3:"155";s:5:"د ک";s:3:"156";s:5:"ز م";s:3:"157";s:5:"ند ";s:3:"158";s:6:"ورد";s:3:"159";s:6:"وکل";s:3:"160";s:5:"گی ";s:3:"161";s:6:"گیا";s:3:"162";s:5:"ہ پ";s:3:"163";s:5:"یز ";s:3:"164";s:5:"ے ت";s:3:"165";s:5:" اع";s:3:"166";s:5:" اپ";s:3:"167";s:5:" جس";s:3:"168";s:5:" جم";s:3:"169";s:5:" جو";s:3:"170";s:5:" سر";s:3:"171";s:6:"اپن";s:3:"172";s:6:"اکث";s:3:"173";s:6:"تھا";s:3:"174";s:6:"ثری";s:3:"175";s:6:"دیا";s:3:"176";s:5:"ر د";s:3:"177";s:5:"رت ";s:3:"178";s:6:"روی";s:3:"179";s:5:"سی ";s:3:"180";s:6:"ملا";s:3:"181";s:6:"ندو";s:3:"182";s:6:"وست";s:3:"183";s:6:"پرو";s:3:"184";s:6:"چاہ";s:3:"185";s:6:"کثر";s:3:"186";s:6:"کلا";s:3:"187";s:5:"ہ ہ";s:3:"188";s:6:"ہند";s:3:"189";s:5:"ہو ";s:3:"190";s:5:"ے ل";s:3:"191";s:5:" اک";s:3:"192";s:5:" دا";s:3:"193";s:5:" سن";s:3:"194";s:5:" وز";s:3:"195";s:5:" پی";s:3:"196";s:5:"ا چ";s:3:"197";s:5:"اء ";s:3:"198";s:6:"اتھ";s:3:"199";s:6:"اقا";s:3:"200";s:5:"اہ ";s:3:"201";s:5:"تھ ";s:3:"202";s:5:"دو ";s:3:"203";s:5:"ر ب";s:3:"204";s:6:"روا";s:3:"205";s:5:"رے ";s:3:"206";s:6:"سات";s:3:"207";s:5:"ف ک";s:3:"208";s:6:"قات";s:3:"209";s:5:"لا ";s:3:"210";s:6:"لاء";s:3:"211";s:5:"م م";s:3:"212";s:5:"م ک";s:3:"213";s:5:"من ";s:3:"214";s:6:"نوں";s:3:"215";s:5:"و ا";s:3:"216";s:6:"کرن";s:3:"217";s:5:"ں ہ";s:3:"218";s:6:"ھار";s:3:"219";s:6:"ہوئ";s:3:"220";s:5:"ہی ";s:3:"221";s:5:"یش ";s:3:"222";s:5:" ام";s:3:"223";s:5:" لا";s:3:"224";s:5:" مس";s:3:"225";s:5:" پو";s:3:"226";s:5:" پہ";s:3:"227";s:6:"انے";s:3:"228";s:5:"ت م";s:3:"229";s:5:"ت ہ";s:3:"230";s:5:"ج ک";s:3:"231";s:6:"دون";s:3:"232";s:6:"زیر";s:3:"233";s:5:"س س";s:3:"234";s:5:"ش ک";s:3:"235";s:5:"ف ن";s:3:"236";s:5:"ل ہ";s:3:"237";s:6:"لاق";s:3:"238";s:5:"لی ";s:3:"239";s:6:"وری";s:3:"240";s:6:"وزی";s:3:"241";s:6:"ونو";s:3:"242";s:6:"کھن";s:3:"243";s:5:"گا ";s:3:"244";s:5:"ں س";s:3:"245";s:5:"ں گ";s:3:"246";s:6:"ھنے";s:3:"247";s:5:"ھے ";s:3:"248";s:5:"ہ ب";s:3:"249";s:5:"ہ ج";s:3:"250";s:5:"ہر ";s:3:"251";s:5:"ی آ";s:3:"252";s:5:"ی پ";s:3:"253";s:5:" حا";s:3:"254";s:5:" وف";s:3:"255";s:5:" گا";s:3:"256";s:5:"ا ج";s:3:"257";s:5:"ا گ";s:3:"258";s:5:"اد ";s:3:"259";s:6:"ادی";s:3:"260";s:6:"اعظ";s:3:"261";s:6:"اہت";s:3:"262";s:5:"جس ";s:3:"263";s:6:"جمہ";s:3:"264";s:5:"جو ";s:3:"265";s:5:"ر س";s:3:"266";s:5:"ر ہ";s:3:"267";s:6:"رنے";s:3:"268";s:5:"س م";s:3:"269";s:5:"سا ";s:3:"270";s:6:"سند";s:3:"271";s:6:"سنگ";s:3:"272";s:5:"ظم ";s:3:"273";s:6:"عظم";s:3:"274";s:5:"ل م";s:3:"275";s:6:"لیے";s:3:"276";s:5:"مل ";s:3:"277";s:6:"موہ";s:3:"278";s:6:"مہو";s:3:"279";s:6:"نگھ";s:3:"280";s:5:"و ص";s:3:"281";s:6:"ورٹ";s:3:"282";s:6:"وہن";s:3:"283";s:5:"کن ";s:3:"284";s:5:"گھ ";s:3:"285";s:5:"گے ";s:3:"286";s:5:"ں ج";s:3:"287";s:5:"ں و";s:3:"288";s:5:"ں ی";s:3:"289";s:5:"ہ د";s:3:"290";s:5:"ہن ";s:3:"291";s:6:"ہوں";s:3:"292";s:5:"ے ح";s:3:"293";s:5:"ے گ";s:3:"294";s:5:"ے ی";s:3:"295";s:5:" اگ";s:3:"296";s:5:" بع";s:3:"297";s:5:" رو";s:3:"298";s:5:" شا";s:3:"299";}s:5:"uzbek";a:300:{s:5:"ан ";s:1:"0";s:6:"ган";s:1:"1";s:6:"лар";s:1:"2";s:5:"га ";s:1:"3";s:5:"нг ";s:1:"4";s:6:"инг";s:1:"5";s:6:"нин";s:1:"6";s:5:"да ";s:1:"7";s:5:"ни ";s:1:"8";s:6:"ида";s:1:"9";s:6:"ари";s:2:"10";s:6:"ига";s:2:"11";s:6:"ини";s:2:"12";s:5:"ар ";s:2:"13";s:5:"ди ";s:2:"14";s:5:" би";s:2:"15";s:6:"ани";s:2:"16";s:5:" бо";s:2:"17";s:6:"дан";s:2:"18";s:6:"лга";s:2:"19";s:5:" ҳа";s:2:"20";s:5:" ва";s:2:"21";s:5:" са";s:2:"22";s:5:"ги ";s:2:"23";s:6:"ила";s:2:"24";s:5:"н б";s:2:"25";s:5:"и б";s:2:"26";s:5:" кў";s:2:"27";s:5:" та";s:2:"28";s:5:"ир ";s:2:"29";s:5:" ма";s:2:"30";s:6:"ага";s:2:"31";s:6:"ала";s:2:"32";s:6:"бир";s:2:"33";s:5:"ри ";s:2:"34";s:6:"тга";s:2:"35";s:6:"лан";s:2:"36";s:6:"лик";s:2:"37";s:5:"а к";s:2:"38";s:6:"аги";s:2:"39";s:6:"ати";s:2:"40";s:5:"та ";s:2:"41";s:6:"ади";s:2:"42";s:6:"даг";s:2:"43";s:6:"рга";s:2:"44";s:5:" йи";s:2:"45";s:5:" ми";s:2:"46";s:5:" па";s:2:"47";s:5:" бў";s:2:"48";s:5:" қа";s:2:"49";s:5:" қи";s:2:"50";s:5:"а б";s:2:"51";s:6:"илл";s:2:"52";s:5:"ли ";s:2:"53";s:6:"аси";s:2:"54";s:5:"и т";s:2:"55";s:5:"ик ";s:2:"56";s:6:"или";s:2:"57";s:6:"лла";s:2:"58";s:6:"ард";s:2:"59";s:6:"вчи";s:2:"60";s:5:"ва ";s:2:"61";s:5:"иб ";s:2:"62";s:6:"ири";s:2:"63";s:6:"лиг";s:2:"64";s:6:"нга";s:2:"65";s:6:"ран";s:2:"66";s:5:" ке";s:2:"67";s:5:" ўз";s:2:"68";s:5:"а с";s:2:"69";s:6:"ахт";s:2:"70";s:6:"бўл";s:2:"71";s:6:"иги";s:2:"72";s:6:"кўр";s:2:"73";s:6:"рда";s:2:"74";s:6:"рни";s:2:"75";s:5:"са ";s:2:"76";s:5:" бе";s:2:"77";s:5:" бу";s:2:"78";s:5:" да";s:2:"79";s:5:" жа";s:2:"80";s:5:"а т";s:2:"81";s:6:"ази";s:2:"82";s:6:"ери";s:2:"83";s:5:"и а";s:2:"84";s:6:"илг";s:2:"85";s:6:"йил";s:2:"86";s:6:"ман";s:2:"87";s:6:"пах";s:2:"88";s:6:"рид";s:2:"89";s:5:"ти ";s:2:"90";s:6:"увч";s:2:"91";s:6:"хта";s:2:"92";s:5:" не";s:2:"93";s:5:" со";s:2:"94";s:5:" уч";s:2:"95";s:6:"айт";s:2:"96";s:6:"лли";s:2:"97";s:6:"тла";s:2:"98";s:5:" ай";s:2:"99";s:5:" фр";s:3:"100";s:5:" эт";s:3:"101";s:5:" ҳо";s:3:"102";s:5:"а қ";s:3:"103";s:6:"али";s:3:"104";s:6:"аро";s:3:"105";s:6:"бер";s:3:"106";s:6:"бил";s:3:"107";s:6:"бор";s:3:"108";s:6:"ими";s:3:"109";s:6:"ист";s:3:"110";s:5:"он ";s:3:"111";s:6:"рин";s:3:"112";s:6:"тер";s:3:"113";s:6:"тил";s:3:"114";s:5:"ун ";s:3:"115";s:6:"фра";s:3:"116";s:6:"қил";s:3:"117";s:5:" ба";s:3:"118";s:5:" ол";s:3:"119";s:6:"анс";s:3:"120";s:6:"ефт";s:3:"121";s:6:"зир";s:3:"122";s:6:"кат";s:3:"123";s:6:"мил";s:3:"124";s:6:"неф";s:3:"125";s:6:"саг";s:3:"126";s:5:"чи ";s:3:"127";s:6:"ўра";s:3:"128";s:5:" на";s:3:"129";s:5:" те";s:3:"130";s:5:" эн";s:3:"131";s:5:"а э";s:3:"132";s:5:"ам ";s:3:"133";s:6:"арн";s:3:"134";s:5:"ат ";s:3:"135";s:5:"иш ";s:3:"136";s:5:"ма ";s:3:"137";s:6:"нла";s:3:"138";s:6:"рли";s:3:"139";s:6:"чил";s:3:"140";s:6:"шга";s:3:"141";s:5:" иш";s:3:"142";s:5:" му";s:3:"143";s:5:" ўқ";s:3:"144";s:6:"ара";s:3:"145";s:6:"ваз";s:3:"146";s:5:"и у";s:3:"147";s:5:"иқ ";s:3:"148";s:6:"моқ";s:3:"149";s:6:"рим";s:3:"150";s:6:"учу";s:3:"151";s:6:"чун";s:3:"152";s:5:"ши ";s:3:"153";s:6:"энг";s:3:"154";s:6:"қув";s:3:"155";s:6:"ҳам";s:3:"156";s:5:" сў";s:3:"157";s:5:" ши";s:3:"158";s:6:"бар";s:3:"159";s:6:"бек";s:3:"160";s:6:"дам";s:3:"161";s:5:"и ҳ";s:3:"162";s:6:"иши";s:3:"163";s:6:"лад";s:3:"164";s:6:"оли";s:3:"165";s:6:"олл";s:3:"166";s:6:"ори";s:3:"167";s:6:"оқд";s:3:"168";s:5:"р б";s:3:"169";s:5:"ра ";s:3:"170";s:6:"рла";s:3:"171";s:6:"уни";s:3:"172";s:5:"фт ";s:3:"173";s:6:"ўлг";s:3:"174";s:6:"ўқу";s:3:"175";s:5:" де";s:3:"176";s:5:" ка";s:3:"177";s:5:" қў";s:3:"178";s:5:"а ў";s:3:"179";s:6:"аба";s:3:"180";s:6:"амм";s:3:"181";s:6:"атл";s:3:"182";s:5:"б к";s:3:"183";s:6:"бош";s:3:"184";s:6:"збе";s:3:"185";s:5:"и в";s:3:"186";s:5:"им ";s:3:"187";s:5:"ин ";s:3:"188";s:6:"ишл";s:3:"189";s:6:"лаб";s:3:"190";s:6:"лей";s:3:"191";s:6:"мин";s:3:"192";s:5:"н д";s:3:"193";s:6:"нда";s:3:"194";s:5:"оқ ";s:3:"195";s:5:"р м";s:3:"196";s:6:"рил";s:3:"197";s:6:"сид";s:3:"198";s:6:"тал";s:3:"199";s:6:"тан";s:3:"200";s:6:"тид";s:3:"201";s:6:"тон";s:3:"202";s:6:"ўзб";s:3:"203";s:5:" ам";s:3:"204";s:5:" ки";s:3:"205";s:5:"а ҳ";s:3:"206";s:6:"анг";s:3:"207";s:6:"анд";s:3:"208";s:6:"арт";s:3:"209";s:6:"аёт";s:3:"210";s:6:"дир";s:3:"211";s:6:"ент";s:3:"212";s:5:"и д";s:3:"213";s:5:"и м";s:3:"214";s:5:"и о";s:3:"215";s:5:"и э";s:3:"216";s:6:"иро";s:3:"217";s:6:"йти";s:3:"218";s:6:"нсу";s:3:"219";s:6:"оди";s:3:"220";s:5:"ор ";s:3:"221";s:5:"си ";s:3:"222";s:6:"тиш";s:3:"223";s:6:"тоб";s:3:"224";s:6:"эти";s:3:"225";s:6:"қар";s:3:"226";s:6:"қда";s:3:"227";s:5:" бл";s:3:"228";s:5:" ге";s:3:"229";s:5:" до";s:3:"230";s:5:" ду";s:3:"231";s:5:" но";s:3:"232";s:5:" пр";s:3:"233";s:5:" ра";s:3:"234";s:5:" фо";s:3:"235";s:5:" қо";s:3:"236";s:5:"а м";s:3:"237";s:5:"а о";s:3:"238";s:6:"айд";s:3:"239";s:6:"ало";s:3:"240";s:6:"ама";s:3:"241";s:6:"бле";s:3:"242";s:5:"г н";s:3:"243";s:6:"дол";s:3:"244";s:6:"ейр";s:3:"245";s:5:"ек ";s:3:"246";s:6:"ерг";s:3:"247";s:6:"жар";s:3:"248";s:6:"зид";s:3:"249";s:5:"и к";s:3:"250";s:5:"и ф";s:3:"251";s:5:"ий ";s:3:"252";s:6:"ило";s:3:"253";s:6:"лди";s:3:"254";s:6:"либ";s:3:"255";s:6:"лин";s:3:"256";s:5:"ми ";s:3:"257";s:6:"мма";s:3:"258";s:5:"н в";s:3:"259";s:5:"н к";s:3:"260";s:5:"н ў";s:3:"261";s:5:"н ҳ";s:3:"262";s:6:"ози";s:3:"263";s:6:"ора";s:3:"264";s:6:"оси";s:3:"265";s:6:"рас";s:3:"266";s:6:"риш";s:3:"267";s:6:"рка";s:3:"268";s:6:"роқ";s:3:"269";s:6:"сто";s:3:"270";s:6:"тин";s:3:"271";s:6:"хат";s:3:"272";s:6:"шир";s:3:"273";s:5:" ав";s:3:"274";s:5:" рў";s:3:"275";s:5:" ту";s:3:"276";s:5:" ўт";s:3:"277";s:5:"а п";s:3:"278";s:6:"авт";s:3:"279";s:6:"ада";s:3:"280";s:6:"аза";s:3:"281";s:6:"анл";s:3:"282";s:5:"б б";s:3:"283";s:6:"бой";s:3:"284";s:5:"бу ";s:3:"285";s:6:"вто";s:3:"286";s:5:"г э";s:3:"287";s:6:"гин";s:3:"288";s:6:"дар";s:3:"289";s:6:"ден";s:3:"290";s:6:"дун";s:3:"291";s:6:"иде";s:3:"292";s:6:"ион";s:3:"293";s:6:"ирл";s:3:"294";s:6:"ишг";s:3:"295";s:6:"йха";s:3:"296";s:6:"кел";s:3:"297";s:6:"кўп";s:3:"298";s:6:"лио";s:3:"299";}s:10:"vietnamese";a:300:{s:3:"ng ";s:1:"0";s:3:" th";s:1:"1";s:3:" ch";s:1:"2";s:3:"g t";s:1:"3";s:3:" nh";s:1:"4";s:4:"ông";s:1:"5";s:3:" kh";s:1:"6";s:3:" tr";s:1:"7";s:3:"nh ";s:1:"8";s:4:" cô";s:1:"9";s:4:"côn";s:2:"10";s:3:" ty";s:2:"11";s:3:"ty ";s:2:"12";s:3:"i t";s:2:"13";s:3:"n t";s:2:"14";s:3:" ng";s:2:"15";s:5:"ại ";s:2:"16";s:3:" ti";s:2:"17";s:3:"ch ";s:2:"18";s:3:"y l";s:2:"19";s:5:"ền ";s:2:"20";s:5:" đư";s:2:"21";s:3:"hi ";s:2:"22";s:5:" gở";s:2:"23";s:5:"gởi";s:2:"24";s:5:"iền";s:2:"25";s:5:"tiề";s:2:"26";s:5:"ởi ";s:2:"27";s:3:" gi";s:2:"28";s:3:" le";s:2:"29";s:3:" vi";s:2:"30";s:3:"cho";s:2:"31";s:3:"ho ";s:2:"32";s:4:"khá";s:2:"33";s:4:" và";s:2:"34";s:4:"hác";s:2:"35";s:3:" ph";s:2:"36";s:3:"am ";s:2:"37";s:4:"hàn";s:2:"38";s:4:"ách";s:2:"39";s:4:"ôi ";s:2:"40";s:3:"i n";s:2:"41";s:6:"ược";s:2:"42";s:5:"ợc ";s:2:"43";s:4:" tô";s:2:"44";s:4:"chú";s:2:"45";s:5:"iệt";s:2:"46";s:4:"tôi";s:2:"47";s:4:"ên ";s:2:"48";s:4:"úng";s:2:"49";s:5:"ệt ";s:2:"50";s:4:" có";s:2:"51";s:3:"c t";s:2:"52";s:4:"có ";s:2:"53";s:4:"hún";s:2:"54";s:5:"việ";s:2:"55";s:7:"đượ";s:2:"56";s:3:" na";s:2:"57";s:3:"g c";s:2:"58";s:3:"i c";s:2:"59";s:3:"n c";s:2:"60";s:3:"n n";s:2:"61";s:3:"t n";s:2:"62";s:4:"và ";s:2:"63";s:3:"n l";s:2:"64";s:4:"n đ";s:2:"65";s:4:"àng";s:2:"66";s:4:"ác ";s:2:"67";s:5:"ất ";s:2:"68";s:3:"h l";s:2:"69";s:3:"nam";s:2:"70";s:4:"ân ";s:2:"71";s:4:"ăm ";s:2:"72";s:4:" hà";s:2:"73";s:4:" là";s:2:"74";s:4:" nă";s:2:"75";s:3:" qu";s:2:"76";s:5:" tạ";s:2:"77";s:3:"g m";s:2:"78";s:4:"năm";s:2:"79";s:5:"tại";s:2:"80";s:5:"ới ";s:2:"81";s:5:" lẹ";s:2:"82";s:3:"ay ";s:2:"83";s:3:"e g";s:2:"84";s:3:"h h";s:2:"85";s:3:"i v";s:2:"86";s:4:"i đ";s:2:"87";s:3:"le ";s:2:"88";s:5:"lẹ ";s:2:"89";s:5:"ều ";s:2:"90";s:5:"ời ";s:2:"91";s:4:"hân";s:2:"92";s:3:"nhi";s:2:"93";s:3:"t t";s:2:"94";s:5:" củ";s:2:"95";s:5:" mộ";s:2:"96";s:5:" về";s:2:"97";s:4:" đi";s:2:"98";s:3:"an ";s:2:"99";s:5:"của";s:3:"100";s:4:"là ";s:3:"101";s:5:"một";s:3:"102";s:5:"về ";s:3:"103";s:4:"ành";s:3:"104";s:5:"ết ";s:3:"105";s:5:"ột ";s:3:"106";s:5:"ủa ";s:3:"107";s:3:" bi";s:3:"108";s:4:" cá";s:3:"109";s:3:"a c";s:3:"110";s:3:"anh";s:3:"111";s:4:"các";s:3:"112";s:3:"h c";s:3:"113";s:5:"iều";s:3:"114";s:3:"m t";s:3:"115";s:5:"ện ";s:3:"116";s:3:" ho";s:3:"117";s:3:"'s ";s:3:"118";s:3:"ave";s:3:"119";s:3:"e's";s:3:"120";s:3:"el ";s:3:"121";s:3:"g n";s:3:"122";s:3:"le'";s:3:"123";s:3:"n v";s:3:"124";s:3:"o c";s:3:"125";s:3:"rav";s:3:"126";s:3:"s t";s:3:"127";s:3:"thi";s:3:"128";s:3:"tra";s:3:"129";s:3:"vel";s:3:"130";s:5:"ận ";s:3:"131";s:5:"ến ";s:3:"132";s:3:" ba";s:3:"133";s:3:" cu";s:3:"134";s:3:" sa";s:3:"135";s:5:" đó";s:3:"136";s:6:" đế";s:3:"137";s:3:"c c";s:3:"138";s:3:"chu";s:3:"139";s:5:"hiề";s:3:"140";s:3:"huy";s:3:"141";s:3:"khi";s:3:"142";s:4:"nhâ";s:3:"143";s:4:"như";s:3:"144";s:3:"ong";s:3:"145";s:3:"ron";s:3:"146";s:3:"thu";s:3:"147";s:4:"thư";s:3:"148";s:3:"tro";s:3:"149";s:3:"y c";s:3:"150";s:4:"ày ";s:3:"151";s:6:"đến";s:3:"152";s:6:"ười";s:3:"153";s:6:"ườn";s:3:"154";s:5:"ề v";s:3:"155";s:5:"ờng";s:3:"156";s:5:" vớ";s:3:"157";s:5:"cuộ";s:3:"158";s:4:"g đ";s:3:"159";s:5:"iết";s:3:"160";s:5:"iện";s:3:"161";s:4:"ngà";s:3:"162";s:3:"o t";s:3:"163";s:3:"u c";s:3:"164";s:5:"uộc";s:3:"165";s:5:"với";s:3:"166";s:4:"à c";s:3:"167";s:4:"ài ";s:3:"168";s:4:"ơng";s:3:"169";s:5:"ươn";s:3:"170";s:5:"ải ";s:3:"171";s:5:"ộc ";s:3:"172";s:5:"ức ";s:3:"173";s:3:" an";s:3:"174";s:5:" lậ";s:3:"175";s:3:" ra";s:3:"176";s:5:" sẽ";s:3:"177";s:5:" số";s:3:"178";s:5:" tổ";s:3:"179";s:3:"a k";s:3:"180";s:5:"biế";s:3:"181";s:3:"c n";s:3:"182";s:4:"c đ";s:3:"183";s:5:"chứ";s:3:"184";s:3:"g v";s:3:"185";s:3:"gia";s:3:"186";s:4:"gày";s:3:"187";s:4:"hán";s:3:"188";s:4:"hôn";s:3:"189";s:4:"hư ";s:3:"190";s:5:"hức";s:3:"191";s:3:"i g";s:3:"192";s:3:"i h";s:3:"193";s:3:"i k";s:3:"194";s:3:"i p";s:3:"195";s:4:"iên";s:3:"196";s:4:"khô";s:3:"197";s:5:"lập";s:3:"198";s:3:"n k";s:3:"199";s:3:"ra ";s:3:"200";s:4:"rên";s:3:"201";s:5:"sẽ ";s:3:"202";s:3:"t c";s:3:"203";s:4:"thà";s:3:"204";s:4:"trê";s:3:"205";s:5:"tổ ";s:3:"206";s:3:"u n";s:3:"207";s:3:"y t";s:3:"208";s:4:"ình";s:3:"209";s:5:"ấy ";s:3:"210";s:5:"ập ";s:3:"211";s:5:"ổ c";s:3:"212";s:4:" má";s:3:"213";s:6:" để";s:3:"214";s:3:"ai ";s:3:"215";s:3:"c s";s:3:"216";s:6:"gườ";s:3:"217";s:3:"h v";s:3:"218";s:3:"hoa";s:3:"219";s:5:"hoạ";s:3:"220";s:3:"inh";s:3:"221";s:3:"m n";s:3:"222";s:4:"máy";s:3:"223";s:3:"n g";s:3:"224";s:4:"ngư";s:3:"225";s:5:"nhậ";s:3:"226";s:3:"o n";s:3:"227";s:3:"oa ";s:3:"228";s:4:"oàn";s:3:"229";s:3:"p c";s:3:"230";s:5:"số ";s:3:"231";s:4:"t đ";s:3:"232";s:3:"y v";s:3:"233";s:4:"ào ";s:3:"234";s:4:"áy ";s:3:"235";s:4:"ăn ";s:3:"236";s:5:"đó ";s:3:"237";s:6:"để ";s:3:"238";s:6:"ước";s:3:"239";s:5:"ần ";s:3:"240";s:5:"ển ";s:3:"241";s:5:"ớc ";s:3:"242";s:4:" bá";s:3:"243";s:4:" cơ";s:3:"244";s:5:" cả";s:3:"245";s:5:" cầ";s:3:"246";s:5:" họ";s:3:"247";s:5:" kỳ";s:3:"248";s:3:" li";s:3:"249";s:5:" mạ";s:3:"250";s:5:" sở";s:3:"251";s:5:" tặ";s:3:"252";s:4:" vé";s:3:"253";s:5:" vụ";s:3:"254";s:6:" đạ";s:3:"255";s:4:"a đ";s:3:"256";s:3:"bay";s:3:"257";s:4:"cơ ";s:3:"258";s:3:"g s";s:3:"259";s:3:"han";s:3:"260";s:5:"hươ";s:3:"261";s:3:"i s";s:3:"262";s:5:"kỳ ";s:3:"263";s:3:"m c";s:3:"264";s:3:"n m";s:3:"265";s:3:"n p";s:3:"266";s:3:"o b";s:3:"267";s:5:"oại";s:3:"268";s:3:"qua";s:3:"269";s:5:"sở ";s:3:"270";s:3:"tha";s:3:"271";s:4:"thá";s:3:"272";s:5:"tặn";s:3:"273";s:4:"vào";s:3:"274";s:4:"vé ";s:3:"275";s:5:"vụ ";s:3:"276";s:3:"y b";s:3:"277";s:4:"àn ";s:3:"278";s:4:"áng";s:3:"279";s:4:"ơ s";s:3:"280";s:5:"ầu ";s:3:"281";s:5:"ật ";s:3:"282";s:5:"ặng";s:3:"283";s:5:"ọc ";s:3:"284";s:5:"ở t";s:3:"285";s:5:"ững";s:3:"286";s:3:" du";s:3:"287";s:3:" lu";s:3:"288";s:3:" ta";s:3:"289";s:3:" to";s:3:"290";s:5:" từ";s:3:"291";s:5:" ở ";s:3:"292";s:3:"a v";s:3:"293";s:3:"ao ";s:3:"294";s:3:"c v";s:3:"295";s:5:"cả ";s:3:"296";s:3:"du ";s:3:"297";s:3:"g l";s:3:"298";s:5:"giả";s:3:"299";}s:5:"welsh";a:300:{s:3:"yn ";s:1:"0";s:3:"dd ";s:1:"1";s:3:" yn";s:1:"2";s:3:" y ";s:1:"3";s:3:"ydd";s:1:"4";s:3:"eth";s:1:"5";s:3:"th ";s:1:"6";s:3:" i ";s:1:"7";s:3:"aet";s:1:"8";s:3:"d y";s:1:"9";s:3:"ch ";s:2:"10";s:3:"od ";s:2:"11";s:3:"ol ";s:2:"12";s:3:"edd";s:2:"13";s:3:" ga";s:2:"14";s:3:" gw";s:2:"15";s:3:"'r ";s:2:"16";s:3:"au ";s:2:"17";s:3:"ddi";s:2:"18";s:3:"ad ";s:2:"19";s:3:" cy";s:2:"20";s:3:" gy";s:2:"21";s:3:" ei";s:2:"22";s:3:" o ";s:2:"23";s:3:"iad";s:2:"24";s:3:"yr ";s:2:"25";s:3:"an ";s:2:"26";s:3:"bod";s:2:"27";s:3:"wed";s:2:"28";s:3:" bo";s:2:"29";s:3:" dd";s:2:"30";s:3:"el ";s:2:"31";s:3:"n y";s:2:"32";s:3:" am";s:2:"33";s:3:"di ";s:2:"34";s:3:"edi";s:2:"35";s:3:"on ";s:2:"36";s:3:" we";s:2:"37";s:3:" ym";s:2:"38";s:3:" ar";s:2:"39";s:3:" rh";s:2:"40";s:3:"odd";s:2:"41";s:3:" ca";s:2:"42";s:3:" ma";s:2:"43";s:3:"ael";s:2:"44";s:3:"oed";s:2:"45";s:3:"dae";s:2:"46";s:3:"n a";s:2:"47";s:3:"dda";s:2:"48";s:3:"er ";s:2:"49";s:3:"h y";s:2:"50";s:3:"all";s:2:"51";s:3:"ei ";s:2:"52";s:3:" ll";s:2:"53";s:3:"am ";s:2:"54";s:3:"eu ";s:2:"55";s:3:"fod";s:2:"56";s:3:"fyd";s:2:"57";s:3:"l y";s:2:"58";s:3:"n g";s:2:"59";s:3:"wyn";s:2:"60";s:3:"d a";s:2:"61";s:3:"i g";s:2:"62";s:3:"mae";s:2:"63";s:3:"neu";s:2:"64";s:3:"os ";s:2:"65";s:3:" ne";s:2:"66";s:3:"d i";s:2:"67";s:3:"dod";s:2:"68";s:3:"dol";s:2:"69";s:3:"n c";s:2:"70";s:3:"r h";s:2:"71";s:3:"wyd";s:2:"72";s:3:"wyr";s:2:"73";s:3:"ai ";s:2:"74";s:3:"ar ";s:2:"75";s:3:"in ";s:2:"76";s:3:"rth";s:2:"77";s:3:" fy";s:2:"78";s:3:" he";s:2:"79";s:3:" me";s:2:"80";s:3:" yr";s:2:"81";s:3:"'n ";s:2:"82";s:3:"dia";s:2:"83";s:3:"est";s:2:"84";s:3:"h c";s:2:"85";s:3:"hai";s:2:"86";s:3:"i d";s:2:"87";s:3:"id ";s:2:"88";s:3:"r y";s:2:"89";s:3:"y b";s:2:"90";s:3:" dy";s:2:"91";s:3:" ha";s:2:"92";s:3:"ada";s:2:"93";s:3:"i b";s:2:"94";s:3:"n i";s:2:"95";s:3:"ote";s:2:"96";s:3:"rot";s:2:"97";s:3:"tes";s:2:"98";s:3:"y g";s:2:"99";s:3:"yd ";s:3:"100";s:3:" ad";s:3:"101";s:3:" mr";s:3:"102";s:3:" un";s:3:"103";s:3:"cyn";s:3:"104";s:3:"dau";s:3:"105";s:3:"ddy";s:3:"106";s:3:"edo";s:3:"107";s:3:"i c";s:3:"108";s:3:"i w";s:3:"109";s:3:"ith";s:3:"110";s:3:"lae";s:3:"111";s:3:"lla";s:3:"112";s:3:"nd ";s:3:"113";s:3:"oda";s:3:"114";s:3:"ryd";s:3:"115";s:3:"tho";s:3:"116";s:3:" a ";s:3:"117";s:3:" dr";s:3:"118";s:3:"aid";s:3:"119";s:3:"ain";s:3:"120";s:3:"ddo";s:3:"121";s:3:"dyd";s:3:"122";s:3:"fyn";s:3:"123";s:3:"gyn";s:3:"124";s:3:"hol";s:3:"125";s:3:"io ";s:3:"126";s:3:"o a";s:3:"127";s:3:"wch";s:3:"128";s:3:"wyb";s:3:"129";s:3:"ybo";s:3:"130";s:3:"ych";s:3:"131";s:3:" br";s:3:"132";s:3:" by";s:3:"133";s:3:" di";s:3:"134";s:3:" fe";s:3:"135";s:3:" na";s:3:"136";s:3:" o'";s:3:"137";s:3:" pe";s:3:"138";s:3:"art";s:3:"139";s:3:"byd";s:3:"140";s:3:"dro";s:3:"141";s:3:"gal";s:3:"142";s:3:"l e";s:3:"143";s:3:"lai";s:3:"144";s:3:"mr ";s:3:"145";s:3:"n n";s:3:"146";s:3:"r a";s:3:"147";s:3:"rhy";s:3:"148";s:3:"wn ";s:3:"149";s:3:"ynn";s:3:"150";s:3:" on";s:3:"151";s:3:" r ";s:3:"152";s:3:"cae";s:3:"153";s:3:"d g";s:3:"154";s:3:"d o";s:3:"155";s:3:"d w";s:3:"156";s:3:"gan";s:3:"157";s:3:"gwy";s:3:"158";s:3:"n d";s:3:"159";s:3:"n f";s:3:"160";s:3:"n o";s:3:"161";s:3:"ned";s:3:"162";s:3:"ni ";s:3:"163";s:3:"o'r";s:3:"164";s:3:"r d";s:3:"165";s:3:"ud ";s:3:"166";s:3:"wei";s:3:"167";s:3:"wrt";s:3:"168";s:3:" an";s:3:"169";s:3:" cw";s:3:"170";s:3:" da";s:3:"171";s:3:" ni";s:3:"172";s:3:" pa";s:3:"173";s:3:" pr";s:3:"174";s:3:" wy";s:3:"175";s:3:"d e";s:3:"176";s:3:"dai";s:3:"177";s:3:"dim";s:3:"178";s:3:"eud";s:3:"179";s:3:"gwa";s:3:"180";s:3:"idd";s:3:"181";s:3:"im ";s:3:"182";s:3:"iri";s:3:"183";s:3:"lwy";s:3:"184";s:3:"n b";s:3:"185";s:3:"nol";s:3:"186";s:3:"r o";s:3:"187";s:3:"rwy";s:3:"188";s:3:" ch";s:3:"189";s:3:" er";s:3:"190";s:3:" fo";s:3:"191";s:3:" ge";s:3:"192";s:3:" hy";s:3:"193";s:3:" i'";s:3:"194";s:3:" ro";s:3:"195";s:3:" sa";s:3:"196";s:3:" tr";s:3:"197";s:3:"bob";s:3:"198";s:3:"cwy";s:3:"199";s:3:"cyf";s:3:"200";s:3:"dio";s:3:"201";s:3:"dyn";s:3:"202";s:3:"eit";s:3:"203";s:3:"hel";s:3:"204";s:3:"hyn";s:3:"205";s:3:"ich";s:3:"206";s:3:"ll ";s:3:"207";s:3:"mdd";s:3:"208";s:3:"n r";s:3:"209";s:3:"ond";s:3:"210";s:3:"pro";s:3:"211";s:3:"r c";s:3:"212";s:3:"r g";s:3:"213";s:3:"red";s:3:"214";s:3:"rha";s:3:"215";s:3:"u a";s:3:"216";s:3:"u c";s:3:"217";s:3:"u y";s:3:"218";s:3:"y c";s:3:"219";s:3:"ymd";s:3:"220";s:3:"ymr";s:3:"221";s:3:"yw ";s:3:"222";s:3:" ac";s:3:"223";s:3:" be";s:3:"224";s:3:" bl";s:3:"225";s:3:" co";s:3:"226";s:3:" os";s:3:"227";s:3:"adw";s:3:"228";s:3:"ae ";s:3:"229";s:3:"af ";s:3:"230";s:3:"d p";s:3:"231";s:3:"efn";s:3:"232";s:3:"eic";s:3:"233";s:3:"en ";s:3:"234";s:3:"eol";s:3:"235";s:3:"es ";s:3:"236";s:3:"fer";s:3:"237";s:3:"gel";s:3:"238";s:3:"h g";s:3:"239";s:3:"hod";s:3:"240";s:3:"ied";s:3:"241";s:3:"ir ";s:3:"242";s:3:"laf";s:3:"243";s:3:"n h";s:3:"244";s:3:"na ";s:3:"245";s:3:"nyd";s:3:"246";s:3:"odo";s:3:"247";s:3:"ofy";s:3:"248";s:3:"rdd";s:3:"249";s:3:"rie";s:3:"250";s:3:"ros";s:3:"251";s:3:"stw";s:3:"252";s:3:"twy";s:3:"253";s:3:"yda";s:3:"254";s:3:"yng";s:3:"255";s:3:" at";s:3:"256";s:3:" de";s:3:"257";s:3:" go";s:3:"258";s:3:" id";s:3:"259";s:3:" oe";s:3:"260";s:4:" â ";s:3:"261";s:3:"'ch";s:3:"262";s:3:"ac ";s:3:"263";s:3:"ach";s:3:"264";s:3:"ae'";s:3:"265";s:3:"al ";s:3:"266";s:3:"bl ";s:3:"267";s:3:"d c";s:3:"268";s:3:"d l";s:3:"269";s:3:"dan";s:3:"270";s:3:"dde";s:3:"271";s:3:"ddw";s:3:"272";s:3:"dir";s:3:"273";s:3:"dla";s:3:"274";s:3:"ed ";s:3:"275";s:3:"ela";s:3:"276";s:3:"ell";s:3:"277";s:3:"ene";s:3:"278";s:3:"ewn";s:3:"279";s:3:"gyd";s:3:"280";s:3:"hau";s:3:"281";s:3:"hyw";s:3:"282";s:3:"i a";s:3:"283";s:3:"i f";s:3:"284";s:3:"iol";s:3:"285";s:3:"ion";s:3:"286";s:3:"l a";s:3:"287";s:3:"l i";s:3:"288";s:3:"lia";s:3:"289";s:3:"med";s:3:"290";s:3:"mon";s:3:"291";s:3:"n s";s:3:"292";s:3:"no ";s:3:"293";s:3:"obl";s:3:"294";s:3:"ola";s:3:"295";s:3:"ref";s:3:"296";s:3:"rn ";s:3:"297";s:3:"thi";s:3:"298";s:3:"un ";s:3:"299";}}s:18:"trigram-unicodemap";a:13:{s:11:"Basic Latin";a:38:{s:8:"albanian";i:661;s:5:"azeri";i:653;s:7:"bengali";i:1;s:7:"cebuano";i:750;s:8:"croatian";i:733;s:5:"czech";i:652;s:6:"danish";i:734;s:5:"dutch";i:741;s:7:"english";i:723;s:8:"estonian";i:739;s:7:"finnish";i:743;s:6:"french";i:733;s:6:"german";i:750;s:5:"hausa";i:752;s:8:"hawaiian";i:751;s:9:"hungarian";i:693;s:9:"icelandic";i:662;s:10:"indonesian";i:776;s:7:"italian";i:741;s:5:"latin";i:764;s:7:"latvian";i:693;s:10:"lithuanian";i:738;s:9:"mongolian";i:19;s:9:"norwegian";i:742;s:6:"pidgin";i:702;s:6:"polish";i:701;s:10:"portuguese";i:726;s:8:"romanian";i:714;s:6:"slovak";i:677;s:7:"slovene";i:740;s:6:"somali";i:755;s:7:"spanish";i:749;s:7:"swahili";i:770;s:7:"swedish";i:717;s:7:"tagalog";i:767;s:7:"turkish";i:673;s:10:"vietnamese";i:503;s:5:"welsh";i:728;}s:18:"Latin-1 Supplement";a:21:{s:8:"albanian";i:68;s:5:"azeri";i:10;s:5:"czech";i:51;s:6:"danish";i:13;s:8:"estonian";i:19;s:7:"finnish";i:39;s:6:"french";i:21;s:6:"german";i:8;s:9:"hungarian";i:72;s:9:"icelandic";i:80;s:7:"italian";i:3;s:9:"norwegian";i:5;s:6:"polish";i:6;s:10:"portuguese";i:18;s:8:"romanian";i:9;s:6:"slovak";i:37;s:7:"spanish";i:6;s:7:"swedish";i:26;s:7:"turkish";i:25;s:10:"vietnamese";i:56;s:5:"welsh";i:1;}s:14:"[Malformatted]";a:42:{s:8:"albanian";i:68;s:6:"arabic";i:724;s:5:"azeri";i:109;s:7:"bengali";i:1472;s:9:"bulgarian";i:750;s:8:"croatian";i:10;s:5:"czech";i:78;s:6:"danish";i:13;s:8:"estonian";i:19;s:5:"farsi";i:706;s:7:"finnish";i:39;s:6:"french";i:21;s:6:"german";i:8;s:5:"hausa";i:8;s:5:"hindi";i:1386;s:9:"hungarian";i:74;s:9:"icelandic";i:80;s:7:"italian";i:3;s:6:"kazakh";i:767;s:6:"kyrgyz";i:767;s:7:"latvian";i:56;s:10:"lithuanian";i:30;s:10:"macedonian";i:755;s:9:"mongolian";i:743;s:6:"nepali";i:1514;s:9:"norwegian";i:5;s:6:"pashto";i:677;s:6:"polish";i:45;s:10:"portuguese";i:18;s:8:"romanian";i:31;s:7:"russian";i:759;s:7:"serbian";i:757;s:6:"slovak";i:45;s:7:"slovene";i:10;s:7:"spanish";i:6;s:7:"swedish";i:26;s:7:"turkish";i:87;s:9:"ukrainian";i:748;s:4:"urdu";i:682;s:5:"uzbek";i:773;s:10:"vietnamese";i:289;s:5:"welsh";i:1;}s:6:"Arabic";a:4:{s:6:"arabic";i:724;s:5:"farsi";i:706;s:6:"pashto";i:677;s:4:"urdu";i:682;}s:16:"Latin Extended-B";a:3:{s:5:"azeri";i:73;s:5:"hausa";i:8;s:10:"vietnamese";i:19;}s:16:"Latin Extended-A";a:12:{s:5:"azeri";i:25;s:8:"croatian";i:10;s:5:"czech";i:27;s:9:"hungarian";i:2;s:7:"latvian";i:56;s:10:"lithuanian";i:30;s:6:"polish";i:39;s:8:"romanian";i:22;s:6:"slovak";i:8;s:7:"slovene";i:10;s:7:"turkish";i:62;s:10:"vietnamese";i:20;}s:27:"Combining Diacritical Marks";a:1:{s:5:"azeri";i:1;}s:7:"Bengali";a:1:{s:7:"bengali";i:714;}s:8:"Gujarati";a:1:{s:7:"bengali";i:16;}s:8:"Gurmukhi";a:1:{s:7:"bengali";i:6;}s:8:"Cyrillic";a:9:{s:9:"bulgarian";i:750;s:6:"kazakh";i:767;s:6:"kyrgyz";i:767;s:10:"macedonian";i:755;s:9:"mongolian";i:743;s:7:"russian";i:759;s:7:"serbian";i:757;s:9:"ukrainian";i:748;s:5:"uzbek";i:773;}s:10:"Devanagari";a:2:{s:5:"hindi";i:693;s:6:"nepali";i:757;}s:25:"Latin Extended Additional";a:1:{s:10:"vietnamese";i:97;}}} \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/language-detect/unicode_blocks.dat b/inc/3rdparty/libraries/language-detect/unicode_blocks.dat deleted file mode 100644 index 3b24cd2c..00000000 --- a/inc/3rdparty/libraries/language-detect/unicode_blocks.dat +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | a:145:{i:0;a:3:{i:0;s:6:"0x0000";i:1;s:6:"0x007F";i:2;s:11:"Basic Latin";}i:1;a:3:{i:0;s:6:"0x0080";i:1;s:6:"0x00FF";i:2;s:18:"Latin-1 Supplement";}i:2;a:3:{i:0;s:6:"0x0100";i:1;s:6:"0x017F";i:2;s:16:"Latin Extended-A";}i:3;a:3:{i:0;s:6:"0x0180";i:1;s:6:"0x024F";i:2;s:16:"Latin Extended-B";}i:4;a:3:{i:0;s:6:"0x0250";i:1;s:6:"0x02AF";i:2;s:14:"IPA Extensions";}i:5;a:3:{i:0;s:6:"0x02B0";i:1;s:6:"0x02FF";i:2;s:24:"Spacing Modifier Letters";}i:6;a:3:{i:0;s:6:"0x0300";i:1;s:6:"0x036F";i:2;s:27:"Combining Diacritical Marks";}i:7;a:3:{i:0;s:6:"0x0370";i:1;s:6:"0x03FF";i:2;s:16:"Greek and Coptic";}i:8;a:3:{i:0;s:6:"0x0400";i:1;s:6:"0x04FF";i:2;s:8:"Cyrillic";}i:9;a:3:{i:0;s:6:"0x0500";i:1;s:6:"0x052F";i:2;s:19:"Cyrillic Supplement";}i:10;a:3:{i:0;s:6:"0x0530";i:1;s:6:"0x058F";i:2;s:8:"Armenian";}i:11;a:3:{i:0;s:6:"0x0590";i:1;s:6:"0x05FF";i:2;s:6:"Hebrew";}i:12;a:3:{i:0;s:6:"0x0600";i:1;s:6:"0x06FF";i:2;s:6:"Arabic";}i:13;a:3:{i:0;s:6:"0x0700";i:1;s:6:"0x074F";i:2;s:6:"Syriac";}i:14;a:3:{i:0;s:6:"0x0750";i:1;s:6:"0x077F";i:2;s:17:"Arabic Supplement";}i:15;a:3:{i:0;s:6:"0x0780";i:1;s:6:"0x07BF";i:2;s:6:"Thaana";}i:16;a:3:{i:0;s:6:"0x0900";i:1;s:6:"0x097F";i:2;s:10:"Devanagari";}i:17;a:3:{i:0;s:6:"0x0980";i:1;s:6:"0x09FF";i:2;s:7:"Bengali";}i:18;a:3:{i:0;s:6:"0x0A00";i:1;s:6:"0x0A7F";i:2;s:8:"Gurmukhi";}i:19;a:3:{i:0;s:6:"0x0A80";i:1;s:6:"0x0AFF";i:2;s:8:"Gujarati";}i:20;a:3:{i:0;s:6:"0x0B00";i:1;s:6:"0x0B7F";i:2;s:5:"Oriya";}i:21;a:3:{i:0;s:6:"0x0B80";i:1;s:6:"0x0BFF";i:2;s:5:"Tamil";}i:22;a:3:{i:0;s:6:"0x0C00";i:1;s:6:"0x0C7F";i:2;s:6:"Telugu";}i:23;a:3:{i:0;s:6:"0x0C80";i:1;s:6:"0x0CFF";i:2;s:7:"Kannada";}i:24;a:3:{i:0;s:6:"0x0D00";i:1;s:6:"0x0D7F";i:2;s:9:"Malayalam";}i:25;a:3:{i:0;s:6:"0x0D80";i:1;s:6:"0x0DFF";i:2;s:7:"Sinhala";}i:26;a:3:{i:0;s:6:"0x0E00";i:1;s:6:"0x0E7F";i:2;s:4:"Thai";}i:27;a:3:{i:0;s:6:"0x0E80";i:1;s:6:"0x0EFF";i:2;s:3:"Lao";}i:28;a:3:{i:0;s:6:"0x0F00";i:1;s:6:"0x0FFF";i:2;s:7:"Tibetan";}i:29;a:3:{i:0;s:6:"0x1000";i:1;s:6:"0x109F";i:2;s:7:"Myanmar";}i:30;a:3:{i:0;s:6:"0x10A0";i:1;s:6:"0x10FF";i:2;s:8:"Georgian";}i:31;a:3:{i:0;s:6:"0x1100";i:1;s:6:"0x11FF";i:2;s:11:"Hangul Jamo";}i:32;a:3:{i:0;s:6:"0x1200";i:1;s:6:"0x137F";i:2;s:8:"Ethiopic";}i:33;a:3:{i:0;s:6:"0x1380";i:1;s:6:"0x139F";i:2;s:19:"Ethiopic Supplement";}i:34;a:3:{i:0;s:6:"0x13A0";i:1;s:6:"0x13FF";i:2;s:8:"Cherokee";}i:35;a:3:{i:0;s:6:"0x1400";i:1;s:6:"0x167F";i:2;s:37:"Unified Canadian Aboriginal Syllabics";}i:36;a:3:{i:0;s:6:"0x1680";i:1;s:6:"0x169F";i:2;s:5:"Ogham";}i:37;a:3:{i:0;s:6:"0x16A0";i:1;s:6:"0x16FF";i:2;s:5:"Runic";}i:38;a:3:{i:0;s:6:"0x1700";i:1;s:6:"0x171F";i:2;s:7:"Tagalog";}i:39;a:3:{i:0;s:6:"0x1720";i:1;s:6:"0x173F";i:2;s:7:"Hanunoo";}i:40;a:3:{i:0;s:6:"0x1740";i:1;s:6:"0x175F";i:2;s:5:"Buhid";}i:41;a:3:{i:0;s:6:"0x1760";i:1;s:6:"0x177F";i:2;s:8:"Tagbanwa";}i:42;a:3:{i:0;s:6:"0x1780";i:1;s:6:"0x17FF";i:2;s:5:"Khmer";}i:43;a:3:{i:0;s:6:"0x1800";i:1;s:6:"0x18AF";i:2;s:9:"Mongolian";}i:44;a:3:{i:0;s:6:"0x1900";i:1;s:6:"0x194F";i:2;s:5:"Limbu";}i:45;a:3:{i:0;s:6:"0x1950";i:1;s:6:"0x197F";i:2;s:6:"Tai Le";}i:46;a:3:{i:0;s:6:"0x1980";i:1;s:6:"0x19DF";i:2;s:11:"New Tai Lue";}i:47;a:3:{i:0;s:6:"0x19E0";i:1;s:6:"0x19FF";i:2;s:13:"Khmer Symbols";}i:48;a:3:{i:0;s:6:"0x1A00";i:1;s:6:"0x1A1F";i:2;s:8:"Buginese";}i:49;a:3:{i:0;s:6:"0x1D00";i:1;s:6:"0x1D7F";i:2;s:19:"Phonetic Extensions";}i:50;a:3:{i:0;s:6:"0x1D80";i:1;s:6:"0x1DBF";i:2;s:30:"Phonetic Extensions Supplement";}i:51;a:3:{i:0;s:6:"0x1DC0";i:1;s:6:"0x1DFF";i:2;s:38:"Combining Diacritical Marks Supplement";}i:52;a:3:{i:0;s:6:"0x1E00";i:1;s:6:"0x1EFF";i:2;s:25:"Latin Extended Additional";}i:53;a:3:{i:0;s:6:"0x1F00";i:1;s:6:"0x1FFF";i:2;s:14:"Greek Extended";}i:54;a:3:{i:0;s:6:"0x2000";i:1;s:6:"0x206F";i:2;s:19:"General Punctuation";}i:55;a:3:{i:0;s:6:"0x2070";i:1;s:6:"0x209F";i:2;s:27:"Superscripts and Subscripts";}i:56;a:3:{i:0;s:6:"0x20A0";i:1;s:6:"0x20CF";i:2;s:16:"Currency Symbols";}i:57;a:3:{i:0;s:6:"0x20D0";i:1;s:6:"0x20FF";i:2;s:39:"Combining Diacritical Marks for Symbols";}i:58;a:3:{i:0;s:6:"0x2100";i:1;s:6:"0x214F";i:2;s:18:"Letterlike Symbols";}i:59;a:3:{i:0;s:6:"0x2150";i:1;s:6:"0x218F";i:2;s:12:"Number Forms";}i:60;a:3:{i:0;s:6:"0x2190";i:1;s:6:"0x21FF";i:2;s:6:"Arrows";}i:61;a:3:{i:0;s:6:"0x2200";i:1;s:6:"0x22FF";i:2;s:22:"Mathematical Operators";}i:62;a:3:{i:0;s:6:"0x2300";i:1;s:6:"0x23FF";i:2;s:23:"Miscellaneous Technical";}i:63;a:3:{i:0;s:6:"0x2400";i:1;s:6:"0x243F";i:2;s:16:"Control Pictures";}i:64;a:3:{i:0;s:6:"0x2440";i:1;s:6:"0x245F";i:2;s:29:"Optical Character Recognition";}i:65;a:3:{i:0;s:6:"0x2460";i:1;s:6:"0x24FF";i:2;s:22:"Enclosed Alphanumerics";}i:66;a:3:{i:0;s:6:"0x2500";i:1;s:6:"0x257F";i:2;s:11:"Box Drawing";}i:67;a:3:{i:0;s:6:"0x2580";i:1;s:6:"0x259F";i:2;s:14:"Block Elements";}i:68;a:3:{i:0;s:6:"0x25A0";i:1;s:6:"0x25FF";i:2;s:16:"Geometric Shapes";}i:69;a:3:{i:0;s:6:"0x2600";i:1;s:6:"0x26FF";i:2;s:21:"Miscellaneous Symbols";}i:70;a:3:{i:0;s:6:"0x2700";i:1;s:6:"0x27BF";i:2;s:8:"Dingbats";}i:71;a:3:{i:0;s:6:"0x27C0";i:1;s:6:"0x27EF";i:2;s:36:"Miscellaneous Mathematical Symbols-A";}i:72;a:3:{i:0;s:6:"0x27F0";i:1;s:6:"0x27FF";i:2;s:21:"Supplemental Arrows-A";}i:73;a:3:{i:0;s:6:"0x2800";i:1;s:6:"0x28FF";i:2;s:16:"Braille Patterns";}i:74;a:3:{i:0;s:6:"0x2900";i:1;s:6:"0x297F";i:2;s:21:"Supplemental Arrows-B";}i:75;a:3:{i:0;s:6:"0x2980";i:1;s:6:"0x29FF";i:2;s:36:"Miscellaneous Mathematical Symbols-B";}i:76;a:3:{i:0;s:6:"0x2A00";i:1;s:6:"0x2AFF";i:2;s:35:"Supplemental Mathematical Operators";}i:77;a:3:{i:0;s:6:"0x2B00";i:1;s:6:"0x2BFF";i:2;s:32:"Miscellaneous Symbols and Arrows";}i:78;a:3:{i:0;s:6:"0x2C00";i:1;s:6:"0x2C5F";i:2;s:10:"Glagolitic";}i:79;a:3:{i:0;s:6:"0x2C80";i:1;s:6:"0x2CFF";i:2;s:6:"Coptic";}i:80;a:3:{i:0;s:6:"0x2D00";i:1;s:6:"0x2D2F";i:2;s:19:"Georgian Supplement";}i:81;a:3:{i:0;s:6:"0x2D30";i:1;s:6:"0x2D7F";i:2;s:8:"Tifinagh";}i:82;a:3:{i:0;s:6:"0x2D80";i:1;s:6:"0x2DDF";i:2;s:17:"Ethiopic Extended";}i:83;a:3:{i:0;s:6:"0x2E00";i:1;s:6:"0x2E7F";i:2;s:24:"Supplemental Punctuation";}i:84;a:3:{i:0;s:6:"0x2E80";i:1;s:6:"0x2EFF";i:2;s:23:"CJK Radicals Supplement";}i:85;a:3:{i:0;s:6:"0x2F00";i:1;s:6:"0x2FDF";i:2;s:15:"Kangxi Radicals";}i:86;a:3:{i:0;s:6:"0x2FF0";i:1;s:6:"0x2FFF";i:2;s:34:"Ideographic Description Characters";}i:87;a:3:{i:0;s:6:"0x3000";i:1;s:6:"0x303F";i:2;s:27:"CJK Symbols and Punctuation";}i:88;a:3:{i:0;s:6:"0x3040";i:1;s:6:"0x309F";i:2;s:8:"Hiragana";}i:89;a:3:{i:0;s:6:"0x30A0";i:1;s:6:"0x30FF";i:2;s:8:"Katakana";}i:90;a:3:{i:0;s:6:"0x3100";i:1;s:6:"0x312F";i:2;s:8:"Bopomofo";}i:91;a:3:{i:0;s:6:"0x3130";i:1;s:6:"0x318F";i:2;s:25:"Hangul Compatibility Jamo";}i:92;a:3:{i:0;s:6:"0x3190";i:1;s:6:"0x319F";i:2;s:6:"Kanbun";}i:93;a:3:{i:0;s:6:"0x31A0";i:1;s:6:"0x31BF";i:2;s:17:"Bopomofo Extended";}i:94;a:3:{i:0;s:6:"0x31C0";i:1;s:6:"0x31EF";i:2;s:11:"CJK Strokes";}i:95;a:3:{i:0;s:6:"0x31F0";i:1;s:6:"0x31FF";i:2;s:28:"Katakana Phonetic Extensions";}i:96;a:3:{i:0;s:6:"0x3200";i:1;s:6:"0x32FF";i:2;s:31:"Enclosed CJK Letters and Months";}i:97;a:3:{i:0;s:6:"0x3300";i:1;s:6:"0x33FF";i:2;s:17:"CJK Compatibility";}i:98;a:3:{i:0;s:6:"0x3400";i:1;s:6:"0x4DBF";i:2;s:34:"CJK Unified Ideographs Extension A";}i:99;a:3:{i:0;s:6:"0x4DC0";i:1;s:6:"0x4DFF";i:2;s:23:"Yijing Hexagram Symbols";}i:100;a:3:{i:0;s:6:"0x4E00";i:1;s:6:"0x9FFF";i:2;s:22:"CJK Unified Ideographs";}i:101;a:3:{i:0;s:6:"0xA000";i:1;s:6:"0xA48F";i:2;s:12:"Yi Syllables";}i:102;a:3:{i:0;s:6:"0xA490";i:1;s:6:"0xA4CF";i:2;s:11:"Yi Radicals";}i:103;a:3:{i:0;s:6:"0xA700";i:1;s:6:"0xA71F";i:2;s:21:"Modifier Tone Letters";}i:104;a:3:{i:0;s:6:"0xA800";i:1;s:6:"0xA82F";i:2;s:12:"Syloti Nagri";}i:105;a:3:{i:0;s:6:"0xAC00";i:1;s:6:"0xD7AF";i:2;s:16:"Hangul Syllables";}i:106;a:3:{i:0;s:6:"0xD800";i:1;s:6:"0xDB7F";i:2;s:15:"High Surrogates";}i:107;a:3:{i:0;s:6:"0xDB80";i:1;s:6:"0xDBFF";i:2;s:27:"High Private Use Surrogates";}i:108;a:3:{i:0;s:6:"0xDC00";i:1;s:6:"0xDFFF";i:2;s:14:"Low Surrogates";}i:109;a:3:{i:0;s:6:"0xE000";i:1;s:6:"0xF8FF";i:2;s:16:"Private Use Area";}i:110;a:3:{i:0;s:6:"0xF900";i:1;s:6:"0xFAFF";i:2;s:28:"CJK Compatibility Ideographs";}i:111;a:3:{i:0;s:6:"0xFB00";i:1;s:6:"0xFB4F";i:2;s:29:"Alphabetic Presentation Forms";}i:112;a:3:{i:0;s:6:"0xFB50";i:1;s:6:"0xFDFF";i:2;s:27:"Arabic Presentation Forms-A";}i:113;a:3:{i:0;s:6:"0xFE00";i:1;s:6:"0xFE0F";i:2;s:19:"Variation Selectors";}i:114;a:3:{i:0;s:6:"0xFE10";i:1;s:6:"0xFE1F";i:2;s:14:"Vertical Forms";}i:115;a:3:{i:0;s:6:"0xFE20";i:1;s:6:"0xFE2F";i:2;s:20:"Combining Half Marks";}i:116;a:3:{i:0;s:6:"0xFE30";i:1;s:6:"0xFE4F";i:2;s:23:"CJK Compatibility Forms";}i:117;a:3:{i:0;s:6:"0xFE50";i:1;s:6:"0xFE6F";i:2;s:19:"Small Form Variants";}i:118;a:3:{i:0;s:6:"0xFE70";i:1;s:6:"0xFEFF";i:2;s:27:"Arabic Presentation Forms-B";}i:119;a:3:{i:0;s:6:"0xFF00";i:1;s:6:"0xFFEF";i:2;s:29:"Halfwidth and Fullwidth Forms";}i:120;a:3:{i:0;s:6:"0xFFF0";i:1;s:6:"0xFFFF";i:2;s:8:"Specials";}i:121;a:3:{i:0;s:7:"0x10000";i:1;s:7:"0x1007F";i:2;s:18:"Linear B Syllabary";}i:122;a:3:{i:0;s:7:"0x10080";i:1;s:7:"0x100FF";i:2;s:18:"Linear B Ideograms";}i:123;a:3:{i:0;s:7:"0x10100";i:1;s:7:"0x1013F";i:2;s:14:"Aegean Numbers";}i:124;a:3:{i:0;s:7:"0x10140";i:1;s:7:"0x1018F";i:2;s:21:"Ancient Greek Numbers";}i:125;a:3:{i:0;s:7:"0x10300";i:1;s:7:"0x1032F";i:2;s:10:"Old Italic";}i:126;a:3:{i:0;s:7:"0x10330";i:1;s:7:"0x1034F";i:2;s:6:"Gothic";}i:127;a:3:{i:0;s:7:"0x10380";i:1;s:7:"0x1039F";i:2;s:8:"Ugaritic";}i:128;a:3:{i:0;s:7:"0x103A0";i:1;s:7:"0x103DF";i:2;s:11:"Old Persian";}i:129;a:3:{i:0;s:7:"0x10400";i:1;s:7:"0x1044F";i:2;s:7:"Deseret";}i:130;a:3:{i:0;s:7:"0x10450";i:1;s:7:"0x1047F";i:2;s:7:"Shavian";}i:131;a:3:{i:0;s:7:"0x10480";i:1;s:7:"0x104AF";i:2;s:7:"Osmanya";}i:132;a:3:{i:0;s:7:"0x10800";i:1;s:7:"0x1083F";i:2;s:17:"Cypriot Syllabary";}i:133;a:3:{i:0;s:7:"0x10A00";i:1;s:7:"0x10A5F";i:2;s:10:"Kharoshthi";}i:134;a:3:{i:0;s:7:"0x1D000";i:1;s:7:"0x1D0FF";i:2;s:25:"Byzantine Musical Symbols";}i:135;a:3:{i:0;s:7:"0x1D100";i:1;s:7:"0x1D1FF";i:2;s:15:"Musical Symbols";}i:136;a:3:{i:0;s:7:"0x1D200";i:1;s:7:"0x1D24F";i:2;s:30:"Ancient Greek Musical Notation";}i:137;a:3:{i:0;s:7:"0x1D300";i:1;s:7:"0x1D35F";i:2;s:21:"Tai Xuan Jing Symbols";}i:138;a:3:{i:0;s:7:"0x1D400";i:1;s:7:"0x1D7FF";i:2;s:33:"Mathematical Alphanumeric Symbols";}i:139;a:3:{i:0;s:7:"0x20000";i:1;s:7:"0x2A6DF";i:2;s:34:"CJK Unified Ideographs Extension B";}i:140;a:3:{i:0;s:7:"0x2F800";i:1;s:7:"0x2FA1F";i:2;s:39:"CJK Compatibility Ideographs Supplement";}i:141;a:3:{i:0;s:7:"0xE0000";i:1;s:7:"0xE007F";i:2;s:4:"Tags";}i:142;a:3:{i:0;s:7:"0xE0100";i:1;s:7:"0xE01EF";i:2;s:30:"Variation Selectors Supplement";}i:143;a:3:{i:0;s:7:"0xF0000";i:1;s:7:"0xFFFFF";i:2;s:32:"Supplementary Private Use Area-A";}i:144;a:3:{i:0;s:8:"0x100000";i:1;s:8:"0x10FFFF";i:2;s:32:"Supplementary Private Use Area-B";}} \ No newline at end of file | ||