Completed
Push — add/password-package ( ea5e4d...5e4458 )
by
unknown
868:52 queued 851:50
created

Password_Checker   F

Complexity

Total Complexity 58

Size/Duplication

Total Lines 1300
Duplicated Lines 18.85 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 0
Metric Value
dl 245
loc 1300
rs 3.36
c 0
b 0
f 0
wmc 58
lcom 2
cbo 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 16 48 5
A test() 7 29 3
B run_tests() 36 36 7
B list_tests() 68 68 2
A test_preg_match() 13 13 3
A test_compare_to_list() 18 18 4
A get_common_passwords() 0 3 1
B get_other_user_data() 0 40 9
B test_not_same_as_other_user_data() 24 24 7
A negative_in_array() 0 3 1
A add_user_strings_to_test() 0 29 4
B get_charset_size() 35 35 7
A get_char_index() 8 8 3
A calculate_entropy_bits() 20 20 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Password_Checker often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Password_Checker, and based on these observations, apply Extract Interface, too.

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 Integer
19
	 */
20
	public $minimum_entropy_bits = 28;
21
22
	/**
23
	 * Currently tested password.
24
	 *
25
	 * @var String
26
	 */
27
	public $password = '';
28
29
	/**
30
	 * Test results array.
31
	 *
32
	 * @var Array
33
	 */
34
	public $test_results = '';
35
36
	/**
37
	 * Current password score.
38
	 *
39
	 * @var Integer
40
	 */
41
	public $score = 0;
42
43
	/**
44
	 * Current multiplier affecting the score.
45
	 *
46
	 * @var Integer
47
	 */
48
	public $multiplier = 4;
49
50
	/**
51
	 * A common password disallow list, which on match will immediately disqualify the password.
52
	 *
53
	 * @var Array
54
	 */
55
	public $common_passwords = array();
56
57
	/**
58
	 * Minimum password length setting.
59
	 *
60
	 * @var Integer
61
	 */
62
	public $min_password_length = 6;
63
64
	/**
65
	 * User defined strings that passwords need to be tested for a match against.
66
	 *
67
	 * @var Array
68
	 */
69
	private $user_strings_to_test = array();
70
71
	/**
72
	 * The user object for whom the password is being tested.
73
	 *
74
	 * @var WP_User
75
	 */
76
	protected $user;
77
78
	/**
79
	 * The user identifier for whom the password is being tested, used if there's no user object.
80
	 *
81
	 * @var WP_User
82
	 */
83
	protected $user_id;
84
85
	/**
86
	 * Creates an instance of the password checker class for the specified user, or
87
	 * defaults to the currently logged in user.
88
	 *
89
	 * @param Mixed $user can be an integer ID, or a WP_User object.
90
	 */
91
	public function __construct( $user = null ) {
92
93
		/**
94
		 * Filters Jetpack's password strength enforcement settings. You can supply your own passwords
95
		 * that should not be used for authenticating in addition to weak and easy to guess strings for
96
		 * each user. For example, you can add passwords from known password databases to avoid compromised
97
		 * password usage.
98
		 *
99
		 * @since 7.2.0
100
		 *
101
		 * @param array $restricted_passwords strings that are forbidden for use as passwords.
102
		 */
103
		$this->common_passwords = apply_filters( 'jetpack_password_checker_restricted_strings', array() );
104
105 View Code Duplication
		if ( is_null( $user ) ) {
106
			$this->user_id = get_current_user_id();
107
		} elseif ( is_object( $user ) && isset( $user->ID ) ) {
108
109
			// Existing user, using their ID.
110
			$this->user_id = $user->ID;
111
112
		} elseif ( is_object( $user ) ) {
113
114
			// Newly created user, using existing data.
115
			$this->user    = $user;
116
			$this->user_id = 'new_user';
0 ignored issues
show
Documentation Bug introduced by
It seems like 'new_user' of type string is incompatible with the declared type object<Automattic\Jetpack\WP_User> of property $user_id.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
117
118
		} else {
119
			$this->user_id = $user;
0 ignored issues
show
Documentation Bug introduced by
It seems like $user of type integer or double or string or array or boolean is incompatible with the declared type object<Automattic\Jetpack\WP_User> of property $user_id.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
120
		}
121
122
		/**
123
		 * Filter for the minimum password length.
124
		 *
125
		 * @param int $min_password_length minimum password length.
126
		 */
127
		$this->min_password_length = apply_filters( 'better_password_min_length', $this->min_password_length );
128
129
		/**
130
		 * Filters Jetpack's password strength enforcement settings. You can modify the minimum
131
		 * entropy bits requirement using this filter.
132
		 *
133
		 * @since 7.2.0
134
		 *
135
		 * @param int $minimum_entropy_bits minimum entropy bits requirement.
136
		 */
137
		$this->minimum_entropy_bits = apply_filters( 'jetpack_password_checker_minimum_entropy_bits', $this->minimum_entropy_bits );
138
	}
139
140
	/**
141
	 * Run tests against a password.
142
	 *
143
	 * @param String  $password      the tested string.
144
	 * @param Boolean $required_only only test against required conditions, defaults to false.
145
	 * @return array $results an array containing failed and passed test results.
146
	 */
147
	public function test( $password, $required_only = false ) {
148
149
		$this->password = $password;
150
		$results        = $this->run_tests( $this->list_tests(), $required_only );
151
152
		// If we've failed on the required tests, return now.
153
		if ( ! empty( $results['failed'] ) ) {
154
			return array(
155
				'passed'       => false,
156
				'test_results' => $results,
157
			);
158
		}
159
160
		$entropy_bits = $this->calculate_entropy_bits( $this->password );
161
162
		// If we have failed the entropy bits test, run the regex tests so we can suggest improvements.
163 View Code Duplication
		if ( $entropy_bits < $this->minimum_entropy_bits ) {
164
			$results['failed']['entropy_bits'] = $entropy_bits;
165
			$results                           = array_merge(
166
				$results,
167
				$this->run_tests( $this->list_tests( 'preg_match' ), false )
0 ignored issues
show
Documentation introduced by
'preg_match' is of type string, but the function expects a false|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
168
			);
169
		}
170
171
		return( array(
172
			'passed'       => empty( $results['failed'] ),
173
			'test_results' => $results,
174
		) );
175
	}
176
177
	/**
178
	 * Run the tests using the currently set up object values.
179
	 *
180
	 * @param array   $tests tests to run.
181
	 * @param Boolean $required_only whether to run only required tests.
182
	 * @return array test results.
183
	 */
184 View Code Duplication
	protected function run_tests( $tests, $required_only = false ) {
185
186
		$results = array(
187
			'passed' => array(),
188
			'failed' => array(),
189
		);
190
191
		foreach ( $tests as $test_type => $section_tests ) {
192
			foreach ( $section_tests as $test_name => $test_data ) {
193
194
				// Skip non-required tests if required_only param is set.
195
				if ( $required_only && ! $test_data['required'] ) {
196
					continue;
197
				}
198
199
				$test_function = 'test_' . $test_type;
200
201
				$result = call_user_func( array( $this, $test_function ), $test_data );
202
203
				if ( $result ) {
204
					$results['passed'][] = array( 'test_name' => $test_name );
205
				} else {
206
					$results['failed'][] = array(
207
						'test_name'   => $test_name,
208
						'explanation' => $test_data['error'],
209
					);
210
211
					if ( isset( $test_data['fail_immediately'] ) ) {
212
						return $results;
213
					}
214
				}
215
			}
216
		}
217
218
		return $results;
219
	}
220
221
	/**
222
	 * Returns a list of tests that need to be run on password strings.
223
	 *
224
	 * @param array $sections only return specific sections with the passed keys, defaults to all.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $sections not be false|array?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
225
	 * @return array test descriptions.
226
	 */
227 View Code Duplication
	protected function list_tests( $sections = false ) {
228
		// Note: these should be in order of priority.
229
		$tests = array(
230
			'preg_match'      => array(
231
				'no_backslashes'   => array(
232
					'pattern'          => '^[^\\\\]*$',
233
					'error'            => __( 'Passwords may not contain the character "\".', 'jetpack' ),
234
					'required'         => true,
235
					'fail_immediately' => true,
236
				),
237
				'minimum_length'   => array(
238
					'pattern'          => '^.{' . $this->min_password_length . ',}',
239
					/* translators: %d is a number of characters in the password. */
240
					'error'            => sprintf( __( 'Password must be at least %d characters.', 'jetpack' ), $this->min_password_length ),
241
					'required'         => true,
242
					'fail_immediately' => true,
243
				),
244
				'has_mixed_case'   => array(
245
					'pattern'  => '([a-z].*?[A-Z]|[A-Z].*?[a-z])',
246
					'error'    => __( 'This password is too easy to guess: you can improve it by adding additional uppercase letters, lowercase letters, or numbers.', 'jetpack' ),
247
					'trim'     => true,
248
					'required' => false,
249
				),
250
				'has_digit'        => array(
251
					'pattern'  => '\d',
252
					'error'    => __( 'This password is too easy to guess: you can improve it by mixing both letters and numbers.', 'jetpack' ),
253
					'trim'     => false,
254
					'required' => false,
255
				),
256
				'has_special_char' => array(
257
					'pattern'  => '[^a-zA-Z\d]',
258
					'error'    => __( 'This password is too easy to guess: you can improve it by including special characters such as !#=?*&.', 'jetpack' ),
259
					'required' => false,
260
				),
261
			),
262
			'compare_to_list' => array(
263
				'not_a_common_password'       => array(
264
					'list_callback'    => 'get_common_passwords',
265
					'compare_callback' => 'negative_in_array',
266
					'error'            => __( 'This is a very common password. Choose something that will be harder for others to guess.', 'jetpack' ),
267
					'required'         => true,
268
				),
269
				'not_same_as_other_user_data' => array(
270
					'list_callback'    => 'get_other_user_data',
271
					'compare_callback' => 'test_not_same_as_other_user_data',
272
					'error'            => __( 'Your password is too weak: Looks like you\'re including easy to guess information about yourself. Try something a little more unique.', 'jetpack' ),
273
					'required'         => true,
274
				),
275
			),
276
		);
277
278
		/**
279
		 * Filters Jetpack's password strength enforcement settings. You can determine the tests run
280
		 * and their order based on whatever criteria you wish to specify.
281
		 *
282
		 * @since 7.2.0
283
		 *
284
		 * @param array $minimum_entropy_bits minimum entropy bits requirement.
285
		 */
286
		$tests = apply_filters( 'jetpack_password_checker_tests', $tests );
287
288
		if ( ! $sections ) {
289
			return $tests;
290
		}
291
292
		$sections = (array) $sections;
293
		return array_intersect_key( $tests, array_flip( $sections ) );
294
	}
295
296
	/**
297
	 * Provides the regular expression tester functionality.
298
	 *
299
	 * @param array $test_data the current test data.
300
	 * @return Boolean does the test pass?
301
	 */
302 View Code Duplication
	protected function test_preg_match( $test_data ) {
303
		$password = stripslashes( $this->password );
304
305
		if ( isset( $test_data['trim'] ) ) {
306
			$password = substr( $password, 1, -1 );
307
		}
308
309
		if ( ! preg_match( '/' . $test_data['pattern'] . '/u', $password ) ) {
310
			return false;
311
		}
312
313
		return true;
314
	}
315
316
	/**
317
	 * Provides the comparison tester functionality.
318
	 *
319
	 * @param array $test_data the current test data.
320
	 * @return Boolean does the test pass?
321
	 */
322 View Code Duplication
	protected function test_compare_to_list( $test_data ) {
323
		$list_callback    = $test_data['list_callback'];
324
		$compare_callback = $test_data['compare_callback'];
325
326
		if (
327
			! is_callable( array( $this, $list_callback ) )
328
			|| ! is_callable( array( $this, $compare_callback ) )
329
		) {
330
			return false;
331
		}
332
333
		$list = call_user_func( array( $this, $list_callback ) );
334
		if ( empty( $list ) ) {
335
			return true;
336
		}
337
338
		return call_user_func( array( $this, $compare_callback ), $this->password, $list );
339
	}
340
341
	/**
342
	 * Getter for the common password list.
343
	 *
344
	 * @return array common passwords.
345
	 */
346
	protected function get_common_passwords() {
347
		return $this->common_passwords;
348
	}
349
350
	/**
351
	 * Returns the widely known user data that can not be used in the password to avoid
352
	 * predictable strings.
353
	 *
354
	 * @return array user data.
355
	 */
356
	protected function get_other_user_data() {
357
		if ( empty( $this->user_id ) ) {
358
			return array();
359
		}
360
361
		$user_data = get_userdata( $this->user_id );
362
		if ( ! $user_data ) {
363
			return array();
364
		}
365
366
		if ( isset( $user_data->ID ) ) {
367
			$this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'first_name', true ) );
368
			$this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'last_name', true ) );
369
			$this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'nickname', true ) );
370
		}
371
372
		if ( isset( $user_data->user_nicename ) ) {
373
			$this->add_user_strings_to_test( $user_data->user_nicename );
374
		}
375
376
		if ( isset( $user_data->display_name ) ) {
377
			$this->add_user_strings_to_test( $user_data->display_name );
378
		}
379
380
		if ( isset( $user_data->first_name ) ) {
381
			$this->add_user_strings_to_test( $user_data->first_name );
382
		}
383
384
		if ( isset( $user_data->last_name ) ) {
385
			$this->add_user_strings_to_test( $user_data->last_name );
386
		}
387
388
		if ( isset( $user_data->user_email ) ) {
389
			$email_username = substr( $user_data->user_email, 0, strpos( $user_data->user_email, '@' ) );
390
			$this->add_user_strings_to_test( $email_username, '.' );
391
			$this->add_user_strings_to_test( $user_data->user_email );
392
		}
393
394
		return $this->user_strings_to_test;
395
	}
396
397
	/**
398
	 * Compare the password for matches with known user data.
399
	 *
400
	 * @param String $password the string to be tested.
401
	 * @param array  $strings_to_test known user data.
402
	 * @return Boolean does the test pass?
403
	 */
404 View Code Duplication
	protected function test_not_same_as_other_user_data( $password, $strings_to_test ) {
405
		$password_lowercase = strtolower( $password );
406
		foreach ( array_unique( $strings_to_test ) as $string ) {
407
			if ( empty( $string ) ) {
408
				continue;
409
			}
410
411
			$string          = strtolower( $string );
412
			$string_reversed = strrev( $string );
413
414
			if ( $password_lowercase === $string || $password_lowercase === $string_reversed ) {
415
				return false;
416
			}
417
418
			// Also check for the string or reversed string with any numbers just stuck to the end to catch things like bob123 as passwords.
419
			if (
420
				preg_match( '/^' . preg_quote( $string, '/' ) . '\d+$/', $password_lowercase )
421
				|| preg_match( '/^' . preg_quote( $string_reversed, '/' ) . '\d+$/', $password_lowercase )
422
			) {
423
				return false;
424
			}
425
		}
426
		return true;
427
	}
428
429
	/**
430
	 * A shorthand for the not in array construct.
431
	 *
432
	 * @param mixed $needle the needle.
433
	 * @param array $haystack the haystack.
434
	 *
435
	 * @return bool is the needle not in the haystack?
436
	 */
437
	protected function negative_in_array( $needle, array $haystack ) {
438
		return ! in_array( $needle, $haystack, true );
439
	}
440
441
	/**
442
	 * A helper function used to break a single string into its constituents so
443
	 * that both the full string and its constituents and any variants thereof
444
	 * can be tested against the password.
445
	 *
446
	 * @param string $string the string to be broken down.
447
	 * @param string $explode_delimiter delimiter.
448
	 *
449
	 * @return bool
450
	 */
451
	protected function add_user_strings_to_test( $string, $explode_delimiter = ' ' ) {
452
		// Don't check against empty strings.
453
		if ( empty( $string ) ) {
454
			return false;
455
		}
456
457
		$strings = explode( $explode_delimiter, $string );
458
459
		// Remove any non alpha numeric characters from the strings to check against.
460
		foreach ( $strings as $key => $_string ) {
461
			$strings[ $key ] = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $_string ) );
462
		}
463
464
		// Check the original too.
465
		$strings[] = trim( $string );
466
467
		// Check the original minus non alpha numeric characters.
468
		$strings[] = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $string ) );
469
470
		// Remove any empty strings.
471
		$strings = array_filter( $strings );
472
		if ( empty( $strings ) ) {
473
			return false;
474
		}
475
476
		$this->user_strings_to_test = array_unique( array_merge( $this->user_strings_to_test, $strings ) );
477
478
		return true;
479
	}
480
481
	/**
482
	 * Return a character set size that is used in the string.
483
	 *
484
	 * @param String $password the password.
485
	 * @return Integer number of different character sets in use.
486
	 */
487 View Code Duplication
	protected function get_charset_size( $password ) {
488
		$size = 0;
489
490
		// Lowercase a-z.
491
		if ( preg_match( '/[a-z]/', $password ) ) {
492
			$size += 26;
493
		}
494
495
		// Uppercase A-Z.
496
		if ( preg_match( '/[A-Z]/', substr( $password, 1, -1 ) ) ) {
497
			$size += 26;
498
		}
499
500
		// Digits.
501
		if ( preg_match( '/\d/', substr( $password, 1, -1 ) ) ) {
502
			$size += 10;
503
		}
504
505
		// Over digits symbols.
506
		if ( preg_match( '/[!|@|#|$|%|^|&|*|(|)]/', $password ) ) {
507
			$size += 10;
508
		}
509
510
		// Other symbols.
511
		if ( preg_match( '#[`|~|-|_|=|+|\[|{|\]|}|\\|\|;:\'",<\.>/\?]#', $password ) ) {
512
			$size += 20;
513
		}
514
515
		// Spaces.
516
		if ( strpos( $password, ' ' ) ) {
517
			$size++;
518
		}
519
520
		return $size;
521
	}
522
523
	/**
524
	 * Shorthand for getting a character index.
525
	 *
526
	 * @param String $char character.
527
	 * @return Integer the character code.
528
	 */
529 View Code Duplication
	protected function get_char_index( $char ) {
530
		$char = strtolower( $char[0] );
531
		if ( $char < 'a' || $char > 'z' ) {
532
			return 0;
533
		} else {
534
			return ord( $char[0] ) - ord( 'a' ) + 1;
535
		}
536
	}
537
538
	/**
539
	 * This is the password strength calculation algorithm, based on the formula H = L(logN/log2).
540
	 *
541
	 * H = Entropy
542
	 * L = String length (the for iterator)
543
	 * N = Our charset size, via get_charset_size()
544
	 *
545
	 * @see https://en.wikipedia.org/wiki/Password_strength#Random_passwords
546
	 *
547
	 * On top of the base formula, we're also multiplying the bits of entropy for every char
548
	 * by 1 - (the probabily of it following the previous char)
549
	 * i.e.: the probablity of U following Q is ~0.84. If our password contains this pair of characters,
550
	 * the u char will only add ( 0.16^2 * charset_score ) to our total of entropy bits.
551
	 *
552
	 * @param String $password the password.
553
	 */
554 View Code Duplication
	protected function calculate_entropy_bits( $password ) {
555
		$bits          = 0;
556
		$charset_score = log( $this->get_charset_size( $password ) ) / log( 2 );
557
558
		$aidx   = $this->get_char_index( $password[0] );
559
		$length = strlen( $password );
560
561
		for ( $b = 1; $b < $length; $b++ ) {
562
			$bidx = $this->get_char_index( $password[ $b ] );
563
564
			// 27 = number of chars in the index (a-z,' ').
565
			$c     = 1.0 - $this->frequency_table[ $aidx * 27 + $bidx ];
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
	 * @var Array
580
	 */
581
	public $frequency_table = array(
582
		0.23653710453418866,
583
		0.04577693541332556,
584
		0.03449832337075375,
585
		0.042918209651552706,
586
		0.037390873305146524,
587
		0.028509112115468728,
588
		0.02350896632162123,
589
		0.022188657238664526,
590
		0.028429800262428927,
591
		0.04357019973757107,
592
		0.00913602565971716,
593
		0.03223093745443942,
594
		0.02235311269864412,
595
		0.04438081352966905,
596
		0.04512377897652719,
597
		0.020055401662049863,
598
		0.055903192885260244,
599
		0.0024388394809739026,
600
		0.035207464644991984,
601
		0.07355941099285611,
602
		0.036905671380667734,
603
		0.026134421927394666,
604
		0.023787724158040528,
605
		0.011352092141711621,
606
		0.0032354570637119114,
607
		0.005986878553725033,
608
		0.008861933226417843,
609
		0.11511532293337222,
610
		0.027556203528211108,
611
		0.024331243621519172,
612
		0.039266365359381834,
613
		0.031599941682461,
614
		0.014403265782183991,
615
		0.015480973902901297,
616
		0.027770812071730572,
617
		0.00942761335471643,
618
		0.039872867764980315,
619
		0.0078122175244204695,
620
		0.02808456043154979,
621
		0.08429100451960927,
622
		0.04688963405744277,
623
		0.13831170724595424,
624
		0.002540311998833649,
625
		0.025211838460416972,
626
		0.001543082081936142,
627
		0.09519638431258201,
628
		0.061845750109345385,
629
		0.08907071001603732,
630
		0.02137571074500656,
631
		0.027093162268552268,
632
		0.005521504592506197,
633
		0.003023181221752442,
634
		0.007086747339262283,
635
		0.010262720513194342,
636
		0.08785070710016038,
637
		0.14617757690625455,
638
		0.03417291150313457,
639
		0.0059635515381250915,
640
		0.006146668610584633,
641
		0.195202799241872,
642
		0.002774748505613063,
643
		0.004715556203528212,
644
		0.0044776206444088066,
645
		0.11205481848665985,
646
		0.005654468581425864,
647
		0.0028820527773727946,
648
		0.07383000437381543,
649
		0.005516839189386207,
650
		0.006496573844583759,
651
		0.09843067502551392,
652
		0.0027140982650532145,
653
		0.0006893133109782768,
654
		0.08425368129464937,
655
		0.021325557661466685,
656
		0.006493074792243767,
657
		0.07023414491908442,
658
		0.002077270739174807,
659
		0.0024633328473538415,
660
		0.0007744569179180639,
661
		0.015413325557661468,
662
		0.0011990086018370024,
663
		0.13162851727657093,
664
		0.10115993585070711,
665
		0.0026989357049132527,
666
		0.03319317684793702,
667
		0.002946202070272634,
668
		0.0783216212275842,
669
		0.0018358361277154103,
670
		0.00258813238081353,
671
		0.2141688292754046,
672
		0.09853681294649366,
673
		0.0032482869222918796,
674
		0.04359352675317102,
675
		0.01993526753171016,
676
		0.0036880011663507797,
677
		0.008011663507799971,
678
		0.12014696019827964,
679
		0.0029846916460125384,
680
		0.0017553579238956116,
681
		0.029470185158186325,
682
		0.010413179763813967,
683
		0.030699518880303252,
684
		0.03508499781309229,
685
		0.002021285901734947,
686
		0.0010613792097973467,
687
		0.0005295232541186761,
688
		0.009677212421635807,
689
		0.010585799679253535,
690
		0.17101734946785244,
691
		0.07968625164018078,
692
		0.007839043592360402,
693
		0.005438693687126403,
694
		0.0183606939787141,
695
		0.2732701559994168,
696
		0.004953491762647616,
697
		0.007259367254701851,
698
		0.008104971570199739,
699
		0.13274588132380813,
700
		0.004210526315789474,
701
		0.004997813092287506,
702
		0.017006560723137484,
703
		0.007442484327161393,
704
		0.016789619478058026,
705
		0.08477737279486806,
706
		0.005106283714827234,
707
		0.0005026971861787433,
708
		0.04040355736987899,
709
		0.037535500801866156,
710
		0.00885960052485785,
711
		0.0336410555474559,
712
		0.007066919376002332,
713
		0.005344219273946639,
714
		0.0006333284735384167,
715
		0.010684939495553289,
716
		0.0063064586674442345,
717
		0.15386849394955532,
718
		0.015049424114302375,
719
		0.012162705933809595,
720
		0.020425134859308938,
721
		0.037366379938766583,
722
		0.02157165767604607,
723
		0.009373961218836564,
724
		0.0173214754337367,
725
		0.009616562181075958,
726
		0.029522670943286193,
727
		0.010154249890654615,
728
		0.018600962239393497,
729
		0.06362210234728094,
730
		0.03157078291296107,
731
		0.151603440734801,
732
		0.0062329785683044175,
733
		0.014775331681003062,
734
		0.0020854351946347867,
735
		0.1826342032366234,
736
		0.0878017203674005,
737
		0.054190989940224525,
738
		0.010329202507654177,
739
		0.012763376585508092,
740
		0.0064872430383437815,
741
		0.006381105117364048,
742
		0.005388540603586529,
743
		0.0090800408222773,
744
		0.09611196967487973,
745
		0.09940691062837148,
746
		0.01033969966467415,
747
		0.004034407348009914,
748
		0.008826942703017933,
749
		0.11474675608689314,
750
		0.07132584924916169,
751
		0.012388977985129028,
752
		0.005435194634786413,
753
		0.1417174515235457,
754
		0.0037066627788307337,
755
		0.0045802595130485495,
756
		0.060800699810468,
757
		0.005341886572386646,
758
		0.005683627350925791,
759
		0.12434932205860913,
760
		0.004596588423968508,
761
		0.0007534626038781163,
762
		0.07107041842834232,
763
		0.022361277154104096,
764
		0.04784720804782038,
765
		0.06277533168100306,
766
		0.003441901151771395,
767
		0.005828254847645429,
768
		0.0009669047966175828,
769
		0.009470768333576322,
770
		0.002077270739174807,
771
		0.12797667298440007,
772
		0.08797783933518005,
773
		0.005388540603586529,
774
		0.0024913252660737715,
775
		0.007550954949701123,
776
		0.2786866890217233,
777
		0.002509986878553725,
778
		0.029002478495407494,
779
		0.0303204548768042,
780
		0.07576614666861058,
781
		0.00246799825047383,
782
		0.00592389561160519,
783
		0.039574281965301064,
784
		0.00706808572678233,
785
		0.03304505029887739,
786
		0.05474150750838315,
787
		0.0028633911648928414,
788
		0.0005073625892987316,
789
		0.07293541332555767,
790
		0.053528502697186175,
791
		0.022566554891383584,
792
		0.038151334013704616,
793
		0.002716430966613209,
794
		0.005049132526607377,
795
		0.0009902318122175246,
796
		0.008997229916897508,
797
		0.0011861787432570347,
798
		0.1666377022889634,
799
		0.14414462749671964,
800
		0.003374252806531564,
801
		0.005169266656947077,
802
		0.008468873013558828,
803
		0.16337541915731155,
804
		0.002873888321912815,
805
		0.004305000728969237,
806
		0.0031141565825922144,
807
		0.1241172182533897,
808
		0.0052800699810468,
809
		0.008969237498177577,
810
		0.024094474413179766,
811
		0.017029887738737422,
812
		0.01722700102055693,
813
		0.10618457501093455,
814
		0.006147834961364631,
815
		0.0008269427030179326,
816
		0.03303571949263741,
817
		0.024188948826359528,
818
		0.05213937891820965,
819
		0.04505846333284735,
820
		0.0035270447587111824,
821
		0.006799825047383001,
822
		0.0008199445983379502,
823
		0.02206735675754483,
824
		0.001010059775477475,
825
		0.11971191135734072,
826
		0.04656538854060359,
827
		0.011243621519171892,
828
		0.06513019390581717,
829
		0.032375564951159064,
830
		0.06347047674588133,
831
		0.013678961947805804,
832
		0.03309870243475726,
833
		0.006982942119842543,
834
		0.009726199154395685,
835
		0.010121592068814697,
836
		0.032514360693978714,
837
		0.04986032949409535,
838
		0.039734072022160664,
839
		0.15690683773144773,
840
		0.03949963551538125,
841
		0.014790494241143023,
842
		0.002722262720513194,
843
		0.02614375273363464,
844
		0.10753637556495116,
845
		0.06764834523983088,
846
		0.006221315060504448,
847
		0.021317393206006705,
848
		0.0030826651115322934,
849
		0.002399183554454002,
850
		0.0019069835252952323,
851
		0.015595276279341012,
852
		0.0925126111678087,
853
		0.18437906400349907,
854
		0.006538562472663654,
855
		0.008719638431258201,
856
		0.02116693395538708,
857
		0.18241376293920394,
858
		0.007290858725761773,
859
		0.005976381396705059,
860
		0.005629975215045925,
861
		0.09721300481119698,
862
		0.004810030616707975,
863
		0.024303251202799244,
864
		0.012954658113427612,
865
		0.011057005394372358,
866
		0.02733459688001166,
867
		0.10135121737862662,
868
		0.012016912086309959,
869
		0.001055547455897361,
870
		0.009027555037177431,
871
		0.07162326869806095,
872
		0.01007143898527482,
873
		0.07297623560285756,
874
		0.006741507508383147,
875
		0.0036891675171307776,
876
		0.0008409389123778977,
877
		0.011272780288671819,
878
		0.007020265344802449,
879
		0.1030389269572824,
880
		0.15350809155853623,
881
		0.004232686980609419,
882
		0.004353987461729115,
883
		0.0023385333138941536,
884
		0.14450386353695874,
885
		0.002546143752733635,
886
		0.0024470039364338824,
887
		0.01200758128006998,
888
		0.0981227584195947,
889
		0.003161976964572095,
890
		0.040695145064878264,
891
		0.03460446129173349,
892
		0.003908441463770229,
893
		0.01598483743986004,
894
		0.13107216795451232,
895
		0.003129319142732177,
896
		0.00032307916605919226,
897
		0.04050386353695874,
898
		0.05452689896486368,
899
		0.03589677795597026,
900
		0.07087097244496282,
901
		0.006143169558244642,
902
		0.008684647907858289,
903
		0.0004607085580988482,
904
		0.022010205569324977,
905
		0.0009097536083977258,
906
		0.07328765126111678,
907
		0.14751421490013122,
908
		0.008015162560139961,
909
		0.006601545414783497,
910
		0.025279486805656802,
911
		0.1682449336637994,
912
		0.008313748359819215,
913
		0.007010934538562473,
914
		0.005886572386645284,
915
		0.16889575739903775,
916
		0.004123050007289692,
917
		0.011925936725470185,
918
		0.10007289692374982,
919
		0.013380376148126549,
920
		0.009021723283277445,
921
		0.08650823735238372,
922
		0.007756232686980609,
923
		0.0007243038343781893,
924
		0.0026791077416533026,
925
		0.02797492345823006,
926
		0.032384895757399036,
927
		0.04187432570345531,
928
		0.00882461000145794,
929
		0.0032401224668318998,
930
		0.00033357632307916605,
931
		0.027878116343490307,
932
		0.0022277299897944304,
933
		0.14333518005540166,
934
		0.1725534334451086,
935
		0.02781629975215046,
936
		0.006909462020702727,
937
		0.005264907420906838,
938
		0.16661437527336345,
939
		0.004325995043009185,
940
		0.003334596880011664,
941
		0.005312727802886718,
942
		0.14024668318996938,
943
		0.0013261408368566844,
944
		0.003504884093891238,
945
		0.006375273363464061,
946
		0.04964922000291588,
947
		0.008290421344219274,
948
		0.09536783787724158,
949
		0.05394372357486515,
950
		0.005505175681586237,
951
		0.005339553870826651,
952
		0.01782067356757545,
953
		0.006710016037323225,
954
		0.05105933809593235,
955
		0.002983525295232541,
956
		0.002940370316372649,
957
		0.0004548768041988629,
958
		0.01208456043154979,
959
		0.000915585362297711,
960
		0.20146260387811635,
961
		0.067196967487972,
962
		0.006158332118384605,
963
		0.025438110511736407,
964
		0.07753783350342616,
965
		0.1273876658405015,
966
		0.009337804344656656,
967
		0.07683452398308792,
968
		0.0070412596588423975,
969
		0.08747164309666132,
970
		0.0038827817466102928,
971
		0.018116926665694706,
972
		0.005017641055547455,
973
		0.004567429654468581,
974
		0.028277008310249308,
975
		0.05271555620352821,
976
		0.004394809739029013,
977
		0.0013343052923166642,
978
		0.00411605190260971,
979
		0.059621519171890944,
980
		0.09073859163143316,
981
		0.01446858142586383,
982
		0.006770666277883074,
983
		0.003425572240851436,
984
		0.0004455459979588861,
985
		0.010401516256013998,
986
		0.005825922146085436,
987
		0.10833882490158916,
988
		0.007584779122321038,
989
		0.016903921854497742,
990
		0.02719580113719201,
991
		0.0304814112844438,
992
		0.02206385770520484,
993
		0.013064295086747339,
994
		0.02696369733197259,
995
		0.009581571657676046,
996
		0.026761918647033093,
997
		0.006510570053943724,
998
		0.021941390873305145,
999
		0.07042659279778393,
1000
		0.05437410701268406,
1001
		0.1425175681586237,
1002
		0.027802303542790494,
1003
		0.037690625455605774,
1004
		0.0019606356611750987,
1005
		0.1095623268698061,
1006
		0.06157748942994606,
1007
		0.044618749088788455,
1008
		0.04955124653739612,
1009
		0.03608689313310978,
1010
		0.018381688292754043,
1011
		0.003404577926811489,
1012
		0.015036594255722409,
1013
		0.009600233270156,
1014
		0.10794693103951014,
1015
		0.12447528794284882,
1016
		0.0031981338387520046,
1017
		0.0074716430966613205,
1018
		0.003202799241871993,
1019
		0.13437643971424407,
1020
		0.006655197550663361,
1021
		0.0036693395538708266,
1022
		0.049338970695436656,
1023
		0.09486863974340283,
1024
		0.0015990669193760023,
1025
		0.0026604461291733486,
1026
		0.051775477474850555,
1027
		0.0041347135150896636,
1028
		0.005450357194926374,
1029
		0.12030325120279925,
1030
		0.04581309228750547,
1031
		0.0004537104534188657,
1032
		0.12425601399620935,
1033
		0.025981629975215047,
1034
		0.023926519900860182,
1035
		0.04423385333138941,
1036
		0.0017950138504155123,
1037
		0.002661612479953346,
1038
		0.0006333284735384167,
1039
		0.008449045050298877,
1040
		0.000653156436798367,
1041
		0.04816678816153958,
1042
		0.008625164018078437,
1043
		0.0039037760606502403,
1044
		0.005228750546726928,
1045
		0.004531272780288672,
1046
		0.0056672984400058316,
1047
		0.00359585945473101,
1048
		0.0032179618020119548,
1049
		0.0038093016474704767,
1050
		0.011452398308791368,
1051
		0.002519317684793702,
1052
		0.00280390727511299,
1053
		0.005572824026826068,
1054
		0.004554599795888614,
1055
		0.004531272780288672,
1056
		0.0035841959469310393,
1057
		0.004400641492928998,
1058
		0.0036670068523108326,
1059
		0.004839189386207902,
1060
		0.006258638285464354,
1061
		0.004897506925207757,
1062
		0.840776789619478,
1063
		0.004968654322787578,
1064
		0.002886718180492783,
1065
		0.0019757982213150604,
1066
		0.0018568304417553576,
1067
		0.001691208630995772,
1068
		0.09009243329931477,
1069
		0.14030150167662925,
1070
		0.013242746756086894,
1071
		0.013746610293045632,
1072
		0.027342761335471644,
1073
		0.16938912377897652,
1074
		0.006607377168683481,
1075
		0.01661933226417845,
1076
		0.008173786266219566,
1077
		0.13297448607668758,
1078
		0.0034675608689313307,
1079
		0.016641492928998396,
1080
		0.011722991689750693,
1081
		0.021493512173786266,
1082
		0.03430820819361423,
1083
		0.10099548039072752,
1084
		0.00873596734217816,
1085
		0.0018323370753754193,
1086
		0.020103222044029742,
1087
		0.047197550663362,
1088
		0.040833940807697915,
1089
		0.03361189677795597,
1090
		0.010844729552412887,
1091
		0.005544831608106138,
1092
		0.0007522962530981193,
1093
		0.01525120279924187,
1094
		0.00815512465373961,
1095
		0.2109648636827526,
1096
		0.058258055110074355,
1097
		0.007181221752442048,
1098
		0.043560868931331105,
1099
		0.004058900714389853,
1100
		0.10618107595859454,
1101
		0.0062399766729844,
1102
		0.004835690333867911,
1103
		0.02679224376731302,
1104
		0.08414637702288964,
1105
		0.0030698352529523252,
1106
		0.03637498177576906,
1107
		0.01592885260242018,
1108
		0.017413617145356466,
1109
		0.008430383437818923,
1110
		0.037231083248286924,
1111
		0.03290275550371775,
1112
		0.007538125091121154,
1113
		0.004500947660008748,
1114
		0.05932409972299169,
1115
		0.16006764834523984,
1116
		0.03309636973319726,
1117
		0.007766729844000583,
1118
		0.005225251494386936,
1119
		0.0006321621227584196,
1120
		0.012989648636827526,
1121
		0.005274238227146815,
1122
		0.1254503571949264,
1123
		0.12852719055255868,
1124
		0.0035433736696311416,
1125
		0.005203090829566993,
1126
		0.0019314768916751715,
1127
		0.20520775623268697,
1128
		0.002509986878553725,
1129
		0.00343606939787141,
1130
		0.027138649948972155,
1131
		0.13926578218399185,
1132
		0.004565096952908587,
1133
		0.005614812654905963,
1134
		0.00874413179763814,
1135
		0.004109053797929727,
1136
		0.008300918501239247,
1137
		0.08270943286193323,
1138
		0.002912377897652719,
1139
		0.0037066627788307337,
1140
		0.06909578655780726,
1141
		0.03242805073625893,
1142
		0.05237614812654906,
1143
		0.04723487388832191,
1144
		0.0038991106575302524,
1145
		0.006299460562764251,
1146
		0.00043388249015891526,
1147
		0.020029741944889927,
1148
		0.005311561452106721,
1149
		0.09334072022160665,
1150
		0.022940953491762648,
1151
		0.024658988190698353,
1152
		0.02901297565242747,
1153
		0.03531593526753171,
1154
		0.0758023035427905,
1155
		0.013711619769645722,
1156
		0.021597317393206007,
1157
		0.009670214316955824,
1158
		0.044728386062108175,
1159
		0.010596296836273509,
1160
		0.03264382563055839,
1161
		0.0604822860475288,
1162
		0.05489546581134276,
1163
		0.11501851581863246,
1164
		0.01837585653885406,
1165
		0.026237060796034405,
1166
		0.0011255285026971862,
1167
		0.08704125965884241,
1168
		0.10156349322058608,
1169
		0.06660562764251349,
1170
		0.023434319871701415,
1171
		0.010777081207173057,
1172
		0.005409534917626476,
1173
		0.003123487388832191,
1174
		0.0028762210234728096,
1175
		0.0089995626184575,
1176
		0.07518297127861205,
1177
		0.2314868056568013,
1178
		0.002226563639014434,
1179
		0.003285610147251786,
1180
		0.0027455897361131363,
1181
		0.2724537104534189,
1182
		0.0016655489138358362,
1183
		0.0019209797346551977,
1184
		0.0022137337804344656,
1185
		0.17690392185449774,
1186
		0.0014532730718763668,
1187
		0.0024994897215337513,
1188
		0.015302522233561744,
1189
		0.003441901151771395,
1190
		0.015303688584341741,
1191
		0.09314593964134713,
1192
		0.0017833503426155418,
1193
		0.0005108616416387229,
1194
		0.017828838023035427,
1195
		0.010385187345094037,
1196
		0.003168975069252078,
1197
		0.01902901297565243,
1198
		0.005525003644846187,
1199
		0.0010088934246974776,
1200
		0.0009272488700976819,
1201
		0.036282840064149294,
1202
		0.0022977110365942554,
1203
		0.0766805656801283,
1204
		0.22270418428342326,
1205
		0.005283569033386791,
1206
		0.007155562035282111,
1207
		0.01173582154833066,
1208
		0.1715620352821111,
1209
		0.003925936725470185,
1210
		0.004425134859308937,
1211
		0.020040239101909902,
1212
		0.14243242455168392,
1213
		0.0016737133692958156,
1214
		0.0066808572678232975,
1215
		0.011980755212130047,
1216
		0.012638577052048404,
1217
		0.07206065024055984,
1218
		0.08115701997375711,
1219
		0.00710424260096224,
1220
		0.0007278028867181805,
1221
		0.02347630849978131,
1222
		0.04595538708266512,
1223
		0.01481965301064295,
1224
		0.013925061962385188,
1225
		0.0018125091121154687,
1226
		0.00529173348884677,
1227
		0.0016340574427759146,
1228
		0.03072401224668319,
1229
		0.0023746901880740633,
1230
		0.25174165330223064,
1231
		0.06673392622831317,
1232
		0.00878378772415804,
1233
		0.03956261845750109,
1234
		0.010077270739174807,
1235
		0.0844787869951888,
1236
		0.00985216503863537,
1237
		0.004973319725907567,
1238
		0.01893220586091267,
1239
		0.11200583175389998,
1240
		0.0028715556203528212,
1241
		0.004095057588569762,
1242
		0.01202391019098994,
1243
		0.01756757544831608,
1244
		0.014825484764542934,
1245
		0.05312961073042717,
1246
		0.06746872721971132,
1247
		0.003845458521650386,
1248
		0.0210806239976673,
1249
		0.019443067502551394,
1250
		0.08017028721387957,
1251
		0.01825572240851436,
1252
		0.005365213587986587,
1253
		0.01959702580551101,
1254
		0.026184575010934536,
1255
		0.02474879720075813,
1256
		0.002171745152354571,
1257
		0.25827321767021433,
1258
		0.048050153083539875,
1259
		0.01043184137629392,
1260
		0.03930485493512174,
1261
		0.027640180784370902,
1262
		0.03294007872867765,
1263
		0.006474413179763814,
1264
		0.018314039947514214,
1265
		0.015119405161102202,
1266
		0.014706516984983233,
1267
		0.005494678524566263,
1268
		0.03309870243475726,
1269
		0.043864120134130345,
1270
		0.058996355153812505,
1271
		0.06265986295378335,
1272
		0.04633328473538417,
1273
		0.03790756670068523,
1274
		0.0004642076104388394,
1275
		0.037849249161685375,
1276
		0.08369966467415076,
1277
		0.04999679253535501,
1278
		0.02392768625164018,
1279
		0.010998687855372504,
1280
		0.009881323808135296,
1281
		0.003867619186470331,
1282
		0.012434465665548913,
1283
		0.007253535500801866,
1284
		0.11106225397288234,
1285
		0.17624726636535937,
1286
		0.008209943140399476,
1287
		0.008390727511299025,
1288
		0.012682898381688294,
1289
		0.1825653885406036,
1290
		0.001538416678816154,
1291
		0.004590756670068524,
1292
		0.008710307625018223,
1293
		0.1299513048549351,
1294
		0.002677941390873305,
1295
		0.012309666132089225,
1296
		0.014087184720804781,
1297
		0.01199941682461,
1298
		0.031246537396121883,
1299
		0.07206648199445984,
1300
		0.008254264470039366,
1301
		0.0007033095203382417,
1302
		0.007034261554162415,
1303
		0.006599212713223502,
1304
		0.013906400349905234,
1305
		0.050098265053214755,
1306
		0.007133401370462167,
1307
		0.017750692520775622,
1308
		0.0008257763522379356,
1309
		0.03918821985712203,
1310
		0.06015454147834961,
1311
	);
1312
}
1313