PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta.3
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta.3
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-password-checker / src / class-password-checker.php
jetpack / jetpack_vendor / automattic / jetpack-password-checker / src Last commit date
class-password-checker.php 9 months ago
class-password-checker.php
1314 lines
1 <?php
2 /**
3 * Password Checker package.
4 *
5 * @package automattic/jetpack-password-checker
6 */
7
8 namespace Automattic\Jetpack;
9
10 /**
11 * Checks passwords strength.
12 */
13 class Password_Checker {
14 /**
15 * Minimum entropy bits a password should contain. 36 bits of entropy is considered
16 * to be a reasonable password, 28 stands for a weak one.
17 *
18 * @var int
19 */
20 public $minimum_entropy_bits = 28;
21
22 /**
23 * Test results array.
24 *
25 * @var array
26 */
27 public $test_results = array();
28
29 /**
30 * Current password score.
31 *
32 * @var int
33 */
34 public $score = 0;
35
36 /**
37 * Current multiplier affecting the score.
38 *
39 * @var int
40 */
41 public $multiplier = 4;
42
43 /**
44 * A common password disallow list, which on match will immediately disqualify the password.
45 *
46 * @var array
47 */
48 public $common_passwords = array();
49
50 /**
51 * Minimum password length setting.
52 *
53 * @var int
54 */
55 public $minimum_password_length = 6;
56
57 /**
58 * User defined strings that passwords need to be tested for a match against.
59 *
60 * @var array
61 */
62 private $user_strings_to_test = array();
63
64 /**
65 * The user object for whom the password is being tested.
66 *
67 * @var mixed
68 */
69 protected $user = null;
70
71 /**
72 * The user identifier for whom the password is being tested, used if there's no user object.
73 *
74 * @var mixed
75 */
76 protected $user_id = null;
77
78 /**
79 * Creates an instance of the password checker class for the specified user, or
80 * defaults to the currently logged in user.
81 *
82 * @param mixed $user can be an integer ID, or a WP_User object.
83 */
84 public function __construct( $user = null ) {
85 if ( $user === null ) {
86 $this->user_id = get_current_user_id();
87 } elseif ( is_object( $user ) && isset( $user->ID ) ) {
88 // Existing user, using their ID.
89 $this->user_id = $user->ID;
90 } elseif ( is_object( $user ) ) {
91 // Newly created user, using existing data.
92 $this->user = $user;
93 $this->user_id = 'new_user';
94 } else {
95 $this->user_id = $user;
96 }
97
98 /**
99 * Filters the password strength enforcement settings.
100 *
101 * You can supply your own passwords that should not be used for authenticating in addition to weak and easy
102 * to guess strings for each user. For example, you can add passwords from known password databases to avoid
103 * compromised password usage.
104 *
105 * @param array $common_passwords strings that are forbidden for use as passwords.
106 */
107 $this->common_passwords = apply_filters( 'password_checker_common_passwords', $this->common_passwords );
108
109 /**
110 * Filters the password strength enforcement settings.
111 *
112 * You can modify the minimum password length using this filter.
113 *
114 * @param int $minimum_password_length minimum password length.
115 */
116 $this->minimum_password_length = apply_filters( 'password_checker_minimum_password_length', $this->minimum_password_length );
117
118 /**
119 * Filters the password strength enforcement settings.
120 *
121 * You can modify the minimum entropy bits requirement using this filter.
122 *
123 * @param int $minimum_entropy_bits minimum entropy bits requirement.
124 */
125 $this->minimum_entropy_bits = apply_filters( 'password_checker_minimum_entropy_bits', $this->minimum_entropy_bits );
126 }
127
128 /**
129 * Run tests against a password.
130 *
131 * @param string $password the password.
132 * @param bool $required_only only test against required conditions, defaults to false.
133 *
134 * @return array an array containing failed and passed test results.
135 */
136 public function test( $password, $required_only = false ) {
137 // Run the tests.
138 $results = $this->run_tests( $password, $this->get_tests(), $required_only );
139
140 // If we've failed on the required tests, return now.
141 if ( ! empty( $results['failed'] ) ) {
142 return array(
143 'passed' => false,
144 'test_results' => $results,
145 );
146 }
147
148 $entropy_bits = $this->calculate_entropy_bits( $password );
149
150 // If we have failed the entropy bits test, run the regex tests so we can suggest improvements.
151 if ( $entropy_bits < $this->minimum_entropy_bits ) {
152 $results['failed']['entropy_bits'] = $entropy_bits;
153 // Run the tests.
154 $results = array_merge( $results, $this->run_tests( $password, $this->get_tests( 'preg_match' ) ) );
155 }
156
157 return ( array(
158 'passed' => empty( $results['failed'] ),
159 'test_results' => $results,
160 ) );
161 }
162
163 /**
164 * Run the tests using the currently set up object values.
165 *
166 * @param string $password the password.
167 * @param array $tests tests to run.
168 * @param bool $required_only whether to run only required tests.
169 *
170 * @return array test results.
171 */
172 public function run_tests( $password, $tests, $required_only = false ) {
173 $results = array(
174 'passed' => array(),
175 'failed' => array(),
176 );
177
178 foreach ( $tests as $test_type => $section_tests ) {
179 foreach ( $section_tests as $test_name => $test_data ) {
180 // Skip non-required tests if required_only param is set.
181 if ( $required_only && ! $test_data['required'] ) {
182 continue;
183 }
184
185 $result = call_user_func_array( array( $this, 'test_' . $test_type ), array( $password, $test_data ) );
186 if ( $result ) {
187 $results['passed'][] = array( 'test_name' => $test_name );
188 } else {
189 $results['failed'][] = array(
190 'test_name' => $test_name,
191 'explanation' => $test_data['error'],
192 );
193
194 if ( isset( $test_data['fail_immediately'] ) ) {
195 return $results;
196 }
197 }
198 }
199 }
200
201 return $results;
202 }
203
204 /**
205 * Returns an array of tests that need to be run on password strings.
206 *
207 * @param array $sections only return specific sections with the passed keys, defaults to all.
208 *
209 * @return array test descriptions.
210 */
211 public function get_tests( $sections = false ) {
212 // Note: these should be in order of priority.
213 $tests = array(
214 'preg_match' => array(
215 'no_backslashes' => array(
216 'pattern' => '/^[^\\\\]*$/u',
217 'error' => __( 'Passwords may not contain the character "\".', 'jetpack-password-checker' ),
218 'required' => true,
219 'fail_immediately' => true,
220 ),
221 'minimum_length' => array(
222 'pattern' => '/^.{' . $this->minimum_password_length . ',}/u',
223 /* translators: %d is a number of characters in the password. */
224 'error' => sprintf( __( 'Password must be at least %d characters.', 'jetpack-password-checker' ), $this->minimum_password_length ),
225 'required' => true,
226 'fail_immediately' => true,
227 ),
228 'has_mixed_case' => array(
229 'pattern' => '/([a-z].*?[A-Z]|[A-Z].*?[a-z])/u',
230 'error' => __( 'This password is too easy to guess: you can improve it by adding additional uppercase letters, lowercase letters, or numbers.', 'jetpack-password-checker' ),
231 'required' => false,
232 ),
233 'has_digit' => array(
234 'pattern' => '/\d/u',
235 'error' => __( 'This password is too easy to guess: you can improve it by mixing both letters and numbers.', 'jetpack-password-checker' ),
236 'required' => false,
237 ),
238 'has_special_char' => array(
239 'pattern' => '/[^a-zA-Z\d]/u',
240 'error' => __( 'This password is too easy to guess: you can improve it by including special characters such as !#=?*&.', 'jetpack-password-checker' ),
241 'required' => false,
242 ),
243 ),
244 'compare_to_list' => array(
245 'not_a_common_password' => array(
246 'list_callback' => 'get_common_passwords',
247 'compare_callback' => 'negative_in_array',
248 'error' => __( 'This is a very common password. Choose something that will be harder for others to guess.', 'jetpack-password-checker' ),
249 'required' => true,
250 ),
251 'not_same_as_other_user_data' => array(
252 'list_callback' => 'get_other_user_data',
253 'compare_callback' => 'test_not_same_as_other_user_data',
254 'error' => __( 'Your password is too weak: Looks like you are including easy to guess information about yourself. Try something a little more unique.', 'jetpack-password-checker' ),
255 'required' => true,
256 ),
257 ),
258 );
259
260 /**
261 * Filters the password strength enforcement settings.
262 *
263 * You can determine the tests run and their order based on whatever criteria you wish to specify.
264 *
265 * @param array $tests tests to run.
266 */
267 $tests = apply_filters( 'password_checker_tests', $tests );
268
269 if ( ! $sections ) {
270 return $tests;
271 }
272
273 $sections = (array) $sections;
274
275 return array_intersect_key( $tests, array_flip( $sections ) );
276 }
277
278 /**
279 * Provides the regular expression tester functionality.
280 *
281 * @param string $password the password.
282 * @param array $test_data the current test data.
283 *
284 * @return bool does the test pass?
285 */
286 protected function test_preg_match( $password, $test_data ) {
287 return preg_match( $test_data['pattern'], $password );
288 }
289
290 /**
291 * Provides the comparison tester functionality.
292 *
293 * @param string $password the password.
294 * @param array $test_data the current test data.
295 *
296 * @return bool does the test pass?
297 */
298 protected function test_compare_to_list( $password, $test_data ) {
299 if (
300 ! is_callable( array( $this, $test_data['list_callback'] ) )
301 || ! is_callable( array( $this, $test_data['compare_callback'] ) )
302 ) {
303 return false;
304 }
305
306 return call_user_func(
307 array(
308 $this,
309 $test_data['compare_callback'],
310 ),
311 $password,
312 call_user_func( array( $this, $test_data['list_callback'] ) )
313 );
314 }
315
316 /**
317 * Getter for the common password list.
318 *
319 * @return array common passwords.
320 */
321 protected function get_common_passwords() {
322 return $this->common_passwords;
323 }
324
325 /**
326 * Returns the widely known user data that cannot be used in the password to avoid
327 * predictable strings.
328 *
329 * @return array user data.
330 */
331 protected function get_other_user_data() {
332 if ( empty( $this->user_id ) ) {
333 return array();
334 }
335
336 $user_data = get_userdata( $this->user_id );
337 if ( ! $user_data ) {
338 return array();
339 }
340
341 if ( isset( $user_data->ID ) ) {
342 $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'first_name', true ) );
343 $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'last_name', true ) );
344 $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'nickname', true ) );
345 }
346
347 if ( isset( $user_data->user_nicename ) ) {
348 $this->add_user_strings_to_test( $user_data->user_nicename );
349 }
350
351 if ( isset( $user_data->display_name ) ) {
352 $this->add_user_strings_to_test( $user_data->display_name );
353 }
354
355 if ( isset( $user_data->first_name ) ) {
356 $this->add_user_strings_to_test( $user_data->first_name );
357 }
358
359 if ( isset( $user_data->last_name ) ) {
360 $this->add_user_strings_to_test( $user_data->last_name );
361 }
362
363 if ( isset( $user_data->user_email ) ) {
364 $email_username = substr( $user_data->user_email, 0, strpos( $user_data->user_email, '@' ) );
365 $this->add_user_strings_to_test( $email_username, '.' );
366 $this->add_user_strings_to_test( $user_data->user_email );
367 }
368
369 return $this->get_user_strings_to_test();
370 }
371
372 /**
373 * Compare the password for matches with known user data.
374 *
375 * @param string $password the password.
376 * @param array $strings_to_test known user data.
377 *
378 * @return bool does the test pass?
379 */
380 protected function test_not_same_as_other_user_data( $password, $strings_to_test ) {
381 if ( empty( $strings_to_test ) ) {
382 return false;
383 }
384
385 $password_lowercase = strtolower( $password );
386
387 foreach ( $strings_to_test as $string ) {
388 $string = strtolower( $string );
389 $string_reversed = strrev( $string );
390
391 if ( $password_lowercase === $string || $password_lowercase === $string_reversed ) {
392 return false;
393 }
394
395 // Also check for the string or reversed string with any numbers just stuck to the end to catch things like bob123 as passwords.
396 if (
397 preg_match( '/^' . preg_quote( $string, '/' ) . '\d+$/', $password_lowercase )
398 || preg_match( '/^' . preg_quote( $string_reversed, '/' ) . '\d+$/', $password_lowercase )
399 ) {
400 return false;
401 }
402 }
403
404 return true;
405 }
406
407 /**
408 * A shorthand for the not in array construct.
409 *
410 * @param mixed $needle the needle.
411 * @param array $haystack the haystack.
412 *
413 * @return bool is the needle not in the haystack?
414 */
415 protected function negative_in_array( $needle, $haystack ) {
416 return ! in_array( $needle, $haystack, true );
417 }
418
419 /**
420 * A helper function used to break a single string into its constituents so
421 * that both the full string and its constituents and any variants thereof
422 * can be tested against the password.
423 *
424 * @param string $string the string to be broken down.
425 * @param string $explode_delimiter delimiter.
426 *
427 * @return bool
428 */
429 protected function add_user_strings_to_test( $string, $explode_delimiter = ' ' ) {
430 // Don't check against empty strings.
431 if ( empty( $string ) ) {
432 return false;
433 }
434
435 $strings = explode( $explode_delimiter, $string );
436
437 // Remove any non alpha numeric characters from the strings to check against.
438 foreach ( $strings as $key => $_string ) {
439 $_string = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $_string ) );
440 if ( empty( $_string ) ) {
441 continue;
442 }
443
444 $strings[ $key ] = $_string;
445 }
446
447 // Check the original too.
448 $strings[] = trim( $string );
449
450 // Check the original minus non alpha numeric characters.
451 $strings[] = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $string ) );
452
453 // Remove any empty strings.
454 // Note: This will also filter out '0'.
455 $strings = array_filter( $strings );
456 if ( empty( $strings ) ) {
457 return false;
458 }
459
460 $this->user_strings_to_test = array_unique( array_merge( $this->user_strings_to_test, $strings ) );
461
462 return true;
463 }
464
465 /**
466 * Getter for the user strings array.
467 *
468 * @return array user strings.
469 */
470 protected function get_user_strings_to_test() {
471 return $this->user_strings_to_test;
472 }
473
474 /**
475 * Return a character set size that is used in the string.
476 *
477 * @param string $password the password.
478 *
479 * @return int number of different character sets in use.
480 */
481 protected function get_charset_size( $password ) {
482 $size = 0;
483
484 // Lowercase a-z.
485 if ( preg_match( '/[a-z]/', $password ) ) {
486 $size += 26;
487 }
488
489 // Uppercase A-Z.
490 if ( preg_match( '/[A-Z]/', substr( $password, 1, - 1 ) ) ) {
491 $size += 26;
492 }
493
494 // Digits.
495 if ( preg_match( '/\d/', substr( $password, 1, - 1 ) ) ) {
496 $size += 10;
497 }
498
499 // Over digits symbols.
500 if ( preg_match( '/[!|@|#|$|%|^|&|*|(|)]/', $password ) ) {
501 $size += 10;
502 }
503
504 // Other symbols.
505 if ( preg_match( '#[`|~|-|_|=|+|\[|{|\]|}|\\|\|;:\'",<\.>/\?]#', $password ) ) {
506 $size += 20;
507 }
508
509 // Spaces.
510 if ( strpos( $password, ' ' ) ) {
511 ++$size;
512 }
513
514 return $size;
515 }
516
517 /**
518 * Shorthand for getting a character index.
519 *
520 * @param string $char character.
521 *
522 * @return int the character code.
523 */
524 protected function get_char_index( $char ) {
525 $char = strtolower( $char[0] );
526 if ( $char < 'a' || $char > 'z' ) {
527 return 0;
528 } else {
529 return ord( $char[0] ) - ord( 'a' ) + 1;
530 }
531 }
532
533 /**
534 * This is the password strength calculation algorithm, based on the formula H = L(logN/log2).
535 *
536 * H = Entropy
537 * L = String length (the for iterator)
538 * N = Our charset size, via get_charset_size()
539 *
540 * @see https://en.wikipedia.org/wiki/Password_strength#Random_passwords
541 *
542 * On top of the base formula, we're also multiplying the bits of entropy for every char
543 * by 1 - (the probabily of it following the previous char)
544 * i.e.: the probablity of U following Q is ~0.84. If our password contains this pair of characters,
545 * the u char will only add ( 0.16^2 * charset_score ) to our total of entropy bits.
546 *
547 * @param string $password the password.
548 *
549 * @return float|int
550 */
551 protected function calculate_entropy_bits( $password ) {
552 $bits = 0;
553 // Calculate the score.
554 $charset_score = log( $this->get_charset_size( $password ) ) / log( 2 );
555
556 $aidx = $this->get_char_index( $password[0] );
557 $length = strlen( $password );
558
559 for ( $b = 1; $b < $length; $b++ ) {
560 $bidx = $this->get_char_index( $password[ $b ] );
561
562 // 27 = number of chars in the index (a-z,' ').
563 $c = 1.0 - $this->frequency_table[ $aidx * 27 + $bidx ];
564
565 // Increment the bits.
566 $bits += $charset_score * $c * $c;
567
568 // Move on to next pair.
569 $aidx = $bidx;
570 }
571
572 return $bits;
573 }
574
575 /**
576 * A frequency table of character pairs, starting with ' ' then ' a', ' b' [...] , 'a ', 'aa' etc.
577 *
578 * @see http://rumkin.com/tools/password/passchk.php
579 *
580 * @var array
581 */
582 public $frequency_table = array(
583 0.23653710453418866,
584 0.04577693541332556,
585 0.03449832337075375,
586 0.042918209651552706,
587 0.037390873305146524,
588 0.028509112115468728,
589 0.02350896632162123,
590 0.022188657238664526,
591 0.028429800262428927,
592 0.04357019973757107,
593 0.00913602565971716,
594 0.03223093745443942,
595 0.02235311269864412,
596 0.04438081352966905,
597 0.04512377897652719,
598 0.020055401662049863,
599 0.055903192885260244,
600 0.0024388394809739026,
601 0.035207464644991984,
602 0.07355941099285611,
603 0.036905671380667734,
604 0.026134421927394666,
605 0.023787724158040528,
606 0.011352092141711621,
607 0.0032354570637119114,
608 0.005986878553725033,
609 0.008861933226417843,
610 0.11511532293337222,
611 0.027556203528211108,
612 0.024331243621519172,
613 0.039266365359381834,
614 0.031599941682461,
615 0.014403265782183991,
616 0.015480973902901297,
617 0.027770812071730572,
618 0.00942761335471643,
619 0.039872867764980315,
620 0.0078122175244204695,
621 0.02808456043154979,
622 0.08429100451960927,
623 0.04688963405744277,
624 0.13831170724595424,
625 0.002540311998833649,
626 0.025211838460416972,
627 0.001543082081936142,
628 0.09519638431258201,
629 0.061845750109345385,
630 0.08907071001603732,
631 0.02137571074500656,
632 0.027093162268552268,
633 0.005521504592506197,
634 0.003023181221752442,
635 0.007086747339262283,
636 0.010262720513194342,
637 0.08785070710016038,
638 0.14617757690625455,
639 0.03417291150313457,
640 0.0059635515381250915,
641 0.006146668610584633,
642 0.195202799241872,
643 0.002774748505613063,
644 0.004715556203528212,
645 0.0044776206444088066,
646 0.11205481848665985,
647 0.005654468581425864,
648 0.0028820527773727946,
649 0.07383000437381543,
650 0.005516839189386207,
651 0.006496573844583759,
652 0.09843067502551392,
653 0.0027140982650532145,
654 0.0006893133109782768,
655 0.08425368129464937,
656 0.021325557661466685,
657 0.006493074792243767,
658 0.07023414491908442,
659 0.002077270739174807,
660 0.0024633328473538415,
661 0.0007744569179180639,
662 0.015413325557661468,
663 0.0011990086018370024,
664 0.13162851727657093,
665 0.10115993585070711,
666 0.0026989357049132527,
667 0.03319317684793702,
668 0.002946202070272634,
669 0.0783216212275842,
670 0.0018358361277154103,
671 0.00258813238081353,
672 0.2141688292754046,
673 0.09853681294649366,
674 0.0032482869222918796,
675 0.04359352675317102,
676 0.01993526753171016,
677 0.0036880011663507797,
678 0.008011663507799971,
679 0.12014696019827964,
680 0.0029846916460125384,
681 0.0017553579238956116,
682 0.029470185158186325,
683 0.010413179763813967,
684 0.030699518880303252,
685 0.03508499781309229,
686 0.002021285901734947,
687 0.0010613792097973467,
688 0.0005295232541186761,
689 0.009677212421635807,
690 0.010585799679253535,
691 0.17101734946785244,
692 0.07968625164018078,
693 0.007839043592360402,
694 0.005438693687126403,
695 0.0183606939787141,
696 0.2732701559994168,
697 0.004953491762647616,
698 0.007259367254701851,
699 0.008104971570199739,
700 0.13274588132380813,
701 0.004210526315789474,
702 0.004997813092287506,
703 0.017006560723137484,
704 0.007442484327161393,
705 0.016789619478058026,
706 0.08477737279486806,
707 0.005106283714827234,
708 0.0005026971861787433,
709 0.04040355736987899,
710 0.037535500801866156,
711 0.00885960052485785,
712 0.0336410555474559,
713 0.007066919376002332,
714 0.005344219273946639,
715 0.0006333284735384167,
716 0.010684939495553289,
717 0.0063064586674442345,
718 0.15386849394955532,
719 0.015049424114302375,
720 0.012162705933809595,
721 0.020425134859308938,
722 0.037366379938766583,
723 0.02157165767604607,
724 0.009373961218836564,
725 0.0173214754337367,
726 0.009616562181075958,
727 0.029522670943286193,
728 0.010154249890654615,
729 0.018600962239393497,
730 0.06362210234728094,
731 0.03157078291296107,
732 0.151603440734801,
733 0.0062329785683044175,
734 0.014775331681003062,
735 0.0020854351946347867,
736 0.1826342032366234,
737 0.0878017203674005,
738 0.054190989940224525,
739 0.010329202507654177,
740 0.012763376585508092,
741 0.0064872430383437815,
742 0.006381105117364048,
743 0.005388540603586529,
744 0.0090800408222773,
745 0.09611196967487973,
746 0.09940691062837148,
747 0.01033969966467415,
748 0.004034407348009914,
749 0.008826942703017933,
750 0.11474675608689314,
751 0.07132584924916169,
752 0.012388977985129028,
753 0.005435194634786413,
754 0.1417174515235457,
755 0.0037066627788307337,
756 0.0045802595130485495,
757 0.060800699810468,
758 0.005341886572386646,
759 0.005683627350925791,
760 0.12434932205860913,
761 0.004596588423968508,
762 0.0007534626038781163,
763 0.07107041842834232,
764 0.022361277154104096,
765 0.04784720804782038,
766 0.06277533168100306,
767 0.003441901151771395,
768 0.005828254847645429,
769 0.0009669047966175828,
770 0.009470768333576322,
771 0.002077270739174807,
772 0.12797667298440007,
773 0.08797783933518005,
774 0.005388540603586529,
775 0.0024913252660737715,
776 0.007550954949701123,
777 0.2786866890217233,
778 0.002509986878553725,
779 0.029002478495407494,
780 0.0303204548768042,
781 0.07576614666861058,
782 0.00246799825047383,
783 0.00592389561160519,
784 0.039574281965301064,
785 0.00706808572678233,
786 0.03304505029887739,
787 0.05474150750838315,
788 0.0028633911648928414,
789 0.0005073625892987316,
790 0.07293541332555767,
791 0.053528502697186175,
792 0.022566554891383584,
793 0.038151334013704616,
794 0.002716430966613209,
795 0.005049132526607377,
796 0.0009902318122175246,
797 0.008997229916897508,
798 0.0011861787432570347,
799 0.1666377022889634,
800 0.14414462749671964,
801 0.003374252806531564,
802 0.005169266656947077,
803 0.008468873013558828,
804 0.16337541915731155,
805 0.002873888321912815,
806 0.004305000728969237,
807 0.0031141565825922144,
808 0.1241172182533897,
809 0.0052800699810468,
810 0.008969237498177577,
811 0.024094474413179766,
812 0.017029887738737422,
813 0.01722700102055693,
814 0.10618457501093455,
815 0.006147834961364631,
816 0.0008269427030179326,
817 0.03303571949263741,
818 0.024188948826359528,
819 0.05213937891820965,
820 0.04505846333284735,
821 0.0035270447587111824,
822 0.006799825047383001,
823 0.0008199445983379502,
824 0.02206735675754483,
825 0.001010059775477475,
826 0.11971191135734072,
827 0.04656538854060359,
828 0.011243621519171892,
829 0.06513019390581717,
830 0.032375564951159064,
831 0.06347047674588133,
832 0.013678961947805804,
833 0.03309870243475726,
834 0.006982942119842543,
835 0.009726199154395685,
836 0.010121592068814697,
837 0.032514360693978714,
838 0.04986032949409535,
839 0.039734072022160664,
840 0.15690683773144773,
841 0.03949963551538125,
842 0.014790494241143023,
843 0.002722262720513194,
844 0.02614375273363464,
845 0.10753637556495116,
846 0.06764834523983088,
847 0.006221315060504448,
848 0.021317393206006705,
849 0.0030826651115322934,
850 0.002399183554454002,
851 0.0019069835252952323,
852 0.015595276279341012,
853 0.0925126111678087,
854 0.18437906400349907,
855 0.006538562472663654,
856 0.008719638431258201,
857 0.02116693395538708,
858 0.18241376293920394,
859 0.007290858725761773,
860 0.005976381396705059,
861 0.005629975215045925,
862 0.09721300481119698,
863 0.004810030616707975,
864 0.024303251202799244,
865 0.012954658113427612,
866 0.011057005394372358,
867 0.02733459688001166,
868 0.10135121737862662,
869 0.012016912086309959,
870 0.001055547455897361,
871 0.009027555037177431,
872 0.07162326869806095,
873 0.01007143898527482,
874 0.07297623560285756,
875 0.006741507508383147,
876 0.0036891675171307776,
877 0.0008409389123778977,
878 0.011272780288671819,
879 0.007020265344802449,
880 0.1030389269572824,
881 0.15350809155853623,
882 0.004232686980609419,
883 0.004353987461729115,
884 0.0023385333138941536,
885 0.14450386353695874,
886 0.002546143752733635,
887 0.0024470039364338824,
888 0.01200758128006998,
889 0.0981227584195947,
890 0.003161976964572095,
891 0.040695145064878264,
892 0.03460446129173349,
893 0.003908441463770229,
894 0.01598483743986004,
895 0.13107216795451232,
896 0.003129319142732177,
897 0.00032307916605919226,
898 0.04050386353695874,
899 0.05452689896486368,
900 0.03589677795597026,
901 0.07087097244496282,
902 0.006143169558244642,
903 0.008684647907858289,
904 0.0004607085580988482,
905 0.022010205569324977,
906 0.0009097536083977258,
907 0.07328765126111678,
908 0.14751421490013122,
909 0.008015162560139961,
910 0.006601545414783497,
911 0.025279486805656802,
912 0.1682449336637994,
913 0.008313748359819215,
914 0.007010934538562473,
915 0.005886572386645284,
916 0.16889575739903775,
917 0.004123050007289692,
918 0.011925936725470185,
919 0.10007289692374982,
920 0.013380376148126549,
921 0.009021723283277445,
922 0.08650823735238372,
923 0.007756232686980609,
924 0.0007243038343781893,
925 0.0026791077416533026,
926 0.02797492345823006,
927 0.032384895757399036,
928 0.04187432570345531,
929 0.00882461000145794,
930 0.0032401224668318998,
931 0.00033357632307916605,
932 0.027878116343490307,
933 0.0022277299897944304,
934 0.14333518005540166,
935 0.1725534334451086,
936 0.02781629975215046,
937 0.006909462020702727,
938 0.005264907420906838,
939 0.16661437527336345,
940 0.004325995043009185,
941 0.003334596880011664,
942 0.005312727802886718,
943 0.14024668318996938,
944 0.0013261408368566844,
945 0.003504884093891238,
946 0.006375273363464061,
947 0.04964922000291588,
948 0.008290421344219274,
949 0.09536783787724158,
950 0.05394372357486515,
951 0.005505175681586237,
952 0.005339553870826651,
953 0.01782067356757545,
954 0.006710016037323225,
955 0.05105933809593235,
956 0.002983525295232541,
957 0.002940370316372649,
958 0.0004548768041988629,
959 0.01208456043154979,
960 0.000915585362297711,
961 0.20146260387811635,
962 0.067196967487972,
963 0.006158332118384605,
964 0.025438110511736407,
965 0.07753783350342616,
966 0.1273876658405015,
967 0.009337804344656656,
968 0.07683452398308792,
969 0.0070412596588423975,
970 0.08747164309666132,
971 0.0038827817466102928,
972 0.018116926665694706,
973 0.005017641055547455,
974 0.004567429654468581,
975 0.028277008310249308,
976 0.05271555620352821,
977 0.004394809739029013,
978 0.0013343052923166642,
979 0.00411605190260971,
980 0.059621519171890944,
981 0.09073859163143316,
982 0.01446858142586383,
983 0.006770666277883074,
984 0.003425572240851436,
985 0.0004455459979588861,
986 0.010401516256013998,
987 0.005825922146085436,
988 0.10833882490158916,
989 0.007584779122321038,
990 0.016903921854497742,
991 0.02719580113719201,
992 0.0304814112844438,
993 0.02206385770520484,
994 0.013064295086747339,
995 0.02696369733197259,
996 0.009581571657676046,
997 0.026761918647033093,
998 0.006510570053943724,
999 0.021941390873305145,
1000 0.07042659279778393,
1001 0.05437410701268406,
1002 0.1425175681586237,
1003 0.027802303542790494,
1004 0.037690625455605774,
1005 0.0019606356611750987,
1006 0.1095623268698061,
1007 0.06157748942994606,
1008 0.044618749088788455,
1009 0.04955124653739612,
1010 0.03608689313310978,
1011 0.018381688292754043,
1012 0.003404577926811489,
1013 0.015036594255722409,
1014 0.009600233270156,
1015 0.10794693103951014,
1016 0.12447528794284882,
1017 0.0031981338387520046,
1018 0.0074716430966613205,
1019 0.003202799241871993,
1020 0.13437643971424407,
1021 0.006655197550663361,
1022 0.0036693395538708266,
1023 0.049338970695436656,
1024 0.09486863974340283,
1025 0.0015990669193760023,
1026 0.0026604461291733486,
1027 0.051775477474850555,
1028 0.0041347135150896636,
1029 0.005450357194926374,
1030 0.12030325120279925,
1031 0.04581309228750547,
1032 0.0004537104534188657,
1033 0.12425601399620935,
1034 0.025981629975215047,
1035 0.023926519900860182,
1036 0.04423385333138941,
1037 0.0017950138504155123,
1038 0.002661612479953346,
1039 0.0006333284735384167,
1040 0.008449045050298877,
1041 0.000653156436798367,
1042 0.04816678816153958,
1043 0.008625164018078437,
1044 0.0039037760606502403,
1045 0.005228750546726928,
1046 0.004531272780288672,
1047 0.0056672984400058316,
1048 0.00359585945473101,
1049 0.0032179618020119548,
1050 0.0038093016474704767,
1051 0.011452398308791368,
1052 0.002519317684793702,
1053 0.00280390727511299,
1054 0.005572824026826068,
1055 0.004554599795888614,
1056 0.004531272780288672,
1057 0.0035841959469310393,
1058 0.004400641492928998,
1059 0.0036670068523108326,
1060 0.004839189386207902,
1061 0.006258638285464354,
1062 0.004897506925207757,
1063 0.840776789619478,
1064 0.004968654322787578,
1065 0.002886718180492783,
1066 0.0019757982213150604,
1067 0.0018568304417553576,
1068 0.001691208630995772,
1069 0.09009243329931477,
1070 0.14030150167662925,
1071 0.013242746756086894,
1072 0.013746610293045632,
1073 0.027342761335471644,
1074 0.16938912377897652,
1075 0.006607377168683481,
1076 0.01661933226417845,
1077 0.008173786266219566,
1078 0.13297448607668758,
1079 0.0034675608689313307,
1080 0.016641492928998396,
1081 0.011722991689750693,
1082 0.021493512173786266,
1083 0.03430820819361423,
1084 0.10099548039072752,
1085 0.00873596734217816,
1086 0.0018323370753754193,
1087 0.020103222044029742,
1088 0.047197550663362,
1089 0.040833940807697915,
1090 0.03361189677795597,
1091 0.010844729552412887,
1092 0.005544831608106138,
1093 0.0007522962530981193,
1094 0.01525120279924187,
1095 0.00815512465373961,
1096 0.2109648636827526,
1097 0.058258055110074355,
1098 0.007181221752442048,
1099 0.043560868931331105,
1100 0.004058900714389853,
1101 0.10618107595859454,
1102 0.0062399766729844,
1103 0.004835690333867911,
1104 0.02679224376731302,
1105 0.08414637702288964,
1106 0.0030698352529523252,
1107 0.03637498177576906,
1108 0.01592885260242018,
1109 0.017413617145356466,
1110 0.008430383437818923,
1111 0.037231083248286924,
1112 0.03290275550371775,
1113 0.007538125091121154,
1114 0.004500947660008748,
1115 0.05932409972299169,
1116 0.16006764834523984,
1117 0.03309636973319726,
1118 0.007766729844000583,
1119 0.005225251494386936,
1120 0.0006321621227584196,
1121 0.012989648636827526,
1122 0.005274238227146815,
1123 0.1254503571949264,
1124 0.12852719055255868,
1125 0.0035433736696311416,
1126 0.005203090829566993,
1127 0.0019314768916751715,
1128 0.20520775623268697,
1129 0.002509986878553725,
1130 0.00343606939787141,
1131 0.027138649948972155,
1132 0.13926578218399185,
1133 0.004565096952908587,
1134 0.005614812654905963,
1135 0.00874413179763814,
1136 0.004109053797929727,
1137 0.008300918501239247,
1138 0.08270943286193323,
1139 0.002912377897652719,
1140 0.0037066627788307337,
1141 0.06909578655780726,
1142 0.03242805073625893,
1143 0.05237614812654906,
1144 0.04723487388832191,
1145 0.0038991106575302524,
1146 0.006299460562764251,
1147 0.00043388249015891526,
1148 0.020029741944889927,
1149 0.005311561452106721,
1150 0.09334072022160665,
1151 0.022940953491762648,
1152 0.024658988190698353,
1153 0.02901297565242747,
1154 0.03531593526753171,
1155 0.0758023035427905,
1156 0.013711619769645722,
1157 0.021597317393206007,
1158 0.009670214316955824,
1159 0.044728386062108175,
1160 0.010596296836273509,
1161 0.03264382563055839,
1162 0.0604822860475288,
1163 0.05489546581134276,
1164 0.11501851581863246,
1165 0.01837585653885406,
1166 0.026237060796034405,
1167 0.0011255285026971862,
1168 0.08704125965884241,
1169 0.10156349322058608,
1170 0.06660562764251349,
1171 0.023434319871701415,
1172 0.010777081207173057,
1173 0.005409534917626476,
1174 0.003123487388832191,
1175 0.0028762210234728096,
1176 0.0089995626184575,
1177 0.07518297127861205,
1178 0.2314868056568013,
1179 0.002226563639014434,
1180 0.003285610147251786,
1181 0.0027455897361131363,
1182 0.2724537104534189,
1183 0.0016655489138358362,
1184 0.0019209797346551977,
1185 0.0022137337804344656,
1186 0.17690392185449774,
1187 0.0014532730718763668,
1188 0.0024994897215337513,
1189 0.015302522233561744,
1190 0.003441901151771395,
1191 0.015303688584341741,
1192 0.09314593964134713,
1193 0.0017833503426155418,
1194 0.0005108616416387229,
1195 0.017828838023035427,
1196 0.010385187345094037,
1197 0.003168975069252078,
1198 0.01902901297565243,
1199 0.005525003644846187,
1200 0.0010088934246974776,
1201 0.0009272488700976819,
1202 0.036282840064149294,
1203 0.0022977110365942554,
1204 0.0766805656801283,
1205 0.22270418428342326,
1206 0.005283569033386791,
1207 0.007155562035282111,
1208 0.01173582154833066,
1209 0.1715620352821111,
1210 0.003925936725470185,
1211 0.004425134859308937,
1212 0.020040239101909902,
1213 0.14243242455168392,
1214 0.0016737133692958156,
1215 0.0066808572678232975,
1216 0.011980755212130047,
1217 0.012638577052048404,
1218 0.07206065024055984,
1219 0.08115701997375711,
1220 0.00710424260096224,
1221 0.0007278028867181805,
1222 0.02347630849978131,
1223 0.04595538708266512,
1224 0.01481965301064295,
1225 0.013925061962385188,
1226 0.0018125091121154687,
1227 0.00529173348884677,
1228 0.0016340574427759146,
1229 0.03072401224668319,
1230 0.0023746901880740633,
1231 0.25174165330223064,
1232 0.06673392622831317,
1233 0.00878378772415804,
1234 0.03956261845750109,
1235 0.010077270739174807,
1236 0.0844787869951888,
1237 0.00985216503863537,
1238 0.004973319725907567,
1239 0.01893220586091267,
1240 0.11200583175389998,
1241 0.0028715556203528212,
1242 0.004095057588569762,
1243 0.01202391019098994,
1244 0.01756757544831608,
1245 0.014825484764542934,
1246 0.05312961073042717,
1247 0.06746872721971132,
1248 0.003845458521650386,
1249 0.0210806239976673,
1250 0.019443067502551394,
1251 0.08017028721387957,
1252 0.01825572240851436,
1253 0.005365213587986587,
1254 0.01959702580551101,
1255 0.026184575010934536,
1256 0.02474879720075813,
1257 0.002171745152354571,
1258 0.25827321767021433,
1259 0.048050153083539875,
1260 0.01043184137629392,
1261 0.03930485493512174,
1262 0.027640180784370902,
1263 0.03294007872867765,
1264 0.006474413179763814,
1265 0.018314039947514214,
1266 0.015119405161102202,
1267 0.014706516984983233,
1268 0.005494678524566263,
1269 0.03309870243475726,
1270 0.043864120134130345,
1271 0.058996355153812505,
1272 0.06265986295378335,
1273 0.04633328473538417,
1274 0.03790756670068523,
1275 0.0004642076104388394,
1276 0.037849249161685375,
1277 0.08369966467415076,
1278 0.04999679253535501,
1279 0.02392768625164018,
1280 0.010998687855372504,
1281 0.009881323808135296,
1282 0.003867619186470331,
1283 0.012434465665548913,
1284 0.007253535500801866,
1285 0.11106225397288234,
1286 0.17624726636535937,
1287 0.008209943140399476,
1288 0.008390727511299025,
1289 0.012682898381688294,
1290 0.1825653885406036,
1291 0.001538416678816154,
1292 0.004590756670068524,
1293 0.008710307625018223,
1294 0.1299513048549351,
1295 0.002677941390873305,
1296 0.012309666132089225,
1297 0.014087184720804781,
1298 0.01199941682461,
1299 0.031246537396121883,
1300 0.07206648199445984,
1301 0.008254264470039366,
1302 0.0007033095203382417,
1303 0.007034261554162415,
1304 0.006599212713223502,
1305 0.013906400349905234,
1306 0.050098265053214755,
1307 0.007133401370462167,
1308 0.017750692520775622,
1309 0.0008257763522379356,
1310 0.03918821985712203,
1311 0.06015454147834961,
1312 );
1313 }
1314