Merge "merge msg script now detects extensions main files"
[lhc/web/wiklou.git] / tests / phpunit / languages / LanguageTest.php
1 <?php
2
3 class LanguageTest extends MediaWikiTestCase {
4
5 /**
6 * @var Language
7 */
8 private $lang;
9
10 function setUp() {
11 $this->lang = Language::factory( 'en' );
12 }
13 function tearDown() {
14 unset( $this->lang );
15 }
16
17 function testLanguageConvertDoubleWidthToSingleWidth() {
18 $this->assertEquals(
19 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
20 $this->lang->normalizeForSearch(
21 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
22 ),
23 'convertDoubleWidth() with the full alphabet and digits'
24 );
25 }
26
27 /** @dataProvider provideFormattableTimes */
28 function testFormatTimePeriod( $seconds, $format, $expected, $desc ) {
29 $this->assertEquals( $expected, $this->lang->formatTimePeriod( $seconds, $format ), $desc );
30 }
31
32 function provideFormattableTimes() {
33 return array(
34 array( 9.45, array(), '9.5s', 'formatTimePeriod() rounding (<10s)' ),
35 array( 9.45, array( 'noabbrevs' => true ), '9.5 seconds', 'formatTimePeriod() rounding (<10s)' ),
36 array( 9.95, array(), '10s', 'formatTimePeriod() rounding (<10s)' ),
37 array( 9.95, array( 'noabbrevs' => true ), '10 seconds', 'formatTimePeriod() rounding (<10s)' ),
38 array( 59.55, array(), '1m 0s', 'formatTimePeriod() rounding (<60s)' ),
39 array( 59.55, array( 'noabbrevs' => true ), '1 minute 0 seconds', 'formatTimePeriod() rounding (<60s)' ),
40 array( 119.55, array(), '2m 0s', 'formatTimePeriod() rounding (<1h)' ),
41 array( 119.55, array( 'noabbrevs' => true ), '2 minutes 0 seconds', 'formatTimePeriod() rounding (<1h)' ),
42 array( 3599.55, array(), '1h 0m 0s', 'formatTimePeriod() rounding (<1h)' ),
43 array( 3599.55, array( 'noabbrevs' => true ), '1 hour 0 minutes 0 seconds', 'formatTimePeriod() rounding (<1h)' ),
44 array( 7199.55, array(), '2h 0m 0s', 'formatTimePeriod() rounding (>=1h)' ),
45 array( 7199.55, array( 'noabbrevs' => true ), '2 hours 0 minutes 0 seconds', 'formatTimePeriod() rounding (>=1h)' ),
46 array( 7199.55, 'avoidseconds', '2h 0m', 'formatTimePeriod() rounding (>=1h), avoidseconds' ),
47 array( 7199.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '2 hours 0 minutes', 'formatTimePeriod() rounding (>=1h), avoidseconds' ),
48 array( 7199.55, 'avoidminutes', '2h 0m', 'formatTimePeriod() rounding (>=1h), avoidminutes' ),
49 array( 7199.55, array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), '2 hours 0 minutes', 'formatTimePeriod() rounding (>=1h), avoidminutes' ),
50 array( 172799.55, 'avoidseconds', '48h 0m', 'formatTimePeriod() rounding (=48h), avoidseconds' ),
51 array( 172799.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '48 hours 0 minutes', 'formatTimePeriod() rounding (=48h), avoidseconds' ),
52 array( 259199.55, 'avoidminutes', '3d 0h', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
53 array( 259199.55, array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), '3 days 0 hours', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
54 array( 176399.55, 'avoidseconds', '2d 1h 0m', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
55 array( 176399.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '2 days 1 hour 0 minutes', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
56 array( 176399.55, 'avoidminutes', '2d 1h', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
57 array( 176399.55, array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), '2 days 1 hour', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
58 array( 259199.55, 'avoidseconds', '3d 0h 0m', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
59 array( 259199.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '3 days 0 hours 0 minutes', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
60 array( 172801.55, 'avoidseconds', '2d 0h 0m', 'formatTimePeriod() rounding, (>48h), avoidseconds' ),
61 array( 172801.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '2 days 0 hours 0 minutes', 'formatTimePeriod() rounding, (>48h), avoidseconds' ),
62 array( 176460.55, array(), '2d 1h 1m 1s', 'formatTimePeriod() rounding, recursion, (>48h)' ),
63 array( 176460.55, array( 'noabbrevs' => true ), '2 days 1 hour 1 minute 1 second', 'formatTimePeriod() rounding, recursion, (>48h)' ),
64 );
65
66 }
67
68 function testTruncate() {
69 $this->assertEquals(
70 "XXX",
71 $this->lang->truncate( "1234567890", 0, 'XXX' ),
72 'truncate prefix, len 0, small ellipsis'
73 );
74
75 $this->assertEquals(
76 "12345XXX",
77 $this->lang->truncate( "1234567890", 8, 'XXX' ),
78 'truncate prefix, small ellipsis'
79 );
80
81 $this->assertEquals(
82 "123456789",
83 $this->lang->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ),
84 'truncate prefix, large ellipsis'
85 );
86
87 $this->assertEquals(
88 "XXX67890",
89 $this->lang->truncate( "1234567890", -8, 'XXX' ),
90 'truncate suffix, small ellipsis'
91 );
92
93 $this->assertEquals(
94 "123456789",
95 $this->lang->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ),
96 'truncate suffix, large ellipsis'
97 );
98 }
99
100 /**
101 * @dataProvider provideHTMLTruncateData()
102 */
103 function testTruncateHtml( $len, $ellipsis, $input, $expected ) {
104 // Actual HTML...
105 $this->assertEquals(
106 $expected,
107 $this->lang->truncateHTML( $input, $len, $ellipsis )
108 );
109 }
110
111 /**
112 * Array format is ($len, $ellipsis, $input, $expected)
113 */
114 function provideHTMLTruncateData() {
115 return array(
116 array( 0, 'XXX', "1234567890", "XXX" ),
117 array( 8, 'XXX', "1234567890", "12345XXX" ),
118 array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ),
119 array( 2, '***',
120 '<p><span style="font-weight:bold;"></span></p>',
121 '<p><span style="font-weight:bold;"></span></p>',
122 ),
123 array( 2, '***',
124 '<p><span style="font-weight:bold;">123456789</span></p>',
125 '<p><span style="font-weight:bold;">***</span></p>',
126 ),
127 array( 2, '***',
128 '<p><span style="font-weight:bold;">&nbsp;23456789</span></p>',
129 '<p><span style="font-weight:bold;">***</span></p>',
130 ),
131 array( 3, '***',
132 '<p><span style="font-weight:bold;">123456789</span></p>',
133 '<p><span style="font-weight:bold;">***</span></p>',
134 ),
135 array( 4, '***',
136 '<p><span style="font-weight:bold;">123456789</span></p>',
137 '<p><span style="font-weight:bold;">1***</span></p>',
138 ),
139 array( 5, '***',
140 '<tt><span style="font-weight:bold;">123456789</span></tt>',
141 '<tt><span style="font-weight:bold;">12***</span></tt>',
142 ),
143 array( 6, '***',
144 '<p><a href="www.mediawiki.org">123456789</a></p>',
145 '<p><a href="www.mediawiki.org">123***</a></p>',
146 ),
147 array( 6, '***',
148 '<p><a href="www.mediawiki.org">12&nbsp;456789</a></p>',
149 '<p><a href="www.mediawiki.org">12&nbsp;***</a></p>',
150 ),
151 array( 7, '***',
152 '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>',
153 '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>',
154 ),
155 array( 8, '***',
156 '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>',
157 '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>',
158 ),
159 array( 9, '***',
160 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
161 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
162 ),
163 array( 10, '***',
164 '<p><font style="font-weight:bold;">123456789</font></p>',
165 '<p><font style="font-weight:bold;">123456789</font></p>',
166 ),
167 );
168 }
169
170 /**
171 * Test Language::isValidBuiltInCode()
172 * @dataProvider provideLanguageCodes
173 */
174 function testBuiltInCodeValidation( $code, $message = '' ) {
175 $this->assertTrue(
176 (bool) Language::isValidBuiltInCode( $code ),
177 "validating code $code $message"
178 );
179 }
180
181 function testBuiltInCodeValidationRejectUnderscore() {
182 $this->assertFalse(
183 (bool) Language::isValidBuiltInCode( 'be_tarask' ),
184 "reject underscore in language code"
185 );
186 }
187
188 function provideLanguageCodes() {
189 return array(
190 array( 'fr' , 'Two letters, minor case' ),
191 array( 'EN' , 'Two letters, upper case' ),
192 array( 'tyv' , 'Three letters' ),
193 array( 'tokipona' , 'long language code' ),
194 array( 'be-tarask', 'With dash' ),
195 array( 'Zh-classical', 'Begin with upper case, dash' ),
196 array( 'Be-x-old', 'With extension (two dashes)' ),
197 );
198 }
199
200 /**
201 * @dataProvider provideSprintfDateSamples
202 */
203 function testSprintfDate( $format, $ts, $expected, $msg ) {
204 $this->assertEquals(
205 $expected,
206 $this->lang->sprintfDate( $format, $ts ),
207 "sprintfDate('$format', '$ts'): $msg"
208 );
209 }
210 /**
211 * bug 33454. sprintfDate should always use UTC.
212 * @dataProvider provideSprintfDateSamples
213 */
214 function testSprintfDateTZ( $format, $ts, $expected, $msg ) {
215 $oldTZ = date_default_timezone_get();
216 $res = date_default_timezone_set( 'Asia/Seoul' );
217 if ( !$res ) {
218 $this->markTestSkipped( "Error setting Timezone" );
219 }
220
221 $this->assertEquals(
222 $expected,
223 $this->lang->sprintfDate( $format, $ts ),
224 "sprintfDate('$format', '$ts'): $msg"
225 );
226
227 date_default_timezone_set( $oldTZ );
228 }
229
230 function provideSprintfDateSamples() {
231 return array(
232 array(
233 'xiY',
234 '20111212000000',
235 '1390', // note because we're testing English locale we get Latin-standard digits
236 'Iranian calendar full year'
237 ),
238 array(
239 'xiy',
240 '20111212000000',
241 '90',
242 'Iranian calendar short year'
243 ),
244 array(
245 'o',
246 '20120101235000',
247 '2011',
248 'ISO 8601 (week) year'
249 ),
250 array(
251 'W',
252 '20120101235000',
253 '52',
254 'Week number'
255 ),
256 array(
257 'W',
258 '20120102235000',
259 '1',
260 'Week number'
261 ),
262 array(
263 'o-\\WW-N',
264 '20091231235000',
265 '2009-W53-4',
266 'leap week'
267 ),
268 // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time
269 array(
270 'Y',
271 '20120102090705',
272 '2012',
273 'Full year'
274 ),
275 array(
276 'y',
277 '20120102090705',
278 '12',
279 '2 digit year'
280 ),
281 array(
282 'L',
283 '20120102090705',
284 '1',
285 'Leap year'
286 ),
287 array(
288 'n',
289 '20120102090705',
290 '1',
291 'Month index, not zero pad'
292 ),
293 array(
294 'N',
295 '20120102090705',
296 '01',
297 'Month index. Zero pad'
298 ),
299 array(
300 'M',
301 '20120102090705',
302 'Jan',
303 'Month abbrev'
304 ),
305 array(
306 'F',
307 '20120102090705',
308 'January',
309 'Full month'
310 ),
311 array(
312 'xg',
313 '20120102090705',
314 'January',
315 'Genitive month name (same in EN)'
316 ),
317 array(
318 'j',
319 '20120102090705',
320 '2',
321 'Day of month (not zero pad)'
322 ),
323 array(
324 'd',
325 '20120102090705',
326 '02',
327 'Day of month (zero-pad)'
328 ),
329 array(
330 'z',
331 '20120102090705',
332 '1',
333 'Day of year (zero-indexed)'
334 ),
335 array(
336 'D',
337 '20120102090705',
338 'Mon',
339 'Day of week (abbrev)'
340 ),
341 array(
342 'l',
343 '20120102090705',
344 'Monday',
345 'Full day of week'
346 ),
347 array(
348 'N',
349 '20120101090705',
350 '7',
351 'Day of week (Mon=1, Sun=7)'
352 ),
353 array(
354 'w',
355 '20120101090705',
356 '0',
357 'Day of week (Sun=0, Sat=6)'
358 ),
359 array(
360 'N',
361 '20120102090705',
362 '1',
363 'Day of week'
364 ),
365 array(
366 'a',
367 '20120102090705',
368 'am',
369 'am vs pm'
370 ),
371 array(
372 'A',
373 '20120102120000',
374 'PM',
375 'AM vs PM'
376 ),
377 array(
378 'a',
379 '20120102000000',
380 'am',
381 'AM vs PM'
382 ),
383 array(
384 'g',
385 '20120102090705',
386 '9',
387 '12 hour, not Zero'
388 ),
389 array(
390 'h',
391 '20120102090705',
392 '09',
393 '12 hour, zero padded'
394 ),
395 array(
396 'G',
397 '20120102090705',
398 '9',
399 '24 hour, not zero'
400 ),
401 array(
402 'H',
403 '20120102090705',
404 '09',
405 '24 hour, zero'
406 ),
407 array(
408 'H',
409 '20120102110705',
410 '11',
411 '24 hour, zero'
412 ),
413 array(
414 'i',
415 '20120102090705',
416 '07',
417 'Minutes'
418 ),
419 array(
420 's',
421 '20120102090705',
422 '05',
423 'seconds'
424 ),
425 array(
426 'U',
427 '20120102090705',
428 '1325495225',
429 'unix time'
430 ),
431 array(
432 't',
433 '20120102090705',
434 '31',
435 'Days in current month'
436 ),
437 array(
438 'c',
439 '20120102090705',
440 '2012-01-02T09:07:05+00:00',
441 'ISO 8601 timestamp'
442 ),
443 array(
444 'r',
445 '20120102090705',
446 'Mon, 02 Jan 2012 09:07:05 +0000',
447 'RFC 5322'
448 ),
449 array(
450 'xmj xmF xmn xmY',
451 '20120102090705',
452 '7 Safar 2 1433',
453 'Islamic'
454 ),
455 array(
456 'xij xiF xin xiY',
457 '20120102090705',
458 '12 Dey 10 1390',
459 'Iranian'
460 ),
461 array(
462 'xjj xjF xjn xjY',
463 '20120102090705',
464 '7 Tevet 4 5772',
465 'Hebrew'
466 ),
467 array(
468 'xjt',
469 '20120102090705',
470 '29',
471 'Hebrew number of days in month'
472 ),
473 array(
474 'xjx',
475 '20120102090705',
476 'Tevet',
477 'Hebrew genitive month name (No difference in EN)'
478 ),
479 array(
480 'xkY',
481 '20120102090705',
482 '2555',
483 'Thai year'
484 ),
485 array(
486 'xoY',
487 '20120102090705',
488 '101',
489 'Minguo'
490 ),
491 array(
492 'xtY',
493 '20120102090705',
494 '平成24',
495 'nengo'
496 ),
497 array(
498 'xrxkYY',
499 '20120102090705',
500 'MMDLV2012',
501 'Roman numerals'
502 ),
503 array(
504 'xhxjYY',
505 '20120102090705',
506 \'תשע"ב2012',
507 'Hebrew numberals'
508 ),
509 array(
510 'xnY',
511 '20120102090705',
512 '2012',
513 'Raw numerals (doesn\'t mean much in EN)'
514 ),
515 array(
516 '[[Y "(yea"\\r)]] \\"xx\\"',
517 '20120102090705',
518 '[[2012 (year)]] "x"',
519 'Various escaping'
520 ),
521
522 );
523 }
524
525 /**
526 * @dataProvider provideFormatSizes
527 */
528 function testFormatSize( $size, $expected, $msg ) {
529 $this->assertEquals(
530 $expected,
531 $this->lang->formatSize( $size ),
532 "formatSize('$size'): $msg"
533 );
534 }
535
536 function provideFormatSizes() {
537 return array(
538 array(
539 0,
540 "0 B",
541 "Zero bytes"
542 ),
543 array(
544 1024,
545 "1 KB",
546 "1 kilobyte"
547 ),
548 array(
549 1024 * 1024,
550 "1 MB",
551 "1,024 megabytes"
552 ),
553 array(
554 1024 * 1024 * 1024,
555 "1 GB",
556 "1 gigabytes"
557 ),
558 array(
559 pow( 1024, 4 ),
560 "1 TB",
561 "1 terabyte"
562 ),
563 array(
564 pow( 1024, 5 ),
565 "1 PB",
566 "1 petabyte"
567 ),
568 array(
569 pow( 1024, 6 ),
570 "1 EB",
571 "1,024 exabyte"
572 ),
573 array(
574 pow( 1024, 7 ),
575 "1 ZB",
576 "1 zetabyte"
577 ),
578 array(
579 pow( 1024, 8 ),
580 "1 YB",
581 "1 yottabyte"
582 ),
583 // How big!? THIS BIG!
584 );
585 }
586
587 /**
588 * @dataProvider provideFormatBitrate
589 */
590 function testFormatBitrate( $bps, $expected, $msg ) {
591 $this->assertEquals(
592 $expected,
593 $this->lang->formatBitrate( $bps ),
594 "formatBitrate('$bps'): $msg"
595 );
596 }
597
598 function provideFormatBitrate() {
599 return array(
600 array(
601 0,
602 "0bps",
603 "0 bits per second"
604 ),
605 array(
606 999,
607 "999bps",
608 "999 bits per second"
609 ),
610 array(
611 1000,
612 "1kbps",
613 "1 kilobit per second"
614 ),
615 array(
616 1000 * 1000,
617 "1Mbps",
618 "1 megabit per second"
619 ),
620 array(
621 pow( 10, 9 ),
622 "1Gbps",
623 "1 gigabit per second"
624 ),
625 array(
626 pow( 10, 12 ),
627 "1Tbps",
628 "1 terabit per second"
629 ),
630 array(
631 pow( 10, 15 ),
632 "1Pbps",
633 "1 petabit per second"
634 ),
635 array(
636 pow( 10, 18 ),
637 "1Ebps",
638 "1 exabit per second"
639 ),
640 array(
641 pow( 10, 21 ),
642 "1Zbps",
643 "1 zetabit per second"
644 ),
645 array(
646 pow( 10, 24 ),
647 "1Ybps",
648 "1 yottabit per second"
649 ),
650 array(
651 pow( 10, 27 ),
652 "1,000Ybps",
653 "1,000 yottabits per second"
654 ),
655 );
656 }
657
658
659
660 /**
661 * @dataProvider provideFormatDuration
662 */
663 function testFormatDuration( $duration, $expected, $intervals = array() ) {
664 $this->assertEquals(
665 $expected,
666 $this->lang->formatDuration( $duration, $intervals ),
667 "formatDuration('$duration'): $expected"
668 );
669 }
670
671 function provideFormatDuration() {
672 return array(
673 array(
674 0,
675 '0 seconds',
676 ),
677 array(
678 1,
679 '1 second',
680 ),
681 array(
682 2,
683 '2 seconds',
684 ),
685 array(
686 60,
687 '1 minute',
688 ),
689 array(
690 2 * 60,
691 '2 minutes',
692 ),
693 array(
694 3600,
695 '1 hour',
696 ),
697 array(
698 2 * 3600,
699 '2 hours',
700 ),
701 array(
702 24 * 3600,
703 '1 day',
704 ),
705 array(
706 2 * 86400,
707 '2 days',
708 ),
709 array(
710 365.25 * 86400, // 365.25 * 86400 = 31557600
711 '1 year',
712 ),
713 array(
714 2 * 31557600,
715 '2 years',
716 ),
717 array(
718 10 * 31557600,
719 '1 decade',
720 ),
721 array(
722 20 * 31557600,
723 '2 decades',
724 ),
725 array(
726 100 * 31557600,
727 '1 century',
728 ),
729 array(
730 200 * 31557600,
731 '2 centuries',
732 ),
733 array(
734 1000 * 31557600,
735 '1 millennium',
736 ),
737 array(
738 2000 * 31557600,
739 '2 millennia',
740 ),
741 array(
742 9001,
743 '2 hours, 30 minutes and 1 second'
744 ),
745 array(
746 3601,
747 '1 hour and 1 second'
748 ),
749 array(
750 31557600 + 2 * 86400 + 9000,
751 '1 year, 2 days, 2 hours and 30 minutes'
752 ),
753 array(
754 42 * 1000 * 31557600 + 42,
755 '42 millennia and 42 seconds'
756 ),
757 array(
758 60,
759 '60 seconds',
760 array( 'seconds' ),
761 ),
762 array(
763 61,
764 '61 seconds',
765 array( 'seconds' ),
766 ),
767 array(
768 1,
769 '1 second',
770 array( 'seconds' ),
771 ),
772 array(
773 31557600 + 2 * 86400 + 9000,
774 '1 year, 2 days and 150 minutes',
775 array( 'years', 'days', 'minutes' ),
776 ),
777 array(
778 42,
779 '0 days',
780 array( 'years', 'days' ),
781 ),
782 array(
783 31557600 + 2 * 86400 + 9000,
784 '1 year, 2 days and 150 minutes',
785 array( 'minutes', 'days', 'years' ),
786 ),
787 array(
788 42,
789 '0 days',
790 array( 'days', 'years' ),
791 ),
792 );
793 }
794
795 /**
796 * @dataProvider provideCheckTitleEncodingData
797 */
798 function testCheckTitleEncoding( $s ) {
799 $this->assertEquals(
800 $s,
801 $this->lang->checkTitleEncoding($s),
802 "checkTitleEncoding('$s')"
803 );
804 }
805
806 function provideCheckTitleEncodingData() {
807 return array (
808 array( "" ),
809 array( "United States of America" ), // 7bit ASCII
810 array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ),
811 array(
812 rawurldecode(
813 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn"
814 )
815 ),
816 // The following two data sets come from bug 36839. They fail if checkTitleEncoding uses a regexp to test for
817 // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding
818 // uses mb_check_encoding for its test.
819 array(
820 rawurldecode(
821 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C"
822 . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C"
823 . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C"
824 . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C"
825 . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C"
826 . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C"
827 . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C"
828 . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C"
829 . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C"
830 . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C"
831 . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C"
832 . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C"
833 . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C"
834 . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis"
835 ),
836 ),
837 array(
838 rawurldecode(
839 "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C"
840 . "Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C"
841 . "Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C"
842 . "Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C"
843 . "Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou"
844 . "%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C"
845 . "Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C"
846 . "Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C"
847 . "Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C"
848 . "Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C"
849 . "Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C"
850 . "Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C"
851 . "Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C"
852 . "Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C"
853 . "Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes"
854 )
855 )
856 );
857 }
858 }