summaryrefslogtreecommitdiff
path: root/languages
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2006-10-11 20:21:25 +0000
committerPierre Schmitz <pierre@archlinux.de>2006-10-11 20:21:25 +0000
commitd81f562b712f2387fa02290bf2ca86392ab356f2 (patch)
treed666cdefbe6ac320827a2c6cb473581b46e22c4c /languages
parent183851b06bd6c52f3cae5375f433da720d410447 (diff)
Aktualisierung auf Version 1.8.1
Diffstat (limited to 'languages')
-rw-r--r--languages/Language.php1503
-rw-r--r--languages/LanguageConverter.php140
-rw-r--r--languages/Names.php27
-rw-r--r--languages/classes/LanguageAz.php17
-rw-r--r--languages/classes/LanguageBe.php89
-rw-r--r--languages/classes/LanguageBg.php25
-rw-r--r--languages/classes/LanguageBs.php137
-rw-r--r--languages/classes/LanguageCs.php87
-rw-r--r--languages/classes/LanguageEo.php74
-rw-r--r--languages/classes/LanguageEt.php21
-rw-r--r--languages/classes/LanguageFi.php165
-rw-r--r--languages/classes/LanguageFr.php17
-rw-r--r--languages/classes/LanguageGa.php52
-rw-r--r--languages/classes/LanguageGsw.php69
-rw-r--r--languages/classes/LanguageHe.php70
-rw-r--r--languages/classes/LanguageHr.php26
-rw-r--r--languages/classes/LanguageHu.php53
-rw-r--r--languages/classes/LanguageJa.php42
-rw-r--r--languages/classes/LanguageKo.php57
-rw-r--r--languages/classes/LanguageKsh.php35
-rw-r--r--languages/classes/LanguageLa.php37
-rw-r--r--languages/classes/LanguageLt.php22
-rw-r--r--languages/classes/LanguageLv.php57
-rw-r--r--languages/classes/LanguagePt_br.php17
-rw-r--r--languages/classes/LanguageRmy.php72
-rw-r--r--languages/classes/LanguageRu.php87
-rw-r--r--languages/classes/LanguageSk.php94
-rw-r--r--languages/classes/LanguageSl.php124
-rw-r--r--languages/classes/LanguageSr.deps.php10
-rw-r--r--languages/classes/LanguageSr.php181
-rw-r--r--languages/classes/LanguageSr_ec.php28
-rw-r--r--languages/classes/LanguageSr_el.deps.php9
-rw-r--r--languages/classes/LanguageSr_el.php28
-rw-r--r--languages/classes/LanguageTr.php18
-rw-r--r--languages/classes/LanguageTyv.php233
-rw-r--r--languages/classes/LanguageVi.php74
-rw-r--r--languages/classes/LanguageWa.php71
-rw-r--r--languages/classes/LanguageZh.deps.php10
-rw-r--r--languages/classes/LanguageZh.php101
-rw-r--r--languages/classes/LanguageZh_cn.php27
-rw-r--r--languages/classes/LanguageZh_yue.php27
-rw-r--r--languages/messages/MessagesAb.php5
-rw-r--r--languages/messages/MessagesAf.php694
-rw-r--r--languages/messages/MessagesAn.php24
-rw-r--r--languages/messages/MessagesAr.php607
-rw-r--r--languages/messages/MessagesArc.php15
-rw-r--r--languages/messages/MessagesAs.php20
-rw-r--r--languages/messages/MessagesAst.php29
-rw-r--r--languages/messages/MessagesAv.php9
-rw-r--r--languages/messages/MessagesAy.php9
-rw-r--r--languages/messages/MessagesAz.php674
-rw-r--r--languages/messages/MessagesBa.php201
-rw-r--r--languages/messages/MessagesBar.php17
-rw-r--r--languages/messages/MessagesBat_smg.php9
-rw-r--r--languages/messages/MessagesBe.php837
-rw-r--r--languages/messages/MessagesBg.php1379
-rw-r--r--languages/messages/MessagesBm.php9
-rw-r--r--languages/messages/MessagesBn.php133
-rw-r--r--languages/messages/MessagesBo.php20
-rw-r--r--languages/messages/MessagesBpy.php11
-rw-r--r--languages/messages/MessagesBr.php1096
-rw-r--r--languages/messages/MessagesBs.php1093
-rw-r--r--languages/messages/MessagesCa.php1247
-rw-r--r--languages/messages/MessagesCe.php9
-rw-r--r--languages/messages/MessagesCs.php2080
-rw-r--r--languages/messages/MessagesCsb.php326
-rw-r--r--languages/messages/MessagesCv.php244
-rw-r--r--languages/messages/MessagesCy.php845
-rw-r--r--languages/messages/MessagesDa.php1340
-rw-r--r--languages/messages/MessagesDe.php1972
-rw-r--r--languages/messages/MessagesDv.php9
-rw-r--r--languages/messages/MessagesDz.php22
-rw-r--r--languages/messages/MessagesEl.php1769
-rw-r--r--languages/messages/MessagesEn.php2457
-rw-r--r--languages/messages/MessagesEnRTL.php5
-rw-r--r--languages/messages/MessagesEo.php1250
-rw-r--r--languages/messages/MessagesEs.php1708
-rw-r--r--languages/messages/MessagesEt.php897
-rw-r--r--languages/messages/MessagesEu.php201
-rw-r--r--languages/messages/MessagesFa.php924
-rw-r--r--languages/messages/MessagesFi.php1908
-rw-r--r--languages/messages/MessagesFo.php116
-rw-r--r--languages/messages/MessagesFr.php1533
-rw-r--r--languages/messages/MessagesFur.php727
-rw-r--r--languages/messages/MessagesFy.php861
-rw-r--r--languages/messages/MessagesGa.php1785
-rw-r--r--languages/messages/MessagesGn.php9
-rw-r--r--languages/messages/MessagesGsw.php793
-rw-r--r--languages/messages/MessagesGu.php19
-rw-r--r--languages/messages/MessagesHe.php2118
-rw-r--r--languages/messages/MessagesHi.php128
-rw-r--r--languages/messages/MessagesHr.php1558
-rw-r--r--languages/messages/MessagesHu.php1052
-rw-r--r--languages/messages/MessagesIa.php801
-rw-r--r--languages/messages/MessagesId.php1919
-rw-r--r--languages/messages/MessagesIi.php9
-rw-r--r--languages/messages/MessagesIs.php705
-rw-r--r--languages/messages/MessagesIt.php1839
-rw-r--r--languages/messages/MessagesJa.php1673
-rw-r--r--languages/messages/MessagesJbo.php23
-rw-r--r--languages/messages/MessagesJv.php45
-rw-r--r--languages/messages/MessagesKa.php574
-rw-r--r--languages/messages/MessagesKk.php10
-rw-r--r--languages/messages/MessagesKk_cn.php10
-rw-r--r--languages/messages/MessagesKm.php22
-rw-r--r--languages/messages/MessagesKn.php376
-rw-r--r--languages/messages/MessagesKo.php1204
-rw-r--r--languages/messages/MessagesKs.php11
-rw-r--r--languages/messages/MessagesKsh.php2345
-rw-r--r--languages/messages/MessagesKu.php774
-rw-r--r--languages/messages/MessagesKv.php9
-rw-r--r--languages/messages/MessagesLa.php822
-rw-r--r--languages/messages/MessagesLi.php941
-rw-r--r--languages/messages/MessagesLo.php22
-rw-r--r--languages/messages/MessagesLt.php942
-rw-r--r--languages/messages/MessagesLv.php978
-rw-r--r--languages/messages/MessagesMk.php1708
-rw-r--r--languages/messages/MessagesMl.php23
-rw-r--r--languages/messages/MessagesMs.php816
-rw-r--r--languages/messages/MessagesMzn.php23
-rw-r--r--languages/messages/MessagesNah.php51
-rw-r--r--languages/messages/MessagesNap.php10
-rw-r--r--languages/messages/MessagesNds.php1170
-rw-r--r--languages/messages/MessagesNds_nl.php60
-rw-r--r--languages/messages/MessagesNl.php1900
-rw-r--r--languages/messages/MessagesNn.php1601
-rw-r--r--languages/messages/MessagesNo.php1367
-rw-r--r--languages/messages/MessagesNon.php11
-rw-r--r--languages/messages/MessagesNv.php72
-rw-r--r--languages/messages/MessagesOc.php800
-rw-r--r--languages/messages/MessagesOr.php22
-rw-r--r--languages/messages/MessagesOs.php217
-rw-r--r--languages/messages/MessagesPa.php410
-rw-r--r--languages/messages/MessagesPl.php1793
-rw-r--r--languages/messages/MessagesPms.php1699
-rw-r--r--languages/messages/MessagesPs.php17
-rw-r--r--languages/messages/MessagesPt.php1998
-rw-r--r--languages/messages/MessagesPt_br.php789
-rw-r--r--languages/messages/MessagesQu.php9
-rw-r--r--languages/messages/MessagesRmy.php337
-rw-r--r--languages/messages/MessagesRo.php1626
-rw-r--r--languages/messages/MessagesRu.php2168
-rw-r--r--languages/messages/MessagesSc.php655
-rw-r--r--languages/messages/MessagesSd.php12
-rw-r--r--languages/messages/MessagesSk.php1889
-rw-r--r--languages/messages/MessagesSl.php1586
-rw-r--r--languages/messages/MessagesSq.php1496
-rw-r--r--languages/messages/MessagesSr.php12
-rw-r--r--languages/messages/MessagesSr_ec.php2125
-rw-r--r--languages/messages/MessagesSr_el.php2128
-rw-r--r--languages/messages/MessagesSr_jc.php10
-rw-r--r--languages/messages/MessagesSr_jl.php10
-rw-r--r--languages/messages/MessagesSu.php1029
-rw-r--r--languages/messages/MessagesSv.php1524
-rw-r--r--languages/messages/MessagesTa.php730
-rw-r--r--languages/messages/MessagesTe.php836
-rw-r--r--languages/messages/MessagesTg.php34
-rw-r--r--languages/messages/MessagesTh.php214
-rw-r--r--languages/messages/MessagesTlh.php30
-rw-r--r--languages/messages/MessagesTr.php1116
-rw-r--r--languages/messages/MessagesTt.php119
-rw-r--r--languages/messages/MessagesTyv.php306
-rw-r--r--languages/messages/MessagesUdm.php51
-rw-r--r--languages/messages/MessagesUg.php10
-rw-r--r--languages/messages/MessagesUk.php826
-rw-r--r--languages/messages/MessagesUr.php33
-rw-r--r--languages/messages/MessagesUz.php11
-rw-r--r--languages/messages/MessagesVec.php1174
-rw-r--r--languages/messages/MessagesVi.php1315
-rw-r--r--languages/messages/MessagesWa.php1768
-rw-r--r--languages/messages/MessagesXal.php55
-rw-r--r--languages/messages/MessagesYi.php469
-rw-r--r--languages/messages/MessagesZa.php9
-rw-r--r--languages/messages/MessagesZh.php7
-rw-r--r--languages/messages/MessagesZh_cn.php855
-rw-r--r--languages/messages/MessagesZh_hk.php10
-rw-r--r--languages/messages/MessagesZh_sg.php10
-rw-r--r--languages/messages/MessagesZh_tw.php844
-rw-r--r--languages/messages/MessagesZh_yue.php2127
179 files changed, 102489 insertions, 533 deletions
diff --git a/languages/Language.php b/languages/Language.php
index cbb5e316..454d60e1 100644
--- a/languages/Language.php
+++ b/languages/Language.php
@@ -4,7 +4,10 @@
* @subpackage Language
*/
-if( defined( 'MEDIAWIKI' ) ) {
+if( !defined( 'MEDIAWIKI' ) ) {
+ echo "This file is part of MediaWiki, it is not a valid entry point.\n";
+ exit( 1 );
+}
#
# In general you should not make customizations in these language files
@@ -18,294 +21,26 @@ if( defined( 'MEDIAWIKI' ) ) {
# files for examples.
#
-#--------------------------------------------------------------------------
-# Language-specific text
-#--------------------------------------------------------------------------
-
-if($wgMetaNamespace === FALSE)
- $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
-
-/* private */ $wgNamespaceNamesEn = array(
- NS_MEDIA => 'Media',
- NS_SPECIAL => 'Special',
- NS_MAIN => '',
- NS_TALK => 'Talk',
- NS_USER => 'User',
- NS_USER_TALK => 'User_talk',
- NS_PROJECT => $wgMetaNamespace,
- NS_PROJECT_TALK => $wgMetaNamespace . '_talk',
- NS_IMAGE => 'Image',
- NS_IMAGE_TALK => 'Image_talk',
- NS_MEDIAWIKI => 'MediaWiki',
- NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
- NS_TEMPLATE => 'Template',
- NS_TEMPLATE_TALK => 'Template_talk',
- NS_HELP => 'Help',
- NS_HELP_TALK => 'Help_talk',
- NS_CATEGORY => 'Category',
- NS_CATEGORY_TALK => 'Category_talk',
-);
-
-if(isset($wgExtraNamespaces)) {
- $wgNamespaceNamesEn=$wgNamespaceNamesEn+$wgExtraNamespaces;
-}
-
-/* private */ $wgDefaultUserOptionsEn = array(
- 'quickbar' => 1,
- 'underline' => 2,
- 'cols' => 80,
- 'rows' => 25,
- 'searchlimit' => 20,
- 'contextlines' => 5,
- 'contextchars' => 50,
- 'skin' => $wgDefaultSkin,
- 'math' => 1,
- 'rcdays' => 7,
- 'rclimit' => 50,
- 'wllimit' => 250,
- 'highlightbroken' => 1,
- 'stubthreshold' => 0,
- 'previewontop' => 1,
- 'editsection' => 1,
- 'editsectiononrightclick'=> 0,
- 'showtoc' => 1,
- 'showtoolbar' => 1,
- 'date' => 0,
- 'imagesize' => 2,
- 'thumbsize' => 2,
- 'rememberpassword' => 0,
- 'enotifwatchlistpages' => 0,
- 'enotifusertalkpages' => 1,
- 'enotifminoredits' => 0,
- 'enotifrevealaddr' => 0,
- 'shownumberswatching' => 1,
- 'fancysig' => 0,
- 'externaleditor' => 0,
- 'externaldiff' => 0,
- 'showjumplinks' => 1,
- 'numberheadings' => 0,
- 'uselivepreview' => 0,
- 'watchlistdays' => 3.0,
-);
-
-/* private */ $wgQuickbarSettingsEn = array(
- 'None', 'Fixed left', 'Fixed right', 'Floating left', 'Floating right'
-);
-
-/* private */ $wgSkinNamesEn = array(
- 'standard' => 'Classic',
- 'nostalgia' => 'Nostalgia',
- 'cologneblue' => 'Cologne Blue',
- 'davinci' => 'DaVinci',
- 'mono' => 'Mono',
- 'monobook' => 'MonoBook',
- 'myskin' => 'MySkin',
- 'chick' => 'Chick'
-);
-
-/* private */ $wgMathNamesEn = array(
- MW_MATH_PNG => 'mw_math_png',
- MW_MATH_SIMPLE => 'mw_math_simple',
- MW_MATH_HTML => 'mw_math_html',
- MW_MATH_SOURCE => 'mw_math_source',
- MW_MATH_MODERN => 'mw_math_modern',
- MW_MATH_MATHML => 'mw_math_mathml'
-);
-
-/**
- * Whether to use user or default setting in Language::date()
- *
- * NOTE: the array string values are no longer important!
- * The actual date format functions are now called for the selection in
- * Special:Preferences, and the 'datedefault' message for MW_DATE_DEFAULT.
- *
- * The array keys make up the set of formats which this language allows
- * the user to select. It's exposed via Language::getDateFormats().
- *
- * @private
- */
-$wgDateFormatsEn = array(
- MW_DATE_DEFAULT => 'No preference',
- MW_DATE_DMY => '16:12, 15 January 2001',
- MW_DATE_MDY => '16:12, January 15, 2001',
- MW_DATE_YMD => '16:12, 2001 January 15',
- MW_DATE_ISO => '2001-01-15 16:12:34'
-);
-
-/* private */ $wgUserTogglesEn = array(
- 'highlightbroken',
- 'justify',
- 'hideminor',
- 'extendwatchlist',
- 'usenewrc',
- 'numberheadings',
- 'showtoolbar',
- 'editondblclick',
- 'editsection',
- 'editsectiononrightclick',
- 'showtoc',
- 'rememberpassword',
- 'editwidth',
- 'watchcreations',
- 'watchdefault',
- 'minordefault',
- 'previewontop',
- 'previewonfirst',
- 'nocache',
- 'enotifwatchlistpages',
- 'enotifusertalkpages',
- 'enotifminoredits',
- 'enotifrevealaddr',
- 'shownumberswatching',
- 'fancysig',
- 'externaleditor',
- 'externaldiff',
- 'showjumplinks',
- 'uselivepreview',
- 'autopatrol',
- 'forceeditsummary',
- 'watchlisthideown',
- 'watchlisthidebots',
-);
-
-/* private */ $wgBookstoreListEn = array(
- 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
- 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
- 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
- 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
-);
-
# Read language names
global $wgLanguageNames;
-/** */
require_once( 'Names.php' );
-$wgLanguageNamesEn =& $wgLanguageNames;
-
-
-/* private */ $wgWeekdayNamesEn = array(
- 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
- 'friday', 'saturday'
-);
+global $wgInputEncoding, $wgOutputEncoding;
+/**
+ * These are always UTF-8, they exist only for backwards compatibility
+ */
+$wgInputEncoding = "UTF-8";
+$wgOutputEncoding = "UTF-8";
-/* private */ $wgMonthNamesEn = array(
- 'january', 'february', 'march', 'april', 'may_long', 'june',
- 'july', 'august', 'september', 'october', 'november',
- 'december'
-);
-/* private */ $wgMonthNamesGenEn = array(
- 'january-gen', 'february-gen', 'march-gen', 'april-gen', 'may-gen', 'june-gen',
- 'july-gen', 'august-gen', 'september-gen', 'october-gen', 'november-gen',
- 'december-gen'
-);
-
-/* private */ $wgMonthAbbreviationsEn = array(
- 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug',
- 'sep', 'oct', 'nov', 'dec'
-);
-
-# Note to translators:
-# Please include the English words as synonyms. This allows people
-# from other wikis to contribute more easily.
-#
-/* private */ $wgMagicWordsEn = array(
-# ID CASE SYNONYMS
- MAG_REDIRECT => array( 0, '#REDIRECT' ),
- MAG_NOTOC => array( 0, '__NOTOC__' ),
- MAG_NOGALLERY => array( 0, '__NOGALLERY__' ),
- MAG_FORCETOC => array( 0, '__FORCETOC__' ),
- MAG_TOC => array( 0, '__TOC__' ),
- MAG_NOEDITSECTION => array( 0, '__NOEDITSECTION__' ),
- MAG_START => array( 0, '__START__' ),
- MAG_CURRENTMONTH => array( 1, 'CURRENTMONTH' ),
- MAG_CURRENTMONTHNAME => array( 1, 'CURRENTMONTHNAME' ),
- MAG_CURRENTMONTHNAMEGEN => array( 1, 'CURRENTMONTHNAMEGEN' ),
- MAG_CURRENTMONTHABBREV => array( 1, 'CURRENTMONTHABBREV' ),
- MAG_CURRENTDAY => array( 1, 'CURRENTDAY' ),
- MAG_CURRENTDAY2 => array( 1, 'CURRENTDAY2' ),
- MAG_CURRENTDAYNAME => array( 1, 'CURRENTDAYNAME' ),
- MAG_CURRENTYEAR => array( 1, 'CURRENTYEAR' ),
- MAG_CURRENTTIME => array( 1, 'CURRENTTIME' ),
- MAG_NUMBEROFPAGES => array( 1, 'NUMBEROFPAGES' ),
- MAG_NUMBEROFARTICLES => array( 1, 'NUMBEROFARTICLES' ),
- MAG_NUMBEROFFILES => array( 1, 'NUMBEROFFILES' ),
- MAG_NUMBEROFUSERS => array( 1, 'NUMBEROFUSERS' ),
- MAG_PAGENAME => array( 1, 'PAGENAME' ),
- MAG_PAGENAMEE => array( 1, 'PAGENAMEE' ),
- MAG_NAMESPACE => array( 1, 'NAMESPACE' ),
- MAG_NAMESPACEE => array( 1, 'NAMESPACEE' ),
- MAG_TALKSPACE => array( 1, 'TALKSPACE' ),
- MAG_TALKSPACEE => array( 1, 'TALKSPACEE' ),
- MAG_SUBJECTSPACE => array( 1, 'SUBJECTSPACE', 'ARTICLESPACE' ),
- MAG_SUBJECTSPACEE => array( 1, 'SUBJECTSPACEE', 'ARTICLESPACEE' ),
- MAG_FULLPAGENAME => array( 1, 'FULLPAGENAME' ),
- MAG_FULLPAGENAMEE => array( 1, 'FULLPAGENAMEE' ),
- MAG_SUBPAGENAME => array( 1, 'SUBPAGENAME' ),
- MAG_SUBPAGENAMEE => array( 1, 'SUBPAGENAMEE' ),
- MAG_BASEPAGENAME => array( 1, 'BASEPAGENAME' ),
- MAG_BASEPAGENAMEE => array( 1, 'BASEPAGENAMEE' ),
- MAG_TALKPAGENAME => array( 1, 'TALKPAGENAME' ),
- MAG_TALKPAGENAMEE => array( 1, 'TALKPAGENAMEE' ),
- MAG_SUBJECTPAGENAME => array( 1, 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ),
- MAG_SUBJECTPAGENAMEE => array( 1, 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ),
- MAG_MSG => array( 0, 'MSG:' ),
- MAG_SUBST => array( 0, 'SUBST:' ),
- MAG_MSGNW => array( 0, 'MSGNW:' ),
- MAG_END => array( 0, '__END__' ),
- MAG_IMG_THUMBNAIL => array( 1, 'thumbnail', 'thumb' ),
- MAG_IMG_MANUALTHUMB => array( 1, 'thumbnail=$1', 'thumb=$1'),
- MAG_IMG_RIGHT => array( 1, 'right' ),
- MAG_IMG_LEFT => array( 1, 'left' ),
- MAG_IMG_NONE => array( 1, 'none' ),
- MAG_IMG_WIDTH => array( 1, '$1px' ),
- MAG_IMG_CENTER => array( 1, 'center', 'centre' ),
- MAG_IMG_FRAMED => array( 1, 'framed', 'enframed', 'frame' ),
- MAG_INT => array( 0, 'INT:' ),
- MAG_SITENAME => array( 1, 'SITENAME' ),
- MAG_NS => array( 0, 'NS:' ),
- MAG_LOCALURL => array( 0, 'LOCALURL:' ),
- MAG_LOCALURLE => array( 0, 'LOCALURLE:' ),
- MAG_SERVER => array( 0, 'SERVER' ),
- MAG_SERVERNAME => array( 0, 'SERVERNAME' ),
- MAG_SCRIPTPATH => array( 0, 'SCRIPTPATH' ),
- MAG_GRAMMAR => array( 0, 'GRAMMAR:' ),
- MAG_NOTITLECONVERT => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
- MAG_NOCONTENTCONVERT => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
- MAG_CURRENTWEEK => array( 1, 'CURRENTWEEK' ),
- MAG_CURRENTDOW => array( 1, 'CURRENTDOW' ),
- MAG_REVISIONID => array( 1, 'REVISIONID' ),
- MAG_PLURAL => array( 0, 'PLURAL:' ),
- MAG_FULLURL => array( 0, 'FULLURL:' ),
- MAG_FULLURLE => array( 0, 'FULLURLE:' ),
- MAG_LCFIRST => array( 0, 'LCFIRST:' ),
- MAG_UCFIRST => array( 0, 'UCFIRST:' ),
- MAG_LC => array( 0, 'LC:' ),
- MAG_UC => array( 0, 'UC:' ),
- MAG_RAW => array( 0, 'RAW:' ),
- MAG_DISPLAYTITLE => array( 1, 'DISPLAYTITLE' ),
- MAG_RAWSUFFIX => array( 1, 'R' ),
- MAG_NEWSECTIONLINK => array( 1, '__NEWSECTIONLINK__' ),
- MAG_CURRENTVERSION => array( 1, 'CURRENTVERSION' ),
- MAG_URLENCODE => array( 0, 'URLENCODE:' ),
- MAG_CURRENTTIMESTAMP => array( 1, 'CURRENTTIMESTAMP' ),
- MAG_DIRECTIONMARK => array( 1, 'DIRECTIONMARK', 'DIRMARK' ),
- MAG_LANGUAGE => array( 0, '#LANGUAGE:' ),
- MAG_CONTENTLANGUAGE => array( 1, 'CONTENTLANGUAGE', 'CONTENTLANG' ),
- MAG_PAGESINNAMESPACE => array( 1, 'PAGESINNAMESPACE:', 'PAGESINNS:' ),
- MAG_NUMBEROFADMINS => array( 1, 'NUMBEROFADMINS' ),
- MAG_FORMATNUM => array( 0, 'FORMATNUM' ),
-
-);
-
-if (!$wgCachedMessageArrays) {
- require_once('Messages.php');
+if( function_exists( 'mb_strtoupper' ) ) {
+ mb_internal_encoding('UTF-8');
}
/* a fake language converter */
-class fakeConverter {
+class FakeConverter {
var $mLang;
- function fakeConverter($langobj) {$this->mLang = $langobj;}
+ function FakeConverter($langobj) {$this->mLang = $langobj;}
function convert($t, $i) {return $t;}
function parserConvert($t, $p) {return $t;}
function getVariants() { return array( $this->mLang->getCode() ); }
@@ -313,9 +48,10 @@ class fakeConverter {
function findVariantLink(&$l, &$n) {}
function getExtraHashOptions() {return '';}
function getParsedTitle() {return '';}
- function markNoConversion($text) {return $text;}
+ function markNoConversion($text, $noParse=false) {return $text;}
function convertCategoryKey( $key ) {return $key; }
-
+ function convertLinkToAllVariants($text){ return array( $this->mLang->getCode() => $text); }
+ function setNoTitleConvert(){}
}
#--------------------------------------------------------------------------
@@ -323,21 +59,106 @@ class fakeConverter {
#--------------------------------------------------------------------------
class Language {
- var $mConverter;
+ var $mConverter, $mVariants, $mCode, $mLoaded = false;
+
+ static public $mLocalisationKeys = array( 'fallback', 'namespaceNames',
+ 'quickbarSettings', 'skinNames', 'mathNames',
+ 'bookstoreList', 'magicWords', 'messages', 'rtl', 'digitTransformTable',
+ 'separatorTransformTable', 'fallback8bitEncoding', 'linkPrefixExtension',
+ 'defaultUserOptionOverrides', 'linkTrail', 'namespaceAliases',
+ 'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
+ 'defaultDateFormat', 'extraUserToggles' );
+
+ static public $mMergeableMapKeys = array( 'messages', 'namespaceNames', 'mathNames',
+ 'dateFormats', 'defaultUserOptionOverrides', 'magicWords' );
+
+ static public $mMergeableListKeys = array( 'extraUserToggles' );
+
+ static public $mLocalisationCache = array();
+
+ static public $mWeekdayMsgs = array(
+ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
+ 'friday', 'saturday'
+ );
+
+ static public $mWeekdayAbbrevMsgs = array(
+ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'
+ );
+
+ static public $mMonthMsgs = array(
+ 'january', 'february', 'march', 'april', 'may_long', 'june',
+ 'july', 'august', 'september', 'october', 'november',
+ 'december'
+ );
+ static public $mMonthGenMsgs = array(
+ 'january-gen', 'february-gen', 'march-gen', 'april-gen', 'may-gen', 'june-gen',
+ 'july-gen', 'august-gen', 'september-gen', 'october-gen', 'november-gen',
+ 'december-gen'
+ );
+ static public $mMonthAbbrevMsgs = array(
+ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug',
+ 'sep', 'oct', 'nov', 'dec'
+ );
+
+ /**
+ * Create a language object for a given language code
+ */
+ static function factory( $code ) {
+ global $IP;
+ static $recursionLevel = 0;
+
+ if ( $code == 'en' ) {
+ $class = 'Language';
+ } else {
+ $class = 'Language' . str_replace( '-', '_', ucfirst( $code ) );
+ // Preload base classes to work around APC/PHP5 bug
+ if ( file_exists( "$IP/languages/classes/$class.deps.php" ) ) {
+ include_once("$IP/languages/classes/$class.deps.php");
+ }
+ if ( file_exists( "$IP/languages/classes/$class.php" ) ) {
+ include_once("$IP/languages/classes/$class.php");
+ }
+ }
+
+ if ( $recursionLevel > 5 ) {
+ throw new MWException( "Language fallback loop detected when creating class $class\n" );
+ }
+
+ if( ! class_exists( $class ) ) {
+ $fallback = Language::getFallbackFor( $code );
+ ++$recursionLevel;
+ $lang = Language::factory( $fallback );
+ --$recursionLevel;
+ $lang->setCode( $code );
+ } else {
+ $lang = new $class;
+ }
+
+ return $lang;
+ }
+
function __construct() {
- $this->mConverter = new fakeConverter($this);
+ $this->mConverter = new FakeConverter($this);
+ // Set the code to the name of the descendant
+ if ( get_class( $this ) == 'Language' ) {
+ $this->mCode = 'en';
+ } else {
+ $this->mCode = str_replace( '_', '-', strtolower( substr( get_class( $this ), 8 ) ) );
+ }
}
/**
- * Exports the default user options as defined in
- * $wgDefaultUserOptionsEn, user preferences can override some of these
- * depending on what's in (Local|Default)Settings.php and some defines.
- *
+ * Hook which will be called if this is the content language.
+ * Descendants can use this to register hook functions or modify globals
+ */
+ function initContLang() {}
+
+ /**
+ * @deprecated
* @return array
*/
function getDefaultUserOptions() {
- global $wgDefaultUserOptionsEn;
- return $wgDefaultUserOptionsEn;
+ return User::getDefaultOptions();
}
/**
@@ -345,16 +166,16 @@ class Language {
* @return array
*/
function getBookstoreList() {
- global $wgBookstoreListEn;
- return $wgBookstoreListEn;
+ $this->load();
+ return $this->bookstoreList;
}
/**
* @return array
*/
function getNamespaces() {
- global $wgNamespaceNamesEn;
- return $wgNamespaceNamesEn;
+ $this->load();
+ return $this->namespaceNames;
}
/**
@@ -407,13 +228,13 @@ class Language {
* @return mixed An integer if $text is a valid value otherwise false
*/
function getNsIndex( $text ) {
- $ns = $this->getNamespaces();
-
- foreach ( $ns as $i => $n ) {
- if ( strcasecmp( $n, $text ) == 0)
- return $i;
+ $this->load();
+ $index = @$this->mNamespaceIds[$this->lc($text)];
+ if ( is_null( $index ) ) {
+ return false;
+ } else {
+ return $index;
}
- return false;
}
/**
@@ -423,7 +244,7 @@ class Language {
* @return string
*/
function getVariantname( $code ) {
- return wfMsg( "variantname-$code" );
+ return $this->getMessageFromDB( "variantname-$code" );
}
function specialPage( $name ) {
@@ -431,77 +252,122 @@ class Language {
}
function getQuickbarSettings() {
- global $wgQuickbarSettingsEn;
- return $wgQuickbarSettingsEn;
+ $this->load();
+ return $this->quickbarSettings;
}
function getSkinNames() {
- global $wgSkinNamesEn;
- return $wgSkinNamesEn;
+ $this->load();
+ return $this->skinNames;
}
function getMathNames() {
- global $wgMathNamesEn;
- return $wgMathNamesEn;
+ $this->load();
+ return $this->mathNames;
}
+ function getDatePreferences() {
+ $this->load();
+ return $this->datePreferences;
+ }
+
function getDateFormats() {
- global $wgDateFormatsEn;
- return $wgDateFormatsEn;
+ $this->load();
+ return $this->dateFormats;
+ }
+
+ function getDefaultDateFormat() {
+ $this->load();
+ return $this->defaultDateFormat;
+ }
+
+ function getDatePreferenceMigrationMap() {
+ $this->load();
+ return $this->datePreferenceMigrationMap;
+ }
+
+ function getDefaultUserOptionOverrides() {
+ $this->load();
+ return $this->defaultUserOptionOverrides;
}
- function getUserToggles() {
- global $wgUserTogglesEn;
- return $wgUserTogglesEn;
+ function getExtraUserToggles() {
+ $this->load();
+ return $this->extraUserToggles;
}
function getUserToggle( $tog ) {
- return wfMsg( "tog-$tog" );
+ return $this->getMessageFromDB( "tog-$tog" );
+ }
+
+ /**
+ * Get language names, indexed by code.
+ * If $customisedOnly is true, only returns codes with a messages file
+ */
+ function getLanguageNames( $customisedOnly = false ) {
+ global $wgLanguageNames;
+ if ( !$customisedOnly ) {
+ return $wgLanguageNames;
+ }
+
+ global $IP;
+ $messageFiles = glob( "$IP/languages/messages/Messages*.php" );
+ $names = array();
+ foreach ( $messageFiles as $file ) {
+ if( preg_match( '/Messages([A-Z][a-z_]+)\.php$/', $file, $m ) ) {
+ $code = str_replace( '_', '-', strtolower( $m[1] ) );
+ if ( isset( $wgLanguageNames[$code] ) ) {
+ $names[$code] = $wgLanguageNames[$code];
+ }
+ }
+ }
+ return $names;
}
- function getLanguageNames() {
- global $wgLanguageNamesEn;
- return $wgLanguageNamesEn;
+ /**
+ * Ugly hack to get a message maybe from the MediaWiki namespace, if this
+ * language object is the content or user language.
+ */
+ function getMessageFromDB( $msg ) {
+ global $wgContLang, $wgLang;
+ if ( $wgContLang->getCode() == $this->getCode() ) {
+ # Content language
+ return wfMsgForContent( $msg );
+ } elseif ( $wgLang->getCode() == $this->getCode() ) {
+ # User language
+ return wfMsg( $msg );
+ } else {
+ # Neither, get from localisation
+ return $this->getMessage( $msg );
+ }
}
function getLanguageName( $code ) {
- global $wgLanguageNamesEn;
- if ( ! array_key_exists( $code, $wgLanguageNamesEn ) ) {
+ global $wgLanguageNames;
+ if ( ! array_key_exists( $code, $wgLanguageNames ) ) {
return '';
}
- return $wgLanguageNamesEn[$code];
+ return $wgLanguageNames[$code];
}
function getMonthName( $key ) {
- global $wgMonthNamesEn, $wgContLang;
- // see who called us and use the correct message function
- if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
- return wfMsgForContent($wgMonthNamesEn[$key-1]);
- else
- return wfMsg($wgMonthNamesEn[$key-1]);
+ return $this->getMessageFromDB( self::$mMonthMsgs[$key-1] );
}
- /* by default we just return base form */
function getMonthNameGen( $key ) {
- return $this->getMonthName( $key );
+ return $this->getMessageFromDB( self::$mMonthGenMsgs[$key-1] );
}
function getMonthAbbreviation( $key ) {
- global $wgMonthAbbreviationsEn, $wgContLang;
- // see who called us and use the correct message function
- if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
- return wfMsgForContent(@$wgMonthAbbreviationsEn[$key-1]);
- else
- return wfMsg(@$wgMonthAbbreviationsEn[$key-1]);
+ return $this->getMessageFromDB( self::$mMonthAbbrevMsgs[$key-1] );
}
function getWeekdayName( $key ) {
- global $wgWeekdayNamesEn, $wgContLang;
- // see who called us and use the correct message function
- if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
- return wfMsgForContent($wgWeekdayNamesEn[$key-1]);
- else
- return wfMsg($wgWeekdayNamesEn[$key-1]);
+ return $this->getMessageFromDB( self::$mWeekdayMsgs[$key-1] );
+ }
+
+ function getWeekdayAbbreviation( $key ) {
+ return $this->getMessageFromDB( self::$mWeekdayAbbrevMsgs[$key-1] );
}
/**
@@ -511,7 +377,6 @@ class Language {
* @param mixed $tz adjust the time by this amount (default false,
* mean we get user timecorrection setting)
* @return int
-
*/
function userAdjust( $ts, $tz = false ) {
global $wgUser, $wgLocalTZoffset;
@@ -553,6 +418,228 @@ class Language {
}
/**
+ * This is a workalike of PHP's date() function, but with better
+ * internationalisation, a reduced set of format characters, and a better
+ * escaping format.
+ *
+ * Supported format characters are dDjlNwzWFmMntLYyaAgGhHiscrU. See the
+ * PHP manual for definitions. There are a number of extensions, which
+ * start with "x":
+ *
+ * xn Do not translate digits of the next numeric format character
+ * xN Toggle raw digit (xn) flag, stays set until explicitly unset
+ * xr Use roman numerals for the next numeric format character
+ * xx Literal x
+ * xg Genitive month name
+ *
+ * Characters enclosed in double quotes will be considered literal (with
+ * the quotes themselves removed). Unmatched quotes will be considered
+ * literal quotes. Example:
+ *
+ * "The month is" F => The month is January
+ * i's" => 20'11"
+ *
+ * Backslash escaping is also supported.
+ *
+ * @param string $format
+ * @param string $ts 14-character timestamp
+ * YYYYMMDDHHMMSS
+ * 01234567890123
+ */
+ function sprintfDate( $format, $ts ) {
+ $s = '';
+ $raw = false;
+ $roman = false;
+ $unix = false;
+ $rawToggle = false;
+ for ( $p = 0; $p < strlen( $format ); $p++ ) {
+ $num = false;
+ $code = $format[$p];
+ if ( $code == 'x' && $p < strlen( $format ) - 1 ) {
+ $code .= $format[++$p];
+ }
+
+ switch ( $code ) {
+ case 'xx':
+ $s .= 'x';
+ break;
+ case 'xn':
+ $raw = true;
+ break;
+ case 'xN':
+ $rawToggle = !$rawToggle;
+ break;
+ case 'xr':
+ $roman = true;
+ break;
+ case 'xg':
+ $s .= $this->getMonthNameGen( substr( $ts, 4, 2 ) );
+ break;
+ case 'd':
+ $num = substr( $ts, 6, 2 );
+ break;
+ case 'D':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= $this->getWeekdayAbbreviation( date( 'w', $unix ) + 1 );
+ break;
+ case 'j':
+ $num = intval( substr( $ts, 6, 2 ) );
+ break;
+ case 'l':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= $this->getWeekdayName( date( 'w', $unix ) + 1 );
+ break;
+ case 'N':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $w = date( 'w', $unix );
+ $num = $w ? $w : 7;
+ break;
+ case 'w':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'w', $unix );
+ break;
+ case 'z':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'z', $unix );
+ break;
+ case 'W':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'W', $unix );
+ break;
+ case 'F':
+ $s .= $this->getMonthName( substr( $ts, 4, 2 ) );
+ break;
+ case 'm':
+ $num = substr( $ts, 4, 2 );
+ break;
+ case 'M':
+ $s .= $this->getMonthAbbreviation( substr( $ts, 4, 2 ) );
+ break;
+ case 'n':
+ $num = intval( substr( $ts, 4, 2 ) );
+ break;
+ case 't':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 't', $unix );
+ break;
+ case 'L':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'L', $unix );
+ break;
+ case 'Y':
+ $num = substr( $ts, 0, 4 );
+ break;
+ case 'y':
+ $num = substr( $ts, 2, 2 );
+ break;
+ case 'a':
+ $s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'am' : 'pm';
+ break;
+ case 'A':
+ $s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'AM' : 'PM';
+ break;
+ case 'g':
+ $h = substr( $ts, 8, 2 );
+ $num = $h % 12 ? $h % 12 : 12;
+ break;
+ case 'G':
+ $num = intval( substr( $ts, 8, 2 ) );
+ break;
+ case 'h':
+ $h = substr( $ts, 8, 2 );
+ $num = sprintf( '%02d', $h % 12 ? $h % 12 : 12 );
+ break;
+ case 'H':
+ $num = substr( $ts, 8, 2 );
+ break;
+ case 'i':
+ $num = substr( $ts, 10, 2 );
+ break;
+ case 's':
+ $num = substr( $ts, 12, 2 );
+ break;
+ case 'c':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= date( 'c', $unix );
+ break;
+ case 'r':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= date( 'r', $unix );
+ break;
+ case 'U':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = $unix;
+ break;
+ case '\\':
+ # Backslash escaping
+ if ( $p < strlen( $format ) - 1 ) {
+ $s .= $format[++$p];
+ } else {
+ $s .= '\\';
+ }
+ break;
+ case '"':
+ # Quoted literal
+ if ( $p < strlen( $format ) - 1 ) {
+ $endQuote = strpos( $format, '"', $p + 1 );
+ if ( $endQuote === false ) {
+ # No terminating quote, assume literal "
+ $s .= '"';
+ } else {
+ $s .= substr( $format, $p + 1, $endQuote - $p - 1 );
+ $p = $endQuote;
+ }
+ } else {
+ # Quote at end of string, assume literal "
+ $s .= '"';
+ }
+ break;
+ default:
+ $s .= $format[$p];
+ }
+ if ( $num !== false ) {
+ if ( $rawToggle || $raw ) {
+ $s .= $num;
+ $raw = false;
+ } elseif ( $roman ) {
+ $s .= self::romanNumeral( $num );
+ $roman = false;
+ } else {
+ $s .= $this->formatNum( $num, true );
+ }
+ $num = false;
+ }
+ }
+ return $s;
+ }
+
+ /**
+ * Roman number formatting up to 3000
+ */
+ static function romanNumeral( $num ) {
+ static $table = array(
+ array( '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X' ),
+ array( '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', 'C' ),
+ array( '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', 'M' ),
+ array( '', 'M', 'MM', 'MMM' )
+ );
+
+ $num = intval( $num );
+ if ( $num > 3000 || $num <= 0 ) {
+ return $num;
+ }
+
+ $s = '';
+ for ( $pow10 = 1000, $i = 3; $i >= 0; $pow10 /= 10, $i-- ) {
+ if ( $num >= $pow10 ) {
+ $s .= $table[$i][floor($num / $pow10)];
+ }
+ $num = $num % $pow10;
+ }
+ return $s;
+ }
+
+ /**
* This is meant to be used by time(), date(), and timeanddate() to get
* the date preference they're supposed to use, it should be used in
* all children.
@@ -561,6 +648,7 @@ class Language {
* function timeanddate([...], $format = true) {
* $datePreference = $this->dateFormat($format);
* [...]
+ * }
*</code>
*
* @param mixed $usePrefs: if true, the user's preference is used
@@ -573,9 +661,9 @@ class Language {
if( is_bool( $usePrefs ) ) {
if( $usePrefs ) {
- $datePreference = $wgUser->getOption( 'date' );
+ $datePreference = $wgUser->getDatePreference();
} else {
- $options = $this->getDefaultUserOptions();
+ $options = User::getDefaultOptions();
$datePreference = (string)$options['date'];
}
} else {
@@ -584,7 +672,7 @@ class Language {
// return int
if( $datePreference == '' ) {
- return MW_DATE_DEFAULT;
+ return 'default';
}
return $datePreference;
@@ -602,25 +690,16 @@ class Language {
* @return string
*/
function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
- global $wgUser, $wgAmericanDates;
-
- if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
-
- $datePreference = $this->dateFormat( $format );
- if( $datePreference == MW_DATE_DEFAULT ) {
- $datePreference = $wgAmericanDates ? MW_DATE_MDY : MW_DATE_DMY;
+ $this->load();
+ if ( $adj ) {
+ $ts = $this->userAdjust( $ts, $timecorrection );
}
- $month = $this->formatMonth( substr( $ts, 4, 2 ), $datePreference );
- $day = $this->formatDay( substr( $ts, 6, 2 ), $datePreference );
- $year = $this->formatNum( substr( $ts, 0, 4 ), true );
-
- switch( $datePreference ) {
- case MW_DATE_DMY: return "$day $month $year";
- case MW_DATE_YMD: return "$year $month $day";
- case MW_DATE_ISO: return substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
- default: return "$month $day, $year";
+ $pref = $this->dateFormat( $format );
+ if( $pref == 'default' || !isset( $this->dateFormats["$pref date"] ) ) {
+ $pref = $this->defaultDateFormat;
}
+ return $this->sprintfDate( $this->dateFormats["$pref date"], $ts );
}
/**
@@ -635,61 +714,16 @@ class Language {
* @return string
*/
function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
- global $wgUser;
-
- if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
- $datePreference = $this->dateFormat( $format );
-
- $sep = $this->timeSeparator( $format );
-
- $hh = substr( $ts, 8, 2 );
- $mm = substr( $ts, 10, 2 );
- $ss = substr( $ts, 12, 2 );
-
- if ( $datePreference != MW_DATE_ISO ) {
- $hh = $this->formatNum( $hh, true );
- $mm = $this->formatNum( $mm, true );
- //$ss = $this->formatNum( $ss, true );
- return $hh . $sep . $mm;
- } else {
- return $hh . ':' . $mm . ':' . $ss;
+ $this->load();
+ if ( $adj ) {
+ $ts = $this->userAdjust( $ts, $timecorrection );
}
- }
-
- /**
- * Default separator character between hours, minutes, and seconds.
- * Will be used by Language::time() for non-ISO formats.
- * (ISO will always use a colon.)
- * @return string
- */
- function timeSeparator( $format ) {
- return ':';
- }
-
- /**
- * String to insert between the time and the date in a combined
- * string. Should include any relevant whitespace.
- * @return string
- */
- function timeDateSeparator( $format ) {
- return ', ';
- }
- /**
- * Return true if the time should display before the date.
- * @return bool
- * @private
- */
- function timeBeforeDate() {
- return true;
- }
-
- function formatMonth( $month, $format ) {
- return $this->getMonthName( $month );
- }
-
- function formatDay( $day, $format ) {
- return $this->formatNum( 0 + $day, true );
+ $pref = $this->dateFormat( $format );
+ if( $pref == 'default' || !isset( $this->dateFormats["$pref time"] ) ) {
+ $pref = $this->defaultDateFormat;
+ }
+ return $this->sprintfDate( $this->dateFormats["$pref time"], $ts );
}
/**
@@ -706,30 +740,27 @@ class Language {
* @return string
*/
function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false) {
- global $wgUser;
+ $this->load();
+ if ( $adj ) {
+ $ts = $this->userAdjust( $ts, $timecorrection );
+ }
- $datePreference = $this->dateFormat($format);
- switch ( $datePreference ) {
- case MW_DATE_ISO: return $this->date( $ts, $adj, $format, $timecorrection ) . ' ' .
- $this->time( $ts, $adj, $format, $timecorrection );
- default:
- $time = $this->time( $ts, $adj, $format, $timecorrection );
- $sep = $this->timeDateSeparator( $datePreference );
- $date = $this->date( $ts, $adj, $format, $timecorrection );
- return $this->timeBeforeDate( $datePreference )
- ? $time . $sep . $date
- : $date . $sep . $time;
+ $pref = $this->dateFormat( $format );
+ if( $pref == 'default' || !isset( $this->dateFormats["$pref both"] ) ) {
+ $pref = $this->defaultDateFormat;
}
+
+ return $this->sprintfDate( $this->dateFormats["$pref both"], $ts );
}
function getMessage( $key ) {
- global $wgAllMessagesEn;
- return @$wgAllMessagesEn[$key];
+ $this->load();
+ return @$this->messages[$key];
}
function getAllMessages() {
- global $wgAllMessagesEn;
- return $wgAllMessagesEn;
+ $this->load();
+ return $this->messages;
}
function iconv( $in, $out, $string ) {
@@ -737,43 +768,166 @@ class Language {
return iconv( $in, $out, $string );
}
- function ucfirst( $string ) {
- # For most languages, this is a wrapper for ucfirst()
- return ucfirst( $string );
+ // callback functions for uc(), lc(), ucwords(), ucwordbreaks()
+ function ucwordbreaksCallbackAscii($matches){
+ return $this->ucfirst($matches[1]);
}
-
- function uc( $str ) {
- return strtoupper( $str );
+
+ function ucwordbreaksCallbackMB($matches){
+ return mb_strtoupper($matches[0]);
+ }
+
+ function ucCallback($matches){
+ list( $wikiUpperChars ) = self::getCaseMaps();
+ return strtr( $matches[1], $wikiUpperChars );
+ }
+
+ function lcCallback($matches){
+ list( , $wikiLowerChars ) = self::getCaseMaps();
+ return strtr( $matches[1], $wikiLowerChars );
+ }
+
+ function ucwordsCallbackMB($matches){
+ return mb_strtoupper($matches[0]);
+ }
+
+ function ucwordsCallbackWiki($matches){
+ list( $wikiUpperChars ) = self::getCaseMaps();
+ return strtr( $matches[0], $wikiUpperChars );
}
- function lcfirst( $s ) {
- return strtolower( $s{0} ). substr( $s, 1 );
+ function ucfirst( $str ) {
+ return self::uc( $str, true );
}
- function lc( $str ) {
- return strtolower( $str );
+ function uc( $str, $first = false ) {
+ if ( function_exists( 'mb_strtoupper' ) )
+ if ( $first )
+ if ( self::isMultibyte( $str ) )
+ return mb_strtoupper( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
+ else
+ return ucfirst( $str );
+ else
+ return self::isMultibyte( $str ) ? mb_strtoupper( $str ) : strtoupper( $str );
+ else
+ if ( self::isMultibyte( $str ) ) {
+ list( $wikiUpperChars ) = $this->getCaseMaps();
+ $x = $first ? '^' : '';
+ return preg_replace_callback(
+ "/$x([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
+ array($this,"ucCallback"),
+ $str
+ );
+ } else
+ return $first ? ucfirst( $str ) : strtoupper( $str );
+ }
+
+ function lcfirst( $str ) {
+ return self::lc( $str, true );
+ }
+
+ function lc( $str, $first = false ) {
+ if ( function_exists( 'mb_strtolower' ) )
+ if ( $first )
+ if ( self::isMultibyte( $str ) )
+ return mb_strtolower( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
+ else
+ return strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 );
+ else
+ return self::isMultibyte( $str ) ? mb_strtolower( $str ) : strtolower( $str );
+ else
+ if ( self::isMultibyte( $str ) ) {
+ list( , $wikiLowerChars ) = self::getCaseMaps();
+ $x = $first ? '^' : '';
+ return preg_replace_callback(
+ "/$x([A-Z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
+ array($this,"lcCallback"),
+ $str
+ );
+ } else
+ return $first ? strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 ) : strtolower( $str );
+ }
+
+ function isMultibyte( $str ) {
+ return (bool)preg_match( '/[\x80-\xff]/', $str );
+ }
+
+ function ucwords($str) {
+ if ( self::isMultibyte( $str ) ) {
+ $str = self::lc($str);
+
+ // regexp to find first letter in each word (i.e. after each space)
+ $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)| ([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
+
+ // function to use to capitalize a single char
+ if ( function_exists( 'mb_strtoupper' ) )
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordsCallbackMB"),
+ $str
+ );
+ else
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordsCallbackWiki"),
+ $str
+ );
+ }
+ else
+ return ucwords( strtolower( $str ) );
+ }
+
+ # capitalize words at word breaks
+ function ucwordbreaks($str){
+ if (self::isMultibyte( $str ) ) {
+ $str = self::lc($str);
+
+ // since \b doesn't work for UTF-8, we explicitely define word break chars
+ $breaks= "[ \-\(\)\}\{\.,\?!]";
+
+ // find first letter after word break
+ $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)|$breaks([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
+
+ if ( function_exists( 'mb_strtoupper' ) )
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordbreaksCallbackMB"),
+ $str
+ );
+ else
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordsCallbackWiki"),
+ $str
+ );
+ }
+ else
+ return preg_replace_callback(
+ '/\b([\w\x80-\xff]+)\b/',
+ array($this,"ucwordbreaksCallbackAscii"),
+ $str );
}
function checkTitleEncoding( $s ) {
- global $wgInputEncoding;
-
- # Check for UTF-8 URLs; Internet Explorer produces these if you
- # type non-ASCII chars in the URL bar or follow unescaped links.
+ if( is_array( $s ) ) {
+ wfDebugDieBacktrace( 'Given array to checkTitleEncoding.' );
+ }
+ # Check for non-UTF-8 URLs
$ishigh = preg_match( '/[\x80-\xff]/', $s);
- $isutf = ($ishigh ? preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
- '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s ) : true );
+ if(!$ishigh) return $s;
- if( ($wgInputEncoding != 'utf-8') and $ishigh and $isutf )
- return @iconv( 'UTF-8', $wgInputEncoding, $s );
+ $isutf8 = preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
+ if( $isutf8 ) return $s;
- if( ($wgInputEncoding == 'utf-8') and $ishigh and !$isutf )
- return utf8_encode( $s );
-
- # Other languages can safely leave this function, or replace
- # it with one to detect and convert another legacy encoding.
- return $s;
+ return $this->iconv( $this->fallback8bitEncoding(), "utf-8", $s );
}
+ function fallback8bitEncoding() {
+ $this->load();
+ return $this->fallback8bitEncoding;
+ }
+
/**
* Some languages have special punctuation to strip out
* or characters which need to be converted for MySQL's
@@ -782,8 +936,25 @@ class Language {
* @param string $in
* @return string
*/
- function stripForSearch( $in ) {
- return strtolower( $in );
+ function stripForSearch( $string ) {
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+
+ wfProfileIn( __METHOD__ );
+ if( function_exists( 'mb_strtolower' ) ) {
+ $out = preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "'U8' . bin2hex( \"$1\" )",
+ mb_strtolower( $string ) );
+ } else {
+ list( , $wikiLowerChars ) = self::getCaseMaps();
+ $out = preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "'U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
+ $string );
+ }
+ wfProfileOut( __METHOD__ );
+ return $out;
}
function convertForSearchResult( $termsArray ) {
@@ -793,15 +964,16 @@ class Language {
}
/**
- * Get the first character of a string. In ASCII, return
- * first byte of the string. UTF8 and others have to
- * overload this.
+ * Get the first character of a string.
*
* @param string $s
* @return string
*/
function firstChar( $s ) {
- return $s[0];
+ preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})/', $s, $matches);
+
+ return isset( $matches[1] ) ? $matches[1] : "";
}
function initEncoding() {
@@ -809,15 +981,6 @@ class Language {
# (Esperanto X-coding, Japanese furigana conversion, etc)
# If this language is used as the primary content language,
# an override to the defaults can be set here on startup.
- #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
- }
-
- function setAltEncoding() {
- # Some languages may have an alternate char encoding option
- # (Esperanto X-coding, Japanese furigana conversion, etc)
- # If 'altencoding' is checked in user prefs, this gives a
- # chance to swap out the default encoding settings.
- #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
}
function recodeForEdit( $s ) {
@@ -827,27 +990,27 @@ class Language {
# Note that if wgOutputEncoding is different from
# wgInputEncoding, this text will be further converted
# to wgOutputEncoding.
- global $wgInputEncoding, $wgEditEncoding;
+ global $wgEditEncoding;
if( $wgEditEncoding == '' or
- $wgEditEncoding == $wgInputEncoding ) {
+ $wgEditEncoding == 'UTF-8' ) {
return $s;
} else {
- return $this->iconv( $wgInputEncoding, $wgEditEncoding, $s );
+ return $this->iconv( 'UTF-8', $wgEditEncoding, $s );
}
}
function recodeInput( $s ) {
# Take the previous into account.
- global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
+ global $wgEditEncoding;
if($wgEditEncoding != "") {
$enc = $wgEditEncoding;
} else {
- $enc = $wgOutputEncoding;
+ $enc = 'UTF-8';
}
- if( $enc == $wgInputEncoding ) {
+ if( $enc == 'UTF-8' ) {
return $s;
} else {
- return $this->iconv( $enc, $wgInputEncoding, $s );
+ return $this->iconv( $enc, 'UTF-8', $s );
}
}
@@ -856,25 +1019,42 @@ class Language {
*
* @return bool
*/
- function isRTL() { return false; }
+ function isRTL() {
+ $this->load();
+ return $this->rtl;
+ }
/**
* A hidden direction mark (LRM or RLM), depending on the language direction
*
* @return string
*/
- function getDirMark() { return $this->isRTL() ? "\xE2\x80\x8F" : "\xE2\x80\x8E"; }
+ function getDirMark() {
+ return $this->isRTL() ? "\xE2\x80\x8F" : "\xE2\x80\x8E";
+ }
+
+ /**
+ * An arrow, depending on the language direction
+ *
+ * @return string
+ */
+ function getArrow() {
+ return $this->isRTL() ? '←' : '→';
+ }
/**
* To allow "foo[[bar]]" to extend the link over the whole word "foobar"
*
* @return bool
*/
- function linkPrefixExtension() { return false; }
+ function linkPrefixExtension() {
+ $this->load();
+ return $this->linkPrefixExtension;
+ }
function &getMagicWords() {
- global $wgMagicWordsEn;
- return $wgMagicWordsEn;
+ $this->load();
+ return $this->magicWords;
}
# Fill a MagicWord object with data from here
@@ -896,6 +1076,9 @@ class Language {
}
}
+ if( !is_array( $rawEntry ) ) {
+ error_log( "\"$rawEntry\" is not a valid magic thingie for \"$mw->mId\"" );
+ }
$mw->mCaseSensitive = $rawEntry[0];
$mw->mSynonyms = array_slice( $rawEntry, 1 );
}
@@ -963,11 +1146,13 @@ class Language {
}
function digitTransformTable() {
- return null;
+ $this->load();
+ return $this->digitTransformTable;
}
function separatorTransformTable() {
- return null;
+ $this->load();
+ return $this->separatorTransformTable;
}
@@ -984,7 +1169,7 @@ class Language {
if ($i == $m) {
$s = $l[$i];
} else if ($i == $m - 1) {
- $s = $l[$i] . ' ' . wfMsg('and') . ' ' . $s;
+ $s = $l[$i] . ' ' . $this->getMessageFromDB( 'and' ) . ' ' . $s;
} else {
$s = $l[$i] . ', ' . $s;
}
@@ -999,7 +1184,7 @@ class Language {
#
# $length does not include the optional ellipsis.
# If $length is negative, snip from the beginning
- function truncate( $string, $length, $ellipsis = '' ) {
+ function truncate( $string, $length, $ellipsis = "" ) {
if( $length == 0 ) {
return $ellipsis;
}
@@ -1008,9 +1193,24 @@ class Language {
}
if( $length > 0 ) {
$string = substr( $string, 0, $length );
+ $char = ord( $string[strlen( $string ) - 1] );
+ if ($char >= 0xc0) {
+ # We got the first byte only of a multibyte char; remove it.
+ $string = substr( $string, 0, -1 );
+ } elseif( $char >= 0x80 &&
+ preg_match( '/^(.*)(?:[\xe0-\xef][\x80-\xbf]|' .
+ '[\xf0-\xf7][\x80-\xbf]{1,2})$/', $string, $m ) ) {
+ # We chopped in the middle of a character; remove it
+ $string = $m[1];
+ }
return $string . $ellipsis;
} else {
$string = substr( $string, $length );
+ $char = ord( $string[0] );
+ if( $char >= 0x80 && $char < 0xc0 ) {
+ # We chopped in the middle of a character; remove the whole thing
+ $string = preg_replace( '/^[\x80-\xbf]+/', '', $string );
+ }
return $ellipsis . $string;
}
}
@@ -1048,8 +1248,8 @@ class Language {
* @param string $wordform3 (optional)
* @return string
*/
- function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
- return $count == '1' ? $wordform1 : $wordform2;
+ function convertPlural( $count, $w1, $w2, $w3) {
+ return $count == '1' ? $w1 : $w2;
}
/**
@@ -1060,7 +1260,7 @@ class Language {
*/
function translateBlockExpiry( $str ) {
- $scBlockExpiryOptions = wfMsg( 'ipboptions' );
+ $scBlockExpiryOptions = $this->getMessageFromDB( 'ipboptions' );
if ( $scBlockExpiryOptions == '-') {
return $str;
@@ -1109,6 +1309,17 @@ class Language {
return $this->mConverter->parserConvert( $text, $parser );
}
+ # Tell the converter that it shouldn't convert titles
+ function setNoTitleConvert(){
+ $this->mConverter->setNotitleConvert();
+ }
+
+ # Check if this is a language with variants
+ function hasVariants(){
+ return sizeof($this->getVariants())>1;
+ }
+
+
/**
* Perform output conversion on a string, and encode for safe HTML output.
* @param string $text
@@ -1135,8 +1346,8 @@ class Language {
}
- function getPreferredVariant() {
- return $this->mConverter->getPreferredVariant();
+ function getPreferredVariant( $fromUser = true ) {
+ return $this->mConverter->getPreferredVariant( $fromUser );
}
/**
@@ -1154,6 +1365,17 @@ class Language {
}
/**
+ * If a language supports multiple variants, converts text
+ * into an array of all possible variants of the text:
+ * 'variant' => text in that variant
+ */
+
+ function convertLinkToAllVariants($text){
+ return $this->mConverter->convertLinkToAllVariants($text);
+ }
+
+
+ /**
* returns language specific options used by User::getPageRenderHash()
* for example, the preferred language variant
*
@@ -1182,8 +1404,8 @@ class Language {
* @param string $text text to be tagged for no conversion
* @return string the tagged text
*/
- function markNoConversion( $text ) {
- return $this->mConverter->markNoConversion( $text );
+ function markNoConversion( $text, $noParse=false ) {
+ return $this->mConverter->markNoConversion( $text, $noParse );
}
/**
@@ -1194,7 +1416,8 @@ class Language {
* @public
*/
function linkTrail() {
- return $this->getMessage( 'linktrail' );
+ $this->load();
+ return $this->linkTrail;
}
function getLangObj() {
@@ -1205,22 +1428,300 @@ class Language {
* Get the RFC 3066 code for this language object
*/
function getCode() {
- return str_replace( '_', '-', strtolower( substr( get_class( $this ), 8 ) ) );
+ return $this->mCode;
}
+ function setCode( $code ) {
+ $this->mCode = $code;
+ }
-}
+ static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
+ return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
+ }
+
+ static function getMessagesFileName( $code ) {
+ global $IP;
+ return self::getFileName( "$IP/languages/messages/Messages", $code, '.php' );
+ }
+
+ static function getClassFileName( $code ) {
+ global $IP;
+ return self::getFileName( "$IP/languages/classes/Language", $code, '.php' );
+ }
+
+ static function getLocalisationArray( $code, $disableCache = false ) {
+ self::loadLocalisation( $code, $disableCache );
+ return self::$mLocalisationCache[$code];
+ }
+
+ /**
+ * Load localisation data for a given code into the static cache
+ *
+ * @return array Dependencies, map of filenames to mtimes
+ */
+ static function loadLocalisation( $code, $disableCache = false ) {
+ static $recursionGuard = array();
+ global $wgMemc;
+
+ if ( !$code ) {
+ throw new MWException( "Invalid language code requested" );
+ }
+
+ if ( !$disableCache ) {
+ # Try the per-process cache
+ if ( isset( self::$mLocalisationCache[$code] ) ) {
+ return self::$mLocalisationCache[$code]['deps'];
+ }
+
+ wfProfileIn( __METHOD__ );
+
+ # Try the serialized directory
+ $cache = wfGetPrecompiledData( self::getFileName( "Messages", $code, '.ser' ) );
+ if ( $cache ) {
+ self::$mLocalisationCache[$code] = $cache;
+ wfDebug( "Got localisation for $code from precompiled data file\n" );
+ wfProfileOut( __METHOD__ );
+ return self::$mLocalisationCache[$code]['deps'];
+ }
+
+ # Try the global cache
+ $memcKey = wfMemcKey('localisation', $code );
+ $cache = $wgMemc->get( $memcKey );
+ if ( $cache ) {
+ $expired = false;
+ # Check file modification times
+ foreach ( $cache['deps'] as $file => $mtime ) {
+ if ( !file_exists( $file ) || filemtime( $file ) > $mtime ) {
+ $expired = true;
+ break;
+ }
+ }
+ if ( self::isLocalisationOutOfDate( $cache ) ) {
+ $wgMemc->delete( $memcKey );
+ $cache = false;
+ wfDebug( "Localisation cache for $code had expired due to update of $file\n" );
+ } else {
+ self::$mLocalisationCache[$code] = $cache;
+ wfDebug( "Got localisation for $code from cache\n" );
+ wfProfileOut( __METHOD__ );
+ return $cache['deps'];
+ }
+ }
+ } else {
+ wfProfileIn( __METHOD__ );
+ }
-# FIXME: Merge all UTF-8 support code into Language base class.
-# We no longer support Latin-1 charset.
-require_once( 'LanguageUtf8.php' );
+ if ( $code != 'en' ) {
+ $fallback = 'en';
+ } else {
+ $fallback = false;
+ }
+
+ # Load the primary localisation from the source file
+ $filename = self::getMessagesFileName( $code );
+ if ( !file_exists( $filename ) ) {
+ wfDebug( "No localisation file for $code, using implicit fallback to en\n" );
+ $cache = array();
+ $deps = array();
+ } else {
+ $deps = array( $filename => filemtime( $filename ) );
+ require( $filename );
+ $cache = compact( self::$mLocalisationKeys );
+ wfDebug( "Got localisation for $code from source\n" );
+ }
+
+ if ( !empty( $fallback ) ) {
+ # Load the fallback localisation, with a circular reference guard
+ if ( isset( $recursionGuard[$code] ) ) {
+ throw new MWException( "Error: Circular fallback reference in language code $code" );
+ }
+ $recursionGuard[$code] = true;
+ $newDeps = self::loadLocalisation( $fallback, $disableCache );
+ unset( $recursionGuard[$code] );
+
+ $secondary = self::$mLocalisationCache[$fallback];
+ $deps = array_merge( $deps, $newDeps );
+
+ # Merge the fallback localisation with the current localisation
+ foreach ( self::$mLocalisationKeys as $key ) {
+ if ( isset( $cache[$key] ) ) {
+ if ( isset( $secondary[$key] ) ) {
+ if ( in_array( $key, self::$mMergeableMapKeys ) ) {
+ $cache[$key] = $cache[$key] + $secondary[$key];
+ } elseif ( in_array( $key, self::$mMergeableListKeys ) ) {
+ $cache[$key] = array_merge( $secondary[$key], $cache[$key] );
+ }
+ }
+ } else {
+ $cache[$key] = $secondary[$key];
+ }
+ }
+
+ # Merge bookstore lists if requested
+ if ( !empty( $cache['bookstoreList']['inherit'] ) ) {
+ $cache['bookstoreList'] = array_merge( $cache['bookstoreList'], $secondary['bookstoreList'] );
+ }
+ if ( isset( $cache['bookstoreList']['inherit'] ) ) {
+ unset( $cache['bookstoreList']['inherit'] );
+ }
+ }
+
+ # Add dependencies to the cache entry
+ $cache['deps'] = $deps;
+
+ # Replace spaces with underscores in namespace names
+ $cache['namespaceNames'] = str_replace( ' ', '_', $cache['namespaceNames'] );
+
+ # Save to both caches
+ self::$mLocalisationCache[$code] = $cache;
+ if ( !$disableCache ) {
+ $wgMemc->set( $memcKey, $cache );
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $deps;
+ }
+
+ /**
+ * Test if a given localisation cache is out of date with respect to the
+ * source Messages files. This is done automatically for the global cache
+ * in $wgMemc, but is only done on certain occasions for the serialized
+ * data file.
+ *
+ * @param $cache mixed Either a language code or a cache array
+ */
+ static function isLocalisationOutOfDate( $cache ) {
+ if ( !is_array( $cache ) ) {
+ self::loadLocalisation( $cache );
+ $cache = self::$mLocalisationCache[$cache];
+ }
+ $expired = false;
+ foreach ( $cache['deps'] as $file => $mtime ) {
+ if ( !file_exists( $file ) || filemtime( $file ) > $mtime ) {
+ $expired = true;
+ break;
+ }
+ }
+ return $expired;
+ }
+
+ /**
+ * Get the fallback for a given language
+ */
+ static function getFallbackFor( $code ) {
+ self::loadLocalisation( $code );
+ return self::$mLocalisationCache[$code]['fallback'];
+ }
+
+ /**
+ * Get all messages for a given language
+ */
+ static function getMessagesFor( $code ) {
+ self::loadLocalisation( $code );
+ return self::$mLocalisationCache[$code]['messages'];
+ }
-# This should fail gracefully if there's not a localization available
-wfSuppressWarnings();
-// Preload base classes to work around APC/PHP5 bug
-include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.deps.php' );
-include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.php' );
-wfRestoreWarnings();
+ /**
+ * Get a message for a given language
+ */
+ static function getMessageFor( $key, $code ) {
+ self::loadLocalisation( $code );
+ return @self::$mLocalisationCache[$code]['messages'][$key];
+ }
+
+ /**
+ * Load localisation data for this object
+ */
+ function load() {
+ if ( !$this->mLoaded ) {
+ self::loadLocalisation( $this->getCode() );
+ $cache =& self::$mLocalisationCache[$this->getCode()];
+ foreach ( self::$mLocalisationKeys as $key ) {
+ $this->$key = $cache[$key];
+ }
+ $this->mLoaded = true;
+
+ $this->fixUpSettings();
+ }
+ }
+
+ /**
+ * Do any necessary post-cache-load settings adjustment
+ */
+ function fixUpSettings() {
+ global $wgExtraNamespaces, $wgMetaNamespace, $wgMetaNamespaceTalk, $wgMessageCache,
+ $wgNamespaceAliases, $wgAmericanDates;
+ wfProfileIn( __METHOD__ );
+ if ( $wgExtraNamespaces ) {
+ $this->namespaceNames = $wgExtraNamespaces + $this->namespaceNames;
+ }
+
+ $this->namespaceNames[NS_PROJECT] = $wgMetaNamespace;
+ if ( $wgMetaNamespaceTalk ) {
+ $this->namespaceNames[NS_PROJECT_TALK] = $wgMetaNamespaceTalk;
+ } else {
+ $talk = $this->namespaceNames[NS_PROJECT_TALK];
+ $talk = str_replace( '$1', $wgMetaNamespace, $talk );
+
+ # Allow grammar transformations
+ # Allowing full message-style parsing would make simple requests
+ # such as action=raw much more expensive than they need to be.
+ # This will hopefully cover most cases.
+ $talk = preg_replace_callback( '/{{grammar:(.*?)\|(.*?)}}/i',
+ array( &$this, 'replaceGrammarInNamespace' ), $talk );
+ $talk = str_replace( ' ', '_', $talk );
+ $this->namespaceNames[NS_PROJECT_TALK] = $talk;
+ }
+
+ # The above mixing may leave namespaces out of canonical order.
+ # Re-order by namespace ID number...
+ ksort( $this->namespaceNames );
+
+ # Put namespace names and aliases into a hashtable.
+ # If this is too slow, then we should arrange it so that it is done
+ # before caching. The catch is that at pre-cache time, the above
+ # class-specific fixup hasn't been done.
+ $this->mNamespaceIds = array();
+ foreach ( $this->namespaceNames as $index => $name ) {
+ $this->mNamespaceIds[$this->lc($name)] = $index;
+ }
+ if ( $this->namespaceAliases ) {
+ foreach ( $this->namespaceAliases as $name => $index ) {
+ $this->mNamespaceIds[$this->lc($name)] = $index;
+ }
+ }
+ if ( $wgNamespaceAliases ) {
+ foreach ( $wgNamespaceAliases as $name => $index ) {
+ $this->mNamespaceIds[$this->lc($name)] = $index;
+ }
+ }
+
+ if ( $this->defaultDateFormat == 'dmy or mdy' ) {
+ $this->defaultDateFormat = $wgAmericanDates ? 'mdy' : 'dmy';
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ function replaceGrammarInNamespace( $m ) {
+ return $this->convertGrammar( trim( $m[2] ), trim( $m[1] ) );
+ }
+
+ static function getCaseMaps() {
+ static $wikiUpperChars, $wikiLowerChars;
+ if ( isset( $wikiUpperChars ) ) {
+ return array( $wikiUpperChars, $wikiLowerChars );
+ }
+ wfProfileIn( __METHOD__ );
+ $arr = wfGetPrecompiledData( 'Utf8Case.ser' );
+ if ( $arr === false ) {
+ throw new MWException(
+ "Utf8Case.ser is missing, please run \"make\" in the serialized directory\n" );
+ }
+ extract( $arr );
+ wfProfileOut( __METHOD__ );
+ return array( $wikiUpperChars, $wikiLowerChars );
+ }
}
+
?>
diff --git a/languages/LanguageConverter.php b/languages/LanguageConverter.php
index 9bb6715a..a949ad4e 100644
--- a/languages/LanguageConverter.php
+++ b/languages/LanguageConverter.php
@@ -12,7 +12,9 @@ class LanguageConverter {
var $mMainLanguageCode;
var $mVariants, $mVariantFallbacks;
var $mTablesLoaded = false;
+ var $mUseFss = false;
var $mTables;
+ var $mFssObjects;
var $mTitleDisplay='';
var $mDoTitleConvert=true, $mDoContentConvert=true;
var $mCacheKey;
@@ -20,6 +22,7 @@ class LanguageConverter {
var $mMarkup;
var $mFlags;
var $mUcfirst = false;
+ var $mNoTitleConvert = false;
/**
* Constructor
*
@@ -35,17 +38,20 @@ class LanguageConverter {
$variantfallbacks=array(),
$markup=array(),
$flags = array()) {
- global $wgDBname;
+ global $wgLegalTitleChars;
$this->mLangObj = $langobj;
$this->mMainLanguageCode = $maincode;
$this->mVariants = $variants;
$this->mVariantFallbacks = $variantfallbacks;
- $this->mCacheKey = $wgDBname . ":conversiontables";
+ $this->mCacheKey = wfMemcKey( 'conversiontables' );
$m = array('begin'=>'-{', 'flagsep'=>'|', 'codesep'=>':',
'varsep'=>';', 'end'=>'}-');
$this->mMarkup = array_merge($m, $markup);
$f = array('A'=>'A', 'T'=>'T');
$this->mFlags = array_merge($f, $flags);
+ if ( function_exists( 'fss_prep_replace' ) ) {
+ $this->mUseFss = true;
+ }
}
/**
@@ -72,11 +78,12 @@ class LanguageConverter {
/**
- * get preferred language variants.
+ * get preferred language variants.
+ * @param boolean $fromUser Get it from $wgUser's preferences
* @return string the preferred language code
* @access public
*/
- function getPreferredVariant() {
+ function getPreferredVariant( $fromUser = true ) {
global $wgUser, $wgRequest;
if($this->mPreferredVariant)
@@ -90,7 +97,9 @@ class LanguageConverter {
}
// get language variant preference from logged in users
- if(is_object($wgUser) && $wgUser->isLoggedIn() ) {
+ // Don't call this on stub objects because that causes infinite
+ // recursion during initialisation
+ if( $fromUser && $wgUser->isLoggedIn() ) {
$this->mPreferredVariant = $wgUser->getOption('variant');
return $this->mPreferredVariant;
}
@@ -147,19 +156,22 @@ class LanguageConverter {
$marker = "";
// this one is needed when the text is inside an html markup
- $htmlfix = '|<[^>]+=\"[^(>=)]*$|^[^(<>=\")]*\"[^>]*>';
+ $htmlfix = '|<[^>]+$|^[^<>]*>';
+
+ // disable convert to variants between <code></code> tags
+ $codefix = '<code>.+?<\/code>|';
- $reg = '/<[^>]+>|&[a-z#][a-z0-9]+;' . $marker . $htmlfix . '/';
+ $reg = '/'.$codefix.'<[^>]+>|&[a-zA-Z#][a-z0-9]+;' . $marker . $htmlfix . '/s';
$matches = preg_split($reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE);
-
$m = array_shift($matches);
- $ret = strtr($m[0], $this->mTables[$toVariant]);
+
+ $ret = $this->translate($m[0], $toVariant);
$mstart = $m[1]+strlen($m[0]);
foreach($matches as $m) {
$ret .= substr($text, $mstart, $m[1]-$mstart);
- $ret .= strtr($m[0], $this->mTables[$toVariant]);
+ $ret .= $this->translate($m[0], $toVariant);
$mstart = $m[1] + strlen($m[0]);
}
wfProfileOut( $fname );
@@ -167,11 +179,29 @@ class LanguageConverter {
}
/**
+ * Translate a string to a variant
+ * Doesn't process markup or do any of that other stuff, for that use convert()
+ *
+ * @param string $text Text to convert
+ * @param string $variant Variant language code
+ * @return string Translated text
+ */
+ function translate( $text, $variant ) {
+ if( !$this->mTablesLoaded )
+ $this->loadTables();
+ if ( $this->mUseFss ) {
+ return fss_exec_replace( $this->mFssObjects[$variant], $text );
+ } else {
+ return strtr( $text, $this->mTables[$variant] );
+ }
+ }
+
+ /**
* convert text to all supported variants
*
* @param string $text the text to be converted
* @return array of string
- * @private
+ * @public
*/
function autoConvertToAllVariants($text) {
$fname="LanguageConverter::autoConvertToAllVariants";
@@ -181,20 +211,54 @@ class LanguageConverter {
$ret = array();
foreach($this->mVariants as $variant) {
- $ret[$variant] = strtr($text, $this->mTables[$variant]);
+ $ret[$variant] = $this->translate($text, $variant);
}
+
wfProfileOut( $fname );
return $ret;
}
/**
+ * convert link text to all supported variants
+ *
+ * @param string $text the text to be converted
+ * @return array of string
+ * @public
+ */
+ function convertLinkToAllVariants($text) {
+ if( !$this->mTablesLoaded )
+ $this->loadTables();
+
+ $ret = array();
+ $tarray = explode($this->mMarkup['begin'], $text);
+ $tfirst = array_shift($tarray);
+
+ foreach($this->mVariants as $variant)
+ $ret[$variant] = $this->translate($tfirst,$variant);
+
+ foreach($tarray as $txt) {
+ $marked = explode($this->mMarkup['end'], $txt, 2);
+
+ foreach($this->mVariants as $variant){
+ $ret[$variant] .= $this->mMarkup['begin'].$marked[0].$this->mMarkup['end'];
+ if(array_key_exists(1, $marked))
+ $ret[$variant] .= $this->translate($marked[1],$variant);
+ }
+
+ }
+
+ return $ret;
+ }
+
+
+ /**
* Convert text using a parser object for context
*/
function parserConvert( $text, &$parser ) {
global $wgDisableLangConversion;
/* don't do anything if this is the conversion table */
if ( $parser->mTitle->getNamespace() == NS_MEDIAWIKI &&
- strpos($parser->mTitle->getText, "Conversiontable") !== false )
+ strpos($parser->mTitle->getText(), "Conversiontable") !== false )
{
return $text;
}
@@ -223,27 +287,30 @@ class LanguageConverter {
* @access public
*/
function convert( $text , $isTitle=false) {
- $mw =& MagicWord::get( MAG_NOTITLECONVERT );
+ $mw =& MagicWord::get( 'notitleconvert' );
if( $mw->matchAndRemove( $text ) )
$this->mDoTitleConvert = false;
- $mw =& MagicWord::get( MAG_NOCONTENTCONVERT );
+ $mw =& MagicWord::get( 'nocontentconvert' );
if( $mw->matchAndRemove( $text ) ) {
$this->mDoContentConvert = false;
}
// no conversion if redirecting
- $mw =& MagicWord::get( MAG_REDIRECT );
+ $mw =& MagicWord::get( 'redirect' );
if( $mw->matchStart( $text ))
return $text;
if( $isTitle ) {
+ if($this->mNoTitleConvert){
+ $this->mTitleDisplay = $text;
+ return $text;
+ }
+
if( !$this->mDoTitleConvert ) {
$this->mTitleDisplay = $text;
return $text;
}
- if( !empty($this->mTitleDisplay))
- return $this->mTitleDisplay;
global $wgRequest;
$isredir = $wgRequest->getText( 'redirect', 'yes' );
@@ -252,7 +319,7 @@ class LanguageConverter {
return $text;
}
else {
- $this->mTitleDisplay = $this->autoConvert($text);
+ $this->mTitleDisplay = $this->convert($text);
return $this->mTitleDisplay;
}
}
@@ -289,7 +356,7 @@ class LanguageConverter {
else
$rules = $marked[0];
-#FIXME: may cause trouble here...
+ //FIXME: may cause trouble here...
//strip &nbsp; since it interferes with the parsing, plus,
//all spaces should be stripped in this tag anyway.
$rules = str_replace('&nbsp;', '', $rules);
@@ -331,6 +398,9 @@ class LanguageConverter {
}
}
+ if ( $this->mUseFss ) {
+ $this->generateFssObjects();
+ }
}
}
else {
@@ -381,23 +451,16 @@ class LanguageConverter {
* @access public
*/
function findVariantLink( &$link, &$nt ) {
- static $count=0; //used to limit this operation
- static $cache=array();
global $wgDisableLangConversion;
$pref = $this->getPreferredVariant();
$ns=0;
if(is_object($nt))
$ns = $nt->getNamespace();
- if( $count > 50 && $ns != NS_CATEGORY )
- return;
- $count++;
+
$variants = $this->autoConvertToAllVariants($link);
if($variants == false) //give up
return;
foreach( $variants as $v ) {
- if(isset($cache[$v]))
- continue;
- $cache[$v] = 1;
$varnt = Title::newFromText( $v, $ns );
if( $varnt && $varnt->getArticleID() > 0 ) {
$nt = $varnt;
@@ -495,6 +558,18 @@ class LanguageConverter {
$wgMemc->set($this->mCacheKey, $this->mTables, 43200);
$this->unlockCache();
}
+ if ( $this->mUseFss ) {
+ $this->generateFssObjects();
+ }
+ }
+
+ /**
+ * Generate FSS objects. The FSS extension must be available.
+ */
+ function generateFssObjects() {
+ foreach ( $this->mTables as $variant => $table ) {
+ $this->mFssObjects[$variant] = fss_prep_replace( $table );
+ }
}
/**
@@ -601,7 +676,7 @@ class LanguageConverter {
if ($this->mUcfirst) {
foreach ($ret as $k => $v) {
- $ret[LanguageUtf8::ucfirst($k)] = LanguageUtf8::ucfirst($v);
+ $ret[Language::ucfirst($k)] = Language::ucfirst($v);
}
}
return $ret;
@@ -614,7 +689,7 @@ class LanguageConverter {
* @param string $text text to be tagged for no conversion
* @return string the tagged text
*/
- function markNoConversion($text) {
+ function markNoConversion($text, $noParse=false) {
# don't mark if already marked
if(strpos($text, $this->mMarkup['begin']) ||
strpos($text, $this->mMarkup['end']))
@@ -655,6 +730,11 @@ class LanguageConverter {
}
return true;
}
+
+ function setNoTitleConvert(){
+ $this->mNoTitleConvert = true;
+ }
+
}
?>
diff --git a/languages/Names.php b/languages/Names.php
index c5f3d6f1..7b825c57 100644
--- a/languages/Names.php
+++ b/languages/Names.php
@@ -20,6 +20,7 @@
'ay' => 'Aymar', # Aymara, should possibly be Aymará
'az' => 'Azərbaycan', # Azerbaijani
'ba' => 'Башҡорт', # Bashkir
+ 'bar' => 'Boarisch', # Bavarian (Austro-Bavarian and South Tyrolean)
'bat-smg' => 'Žemaitėška', # Samogitian
'be' => 'Беларуская', # Belarusian ''or'' Byelarussian
'bg' => 'Български', # Bulgarian
@@ -28,10 +29,14 @@
'bm' => 'Bamanankan', # Bambara
'bn' => 'বাংলা', # Bengali
'bo' => 'བོད་ཡིག', # Tibetan
+ 'bpy' => 'ইমার ঠার/বিষ্ণুপ্রিয়া মণিপুরী', # Bishnupriya Manipuri
'br' => 'Brezhoneg', # Breton
'bs' => 'Bosanski', # Bosnian
'bug' => 'ᨅᨔ ᨕᨘᨁᨗ', # Buginese
+ 'bxr' => 'Буряад', # Buryat (Russia)
'ca' => 'Català', # Catalan
+ 'cbk-zam' => 'Chavacano de Zamboanga', # Zamboanga Chavacano
+ 'cdo' => 'Mìng-dĕ̤ng-ngṳ̄', # Min Dong
'ce' => 'Нохчийн', # Chechen
'ceb' => 'Cebuano', # Cebuano
'ch' => 'Chamoru', # Chamorro
@@ -42,15 +47,18 @@
'cr' => 'Nēhiyaw / ᓀᐦᐃᔭᐤ', # Cree
'cs' => 'Česky', # Czech
'csb' => 'Kaszëbsczi', # Cassubian
+ 'cu' => 'словѣньскъ', # Old Church Slavonic (ancient language)
'cv' => 'Чăвашла', # Chuvash
'cy' => 'Cymraeg', # Welsh
'da' => 'Dansk', # Danish
'de' => 'Deutsch', # German
+ 'diq' => 'Zazaki', # Zazaki
'dk' => 'Dansk', # Unused code currently redirecting to Danish, 'da' is correct for the language
'dv' => 'ދިވެހިބަސް', # Dhivehi
'dz' => 'ཇོང་ཁ', # Bhutani
- 'ee' => 'Ɛʋɛ', # Ewe
+ 'ee' => 'Eʋegbe', # Ewe
'el' => 'Ελληνικά', # Greek
+ 'eml' => 'Emilià', # Emilian-Romagnol / Sammarinese
'en' => 'English', # English
'eo' => 'Esperanto', # Esperanto
'es' => 'Español', # Spanish
@@ -69,6 +77,7 @@
'ga' => 'Gaeilge', # Irish
'gd' => 'Gàidhlig', # Scots Gaelic
'gl' => 'Galego', # Gallegan
+ 'glk' => 'گیلکی', # Gilaki
'gn' => 'Avañe\'ẽ', # Guarani
'got' => '𐌲𐌿𐍄𐌹𐍃𐌺', # Gothic
'gsw' => 'Alemannisch', # Alemannic
@@ -80,6 +89,7 @@
'hi' => 'हिन्दी', # Hindi
'ho' => 'Hiri Motu', # Hiri Motu
'hr' => 'Hrvatski', # Croatian
+ 'hsb' => 'Hornjoserbsce', # Upper Sorbian
'ht' => 'Krèyol ayisyen', # Haitian, common/popular form is Kreyòl
'hu' => 'Magyar', # Hungarian
'hy' => 'Հայերեն', # Armenian
@@ -102,7 +112,10 @@
'kg' => 'Kongo', # Kongo, (FIXME!) should probaly be KiKongo or KiKoongo
'ki' => 'Gĩkũyũ', # Kikuyu, correctness not guaranteed
'kj' => 'Kuanyama', # Kuanyama (FIXME!)
- 'kk' => 'қазақша', # Kazakh
+ 'kk' => 'Қазақша', # Kazakh
+ 'kk-cn' => 'قازاق', # Kazakh Arabic
+ 'kk-kz' => 'Қазақ', # Kazakh Cyrillic
+ 'kk-tr' => 'Qazaq', # Kazakh Latin
'kl' => 'Kalaallisut', # Greenlandic
'km' => 'ភាសាខ្មែរ', # Cambodian
'kn' => 'ಕನ್ನಡ', # Kannada
@@ -116,6 +129,7 @@
'ky' => 'Кыргызча', # Kirghiz
'la' => 'Latina', # Latin
'lad' => 'Ladino', # Ladino
+ 'lbe' => 'Лакку', # Lak
'lb' => 'Lëtzebuergesch', # Luxemburguish
'lg' => 'Luganda', # Ganda
'li' => 'Limburgs', # Limburgian
@@ -139,6 +153,7 @@
'mt' => 'Malti', # Maltese
'mus' => 'Muscogee', # Creek, should possibly be Muskogee
'my' => 'Myanmasa', # Burmese
+ 'mzn' => 'مَزِروني', # Mazandarin
'na' => 'Ekakairũ Naoero', # Nauruan
'nah' => 'Nahuatl', # Nahuatl, en:Wikipedia writes Nahuatlahtolli, while another form is Náhuatl
'nap' => 'Nnapulitano', # Neapolitan
@@ -146,11 +161,13 @@
'nds' => 'Plattdüütsch', # Low German ''or'' Low Saxon
'nds-nl' => 'Nedersaksisch', # Dutch Low Saxon
'ne' => 'नेपाली', # Nepali
+ 'new' => 'नेपाल भाषा', # Newar / Nepal Bhasa
'ng' => 'Oshiwambo', # Ndonga
'nl' => 'Nederlands', # Dutch
'nn' => 'Norsk (nynorsk)' , # Norwegian (Nynorsk)
'no' => 'Norsk (bokmål)', # Norwegian
'non' => 'Norrǿna', # Old Norse
+ 'nov' => 'Novial', # Novial
'nrm' => 'Nouormand', # Norman
'nv' => 'Diné bizaad', # Navajo
'ny' => 'Chi-Chewa', # Chichewa
@@ -159,6 +176,7 @@
'or' => 'ଓଡ଼ିଆ', # Oriya
'os' => 'Иронау', # Ossetic
'pa' => 'ਪੰਜਾਬੀ', # Punjabi
+ 'pag' => 'Pangasinan', # Pangasinan
'pam' => 'Pampangan', # Pampanga
'pap' => 'Papiamentu', # Papiamentu
'pdc' => 'Deitsch', # Pennsylvania German
@@ -175,7 +193,9 @@
'rn' => 'Kirundi', # Kirundi
'ro' => 'Română', # Romanian
'roa-rup' => 'Armâneashti', # Aromanian
+ 'roa-tara' => 'Tarandíne', # Tarantino
'ru' => 'Русский', # Russian
+ 'ru-sib' => 'Сибирской', # Siberian/North Russian
'rw' => 'Kinyarwanda', # Kinyarwanda, should possibly be Kinyarwandi
'sa' => 'संस्कृत', # Sanskrit
'sc' => 'Sardu', # Sardinian
@@ -237,13 +257,16 @@
'wa' => 'Walon', # Walloon
'war' => 'Samar-Leyte Visayan', # Waray-Waray
'wo' => 'Wollof', # Wolof
+ 'wuu' => '吴语', # Wu
'xal' => 'Хальмг', # Kalmyk
'xh' => 'isiXhosa', # Xhosan
'yi' => 'ייִדיש', # Yiddish
'yo' => 'Yorùbá', # Yoruba
'za' => '(Cuengh)', # Zhuang
+ 'zea' => 'Zeêuws', # Zealandic
'zh' => '中文', # (Zhōng Wén) - Chinese
'zh-cfr' => '閩南語', # Min-nan alias (site is at minnan)
+ 'zh-classical' => '古文 / 文言文', # Classical Chinese/Literary Chinese
'zh-cn' => '中文(简体)', # Simplified
'zh-hk' => '中文(繁體)', # Traditional (Hong Kong)
'zh-min-nan' => 'Bân-lâm-gú', # Min-nan
diff --git a/languages/classes/LanguageAz.php b/languages/classes/LanguageAz.php
new file mode 100644
index 00000000..d5df3ecc
--- /dev/null
+++ b/languages/classes/LanguageAz.php
@@ -0,0 +1,17 @@
+<?php
+/** Azerbaijani (Azərbaycan)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageAz extends Language {
+ function ucfirst ( $string ) {
+ if ( $string[0] == 'i' ) {
+ return 'İ' . substr( $string, 1 );
+ } else {
+ return parent::ucfirst( $string );
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageBe.php b/languages/classes/LanguageBe.php
new file mode 100644
index 00000000..f2a52cca
--- /dev/null
+++ b/languages/classes/LanguageBe.php
@@ -0,0 +1,89 @@
+<?php
+/** Belarusian (Беларуская мова)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @bug 1638, 2135
+ * @link http://be.wikipedia.org/wiki/Talk:LanguageBe.php
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
+ */
+
+class LanguageBe extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: родны, вінавальны, месны
+ */
+ function convertGrammar( $word, $case ) {
+ switch ( $case ) {
+ case 'родны': # genitive
+ if ( $word == 'Вікіпэдыя' ) {
+ $word = 'Вікіпэдыі';
+ } elseif ( $word == 'ВікіСлоўнік' ) {
+ $word = 'ВікіСлоўніка';
+ } elseif ( $word == 'ВікіКнігі' ) {
+ $word = 'ВікіКніг';
+ } elseif ( $word == 'ВікіКрыніца' ) {
+ $word = 'ВікіКрыніцы';
+ } elseif ( $word == 'ВікіНавіны' ) {
+ $word = 'ВікіНавін';
+ } elseif ( $word == 'ВікіВіды' ) {
+ $word = 'ВікіВідаў';
+ }
+ break;
+ case 'вінавальны': # akusative
+ if ( $word == 'Вікіпэдыя' ) {
+ $word = 'Вікіпэдыю';
+ } elseif ( $word == 'ВікіСлоўнік' ) {
+ $word = 'ВікіСлоўнік';
+ } elseif ( $word == 'ВікіКнігі' ) {
+ $word = 'ВікіКнігі';
+ } elseif ( $word == 'ВікіКрыніца' ) {
+ $word = 'ВікіКрыніцу';
+ } elseif ( $word == 'ВікіНавіны' ) {
+ $word = 'ВікіНавіны';
+ } elseif ( $word == 'ВікіВіды' ) {
+ $word = 'ВікіВіды';
+ }
+ break;
+ case 'месны': # prepositional
+ if ( $word == 'Вікіпэдыя' ) {
+ $word = 'Вікіпэдыі';
+ } elseif ( $word == 'ВікіСлоўнік' ) {
+ $word = 'ВікіСлоўніку';
+ } elseif ( $word == 'ВікіКнігі' ) {
+ $word = 'ВікіКнігах';
+ } elseif ( $word == 'ВікіКрыніца' ) {
+ $word = 'ВікіКрыніцы';
+ } elseif ( $word == 'ВікіНавіны' ) {
+ $word = 'ВікіНавінах';
+ } elseif ( $word == 'ВікіВіды' ) {
+ $word = 'ВікіВідах';
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'назоўны' (nominative) and all undefined case values
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageBg.php b/languages/classes/LanguageBg.php
new file mode 100644
index 00000000..4884c2a8
--- /dev/null
+++ b/languages/classes/LanguageBg.php
@@ -0,0 +1,25 @@
+<?php
+/** Bulgarian (Български)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageBg extends Language {
+ /**
+ * ISO number formatting: 123 456 789,99.
+ * Avoid tripple grouping by numbers with whole part up to 4 digits.
+ */
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageBs.php b/languages/classes/LanguageBs.php
new file mode 100644
index 00000000..4734fdc1
--- /dev/null
+++ b/languages/classes/LanguageBs.php
@@ -0,0 +1,137 @@
+<?php
+/** Bosnian (bosanski)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageBs extends Language {
+
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: genitiv, dativ, akuzativ, vokativ, instrumental, lokativ
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['bs'][$case][$word]) ) {
+ return $wgGrammarForms['bs'][$case][$word];
+ }
+ switch ( $case ) {
+ case 'genitiv': # genitive
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipedije';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjiga';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijesti';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitata';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikiizvora';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječnika';
+ }
+ break;
+ case 'dativ': # dative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjigama';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitatima';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijestima';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikiizvoru';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječniku';
+ }
+ break;
+ case 'akuzativ': # akusative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipediju';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjige';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitate';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijesti';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikiizvora';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječnika';
+ }
+ break;
+ case 'vokativ': # vocative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipedijo';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjige';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitati';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijesti';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikizivoru';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječniče';
+ }
+ break;
+ case 'instrumental': # instrumental
+ if ( $word == 'Wikipedia' ) {
+ $word = 's Wikipediom';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 's Wikiknjigama';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 's Wikicitatima';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 's Wikivijestima';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 's Wikiizvorom';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 's Vikirječnikom';
+ } else {
+ $word = 's ' . $word;
+ }
+ break;
+ case 'lokativ': # locative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'o Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'o Wikiknjigama';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'o Wikicitatima';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'o Wikivijestima';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'o Wikiizvoru';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'o Vikirječniku';
+ } else {
+ $word = 'o ' . $word;
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'nominativ' (nominative) and all undefined case values
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageCs.php b/languages/classes/LanguageCs.php
new file mode 100644
index 00000000..6b8d3d61
--- /dev/null
+++ b/languages/classes/LanguageCs.php
@@ -0,0 +1,87 @@
+<?php
+/** Czech (česky)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageCs extends Language {
+ # Grammatical transformations, needed for inflected languages
+ # Invoked by putting {{grammar:case|word}} in a message
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['cs'][$case][$word]) ) {
+ return $wgGrammarForms['cs'][$case][$word];
+ }
+ # allowed values for $case:
+ # 1sg, 2sg, ..., 7sg -- nominative, genitive, ... (in singular)
+ switch ( $word ) {
+ case 'Wikipedia':
+ case 'Wikipedie':
+ switch ( $case ) {
+ case '3sg':
+ case '4sg':
+ case '6sg':
+ return 'Wikipedii';
+ case '7sg':
+ return 'Wikipedií';
+ default:
+ return 'Wikipedie';
+ }
+
+ case 'Wiktionary':
+ case 'Wikcionář':
+ switch ( $case ) {
+ case '2sg':
+ return 'Wikcionáře';
+ case '3sg':
+ case '5sg';
+ case '6sg';
+ return 'Wikcionáři';
+ case '7sg':
+ return 'Wikcionářem';
+ default:
+ return 'Wikcionář';
+ }
+
+ case 'Wikiquote':
+ case 'Wikicitáty':
+ switch ( $case ) {
+ case '2sg':
+ return 'Wikicitátů';
+ case '3sg':
+ return 'Wikicitátům';
+ case '6sg';
+ return 'Wikicitátech';
+ default:
+ return 'Wikicitáty';
+ }
+ }
+ # unknown
+ return $word;
+ }
+
+ # Plural form transformations, needed for some languages.
+ # Invoked by {{plural:count|wordform1|wordform2|wordform3}}
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace( '\xc2\xa0', '', $count );
+ switch ( $count ) {
+ case 1:
+ return $wordform1;
+
+ case 2:
+ case 3:
+ case 4:
+ return $wordform2;
+
+ default:
+ return $wordform3;
+ };
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageEo.php b/languages/classes/LanguageEo.php
new file mode 100644
index 00000000..a62ccc9b
--- /dev/null
+++ b/languages/classes/LanguageEo.php
@@ -0,0 +1,74 @@
+<?php
+/** Esperanto (Esperanto)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageEo extends Language {
+ function iconv( $in, $out, $string ) {
+ # For most languages, this is a wrapper for iconv
+ # Por multaj lingvoj, ĉi tiu nur voku la sisteman funkcion iconv()
+ # Ni ankaŭ konvertu X-sistemajn surogotajn
+ if( strcasecmp( $in, 'x' ) == 0 and strcasecmp( $out, 'utf-8' ) == 0) {
+ $xu = array (
+ 'xx' => 'x' , 'xX' => 'x' ,
+ 'Xx' => 'X' , 'XX' => 'X' ,
+ "Cx" => "\xc4\x88" , "CX" => "\xc4\x88" ,
+ "cx" => "\xc4\x89" , "cX" => "\xc4\x89" ,
+ "Gx" => "\xc4\x9c" , "GX" => "\xc4\x9c" ,
+ "gx" => "\xc4\x9d" , "gX" => "\xc4\x9d" ,
+ "Hx" => "\xc4\xa4" , "HX" => "\xc4\xa4" ,
+ "hx" => "\xc4\xa5" , "hX" => "\xc4\xa5" ,
+ "Jx" => "\xc4\xb4" , "JX" => "\xc4\xb4" ,
+ "jx" => "\xc4\xb5" , "jX" => "\xc4\xb5" ,
+ "Sx" => "\xc5\x9c" , "SX" => "\xc5\x9c" ,
+ "sx" => "\xc5\x9d" , "sX" => "\xc5\x9d" ,
+ "Ux" => "\xc5\xac" , "UX" => "\xc5\xac" ,
+ "ux" => "\xc5\xad" , "uX" => "\xc5\xad"
+ ) ;
+ return preg_replace ( '/([cghjsu]x?)((?:xx)*)(?!x)/ei',
+ 'strtr( "$1", $xu ) . strtr( "$2", $xu )', $string );
+ } else if( strcasecmp( $in, 'UTF-8' ) == 0 and strcasecmp( $out, 'x' ) == 0 ) {
+ $ux = array (
+ 'x' => 'xx' , 'X' => 'Xx' ,
+ "\xc4\x88" => "Cx" , "\xc4\x89" => "cx" ,
+ "\xc4\x9c" => "Gx" , "\xc4\x9d" => "gx" ,
+ "\xc4\xa4" => "Hx" , "\xc4\xa5" => "hx" ,
+ "\xc4\xb4" => "Jx" , "\xc4\xb5" => "jx" ,
+ "\xc5\x9c" => "Sx" , "\xc5\x9d" => "sx" ,
+ "\xc5\xac" => "Ux" , "\xc5\xad" => "ux"
+ ) ;
+ # Double Xs only if they follow cxapelutaj literoj.
+ return preg_replace( '/((?:[cghjsu]|\xc4[\x88\x89\x9c\x9d\xa4\xa5\xb4\xb5]'.
+ '|\xc5[\x9c\x9d\xac\xad])x*)/ei', 'strtr( "$1", $ux )', $string );
+ }
+ return iconv( $in, $out, $string );
+ }
+
+ function checkTitleEncoding( $s ) {
+ # Check for X-system backwards-compatibility URLs
+ $ishigh = preg_match( '/[\x80-\xff]/', $s);
+ $isutf = preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
+
+ if($ishigh and !$isutf) {
+ # Assume Latin1
+ $s = utf8_encode( $s );
+ } else {
+ if( preg_match( '/(\xc4[\x88\x89\x9c\x9d\xa4\xa5\xb4\xb5]'.
+ '|\xc5[\x9c\x9d\xac\xad])/', $s ) )
+ return $s;
+ }
+
+ //if( preg_match( '/[cghjsu]x/i', $s ) )
+ // return $this->iconv( 'x', 'utf-8', $s );
+ return $s;
+ }
+
+ function initEncoding() {
+ global $wgEditEncoding;
+ $wgEditEncoding = 'x';
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageEt.php b/languages/classes/LanguageEt.php
new file mode 100644
index 00000000..92843406
--- /dev/null
+++ b/languages/classes/LanguageEt.php
@@ -0,0 +1,21 @@
+<?php
+/** Estonian (Eesti)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguageEt extends Language {
+ /**
+ * Avoid grouping whole numbers between 0 to 9999
+ */
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageFi.php b/languages/classes/LanguageFi.php
new file mode 100644
index 00000000..47dd0e65
--- /dev/null
+++ b/languages/classes/LanguageFi.php
@@ -0,0 +1,165 @@
+<?php
+/** Finnish (Suomi)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Niklas Laxström
+ */
+class LanguageFi extends Language {
+ /**
+ * Avoid grouping whole numbers between 0 to 9999
+ */
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['fi'][$case][$word]) ) {
+ return $wgGrammarForms['fi'][$case][$word];
+ }
+
+ # These rules are not perfect, but they are currently only used for site names so it doesn't
+ # matter if they are wrong sometimes. Just add a special case for your site name if necessary.
+ switch ( $case ) {
+ case 'genitive':
+ if ( $word == 'Wikisitaatit' ) {
+ $word = 'Wikisitaattien';
+ } else {
+ $word .= 'n';
+ }
+ break;
+ case 'elative':
+ if ( $word == 'Wikisitaatit' ) {
+ $word = 'Wikisitaateista';
+ } else {
+ if ( mb_substr($word, -1) == 'y' ) {
+ $word .= 'stä';
+ } else {
+ $word .= 'sta';
+ }
+ }
+ break;
+ case 'partitive':
+ if ( $word == 'Wikisitaatit' ) {
+ $word = 'Wikisitaatteja';
+ } else {
+ if ( mb_substr($word, -1) == 'y' ) {
+ $word .= 'ä';
+ } else {
+ $word .= 'a';
+ }
+ }
+ break;
+ case 'illative':
+ # Double the last letter and add 'n'
+ # mb_substr has a compatibility function in GlobalFunctions.php
+ if ( $word == 'Wikisitaatit' ) {
+ $word = 'Wikisitaatteihin';
+ } else {
+ $word = $word . mb_substr($word,-1) . 'n';
+ }
+ break;
+ case 'inessive':
+ if ( $word == 'Wikisitaatit' ) {
+ $word = 'Wikisitaateissa';
+ } else {
+ if ( mb_substr($word, -1) == 'y' ) {
+ $word .= 'ssä';
+ } else {
+ $word .= 'ssa';
+ }
+ }
+ break;
+
+ }
+ return $word;
+ }
+
+ function translateBlockExpiry( $str ) {
+ /*
+ 'ago', 'now', 'today', 'this', 'next',
+ 'first', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth',
+ 'tomorrow', 'yesterday'
+
+ $months = 'january:tammikuu,february:helmikuu,march:maaliskuu,april:huhtikuu,may:toukokuu,june:kesäkuu,' .
+ 'july:heinäkuu,august:elokuu,september:syyskuu,october:lokakuu,november:marraskuu,december:joulukuu,' .
+ 'jan:tammikuu,feb:helmikuu,mar:maaliskuu,apr:huhtikuu,jun:kesäkuu,jul:heinäkuu,aug:elokuu,sep:syyskuu,'.
+ 'oct:lokakuu,nov:marraskuu,dec:joulukuu,sept:syyskuu';
+ */
+ $weekds = array(
+ 'monday' => 'maanantai',
+ 'tuesday' => 'tiistai',
+ 'wednesday' => 'keskiviikko',
+ 'thursay' => 'torstai',
+ 'friday' => 'perjantai',
+ 'saturday' => 'lauantai',
+ 'sunday' => 'sunnuntai',
+ 'mon' => 'ma',
+ 'tue' => 'ti',
+ 'tues' => 'ti',
+ 'wed' => 'ke',
+ 'wednes' => 'ke',
+ 'thu' => 'to',
+ 'thur' => 'to',
+ 'thurs' => 'to',
+ 'fri' => 'pe',
+ 'sat' => 'la',
+ 'sun' => 'su',
+ 'next' => 'seuraava',
+ 'tomorrow' => 'huomenna',
+ 'ago' => 'sitten',
+ 'seconds' => 'sekuntia',
+ 'second' => 'sekunti',
+ 'secs' => 's',
+ 'sec' => 's',
+ 'minutes' => 'minuuttia',
+ 'minute' => 'minuutti',
+ 'mins' => 'min',
+ 'min' => 'min',
+ 'days' => 'päivää',
+ 'day' => 'päivä',
+ 'hours' => 'tuntia',
+ 'hour' => 'tunti',
+ 'weeks' => 'viikkoa',
+ 'week' => 'viikko',
+ 'fortnights' => 'tuplaviikkoa',
+ 'fortnight' => 'tuplaviikko',
+ 'months' => 'kuukautta',
+ 'month' => 'kuukausi',
+ 'years' => 'vuotta',
+ 'year' => 'vuosi',
+ 'infinite' => 'ikuisesti',
+ 'indefinite' => 'ikuisesti'
+ );
+
+ $final = '';
+ $tokens = explode ( ' ', $str);
+ foreach( $tokens as $item ) {
+ if ( !is_numeric($item) ) {
+ if ( count ( explode( '-', $item ) ) == 3 && strlen($item) == 10 ) {
+ list( $yyyy, $mm, $dd ) = explode( '-', $item );
+ $final .= ' ' . $this->date( "{$yyyy}{$mm}{$dd}00000000");
+ continue;
+ }
+ if( isset( $weekds[$item] ) ) {
+ $final .= ' ' . $weekds[$item];
+ continue;
+ }
+ }
+
+ $final .= ' ' . $item;
+ }
+ return '<span class="blockexpiry" title="' . htmlspecialchars($str). '">”' . trim( $final ) . '”</span>';
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageFr.php b/languages/classes/LanguageFr.php
new file mode 100644
index 00000000..61cd91c6
--- /dev/null
+++ b/languages/classes/LanguageFr.php
@@ -0,0 +1,17 @@
+<?php
+/** French (Français)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguageFr extends Language {
+ /**
+ * Use singular form for zero (see bug 7309)
+ */
+ function convertPlural( $count, $w1, $w2, $w3) {
+ return $count <= '1' ? $w1 : $w2;
+ }
+}
+?>
diff --git a/languages/classes/LanguageGa.php b/languages/classes/LanguageGa.php
new file mode 100644
index 00000000..0779e42b
--- /dev/null
+++ b/languages/classes/LanguageGa.php
@@ -0,0 +1,52 @@
+<?php
+/** Irish (Gaeilge)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageGa extends Language {
+ # Convert day names
+ # Invoked with {{GRAMMAR:transformation|word}}
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['ga'][$case][$word]) ) {
+ return $wgGrammarForms['ga'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitive':
+ switch ($word) {
+ case 'Vicipéid': $word = 'Vicipéide'; break;
+ case 'Vicífhoclóir': $word = 'Vicífhoclóra'; break;
+ case 'Vicíleabhair': $word = 'Vicíleabhar'; break;
+ case 'Vicíshliocht': $word = 'Vicíshleachta'; break;
+ case 'Vicífhoinse': $word = 'Vicífhoinse'; break;
+ case 'Vicíghnéithe': $word = 'Vicíghnéithe'; break;
+ case 'Vicínuacht': $word = 'Vicínuachta'; break;
+ }
+
+ case 'ainmlae':
+ switch ($word) {
+ case 'an Domhnach':
+ $word = 'Dé Domhnaigh'; break;
+ case 'an Luan':
+ $word = 'Dé Luain'; break;
+ case 'an Mháirt':
+ $word = 'Dé Mháirt'; break;
+ case 'an Chéadaoin':
+ $word = 'Dé Chéadaoin'; break;
+ case 'an Déardaoin':
+ $word = 'Déardaoin'; break;
+ case 'an Aoine':
+ $word = 'Dé hAoine'; break;
+ case 'an Satharn':
+ $word = 'Dé Sathairn'; break;
+ }
+ }
+ return $word;
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageGsw.php b/languages/classes/LanguageGsw.php
new file mode 100644
index 00000000..ce4e0578
--- /dev/null
+++ b/languages/classes/LanguageGsw.php
@@ -0,0 +1,69 @@
+<?php
+/** Alemannic (Alemannisch)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageGsw extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with result
+
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['gsw'][$case][$word]) ) {
+ return $wgGrammarForms['gsw'][$case][$word];
+ }
+ switch ( $case ) {
+ case 'dativ':
+ if ( $word == 'Wikipedia' ) {
+ $word = 'vo de Wikipedia';
+ } elseif ( $word == 'Wikinorchrichte' ) {
+ $word = 'vo de Wikinochrichte';
+ } elseif ( $word == 'Wiktionaire' ) {
+ $word = 'vom Wiktionaire';
+ } elseif ( $word == 'Wikibuecher' ) {
+ $word = 'vo de Wikibuecher';
+ } elseif ( $word == 'Wikisprüch' ) {
+ $word = 'vo de Wikisprüch';
+ } elseif ( $word == 'Wikiquälle' ) {
+ $word = 'vo de Wikiquälle';
+ }
+ break;
+ case 'akkusativ':
+ if ( $word == 'Wikipedia' ) {
+ $word = 'd Wikipedia';
+ } elseif ( $word == 'Wikinorchrichte' ) {
+ $word = 'd Wikinochrichte';
+ } elseif ( $word == 'Wiktionaire' ) {
+ $word = 's Wiktionaire';
+ } elseif ( $word == 'Wikibuecher' ) {
+ $word = 'd Wikibuecher';
+ } elseif ( $word == 'Wikisprüch' ) {
+ $word = 'd Wikisprüch';
+ } elseif ( $word == 'Wikiquälle' ) {
+ $word = 'd Wikiquälle';
+ }
+ break;
+ case 'nominativ':
+ if ( $word == 'Wikipedia' ) {
+ $word = 'd Wikipedia';
+ } elseif ( $word == 'Wikinorchrichte' ) {
+ $word = 'd Wikinochrichte';
+ } elseif ( $word == 'Wiktionaire' ) {
+ $word = 's Wiktionaire';
+ } elseif ( $word == 'Wikibuecher' ) {
+ $word = 'd Wikibuecher';
+ } elseif ( $word == 'Wikisprüch' ) {
+ $word = 'd Wikisprüch';
+ } elseif ( $word == 'Wikiquälle' ) {
+ $word = 'd Wikiquälle';
+ }
+ break;
+ }
+ return $word;
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageHe.php b/languages/classes/LanguageHe.php
new file mode 100644
index 00000000..70de3115
--- /dev/null
+++ b/languages/classes/LanguageHe.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Hebrew (עברית)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Rotem Liss
+ */
+
+class LanguageHe extends Language {
+ /**
+ * Convert grammar forms of words.
+ *
+ * Available cases:
+ * "prefixed" (or "תחילית") - when the word has a prefix
+ *
+ * @param string the word to convert
+ * @param string the case
+ */
+ public function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['he'][$case][$word]) ) {
+ return $wgGrammarForms['he'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'prefixed':
+ case 'תחילית':
+ # Duplicate the "Waw" if prefixed
+ if ( substr( $word, 0, 2 ) == "ו" && substr( $word, 0, 4 ) != "וו" ) {
+ $word = "ו".$word;
+ }
+
+ # Remove the "He" if prefixed
+ if ( substr( $word, 0, 2 ) == "ה" ) {
+ $word = substr( $word, 2 );
+ }
+
+ # Add a hyphen if non-Hebrew letters
+ if ( substr( $word, 0, 2 ) < "א" || substr( $word, 0, 2 ) > "ת" ) {
+ $word = "־".$word;
+ }
+ }
+
+ return $word;
+ }
+
+ /**
+ * Gets a number and uses the suited form of the word.
+ *
+ * @param integer the number of items
+ * @param string the first form (singular)
+ * @param string the second form (plural)
+ * @param string the third form (2 items, plural is used if not applicable and not specified)
+ *
+ * @return string of the suited form of word
+ */
+ public function convertPlural( $count, $w1, $w2, $w3) {
+ if ( $count == '1' ) {
+ return $w1;
+ } elseif ( $count == '2' && $w3 ) {
+ return $w3;
+ } else {
+ return $w2;
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageHr.php b/languages/classes/LanguageHr.php
new file mode 100644
index 00000000..b1f6b0fc
--- /dev/null
+++ b/languages/classes/LanguageHr.php
@@ -0,0 +1,26 @@
+<?php
+/** Croatian (hrvatski)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageHr extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageHu.php b/languages/classes/LanguageHu.php
new file mode 100644
index 00000000..ac6555dc
--- /dev/null
+++ b/languages/classes/LanguageHu.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+#
+# Hungarian localisation for MediaWiki
+#
+
+class LanguageHu extends Language {
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms[$this->getCode()][$case][$word]) ) {
+ return $wgGrammarForms[$this->getCode()][$case][$word];
+ }
+
+ static $localForms = array(
+ 'rol' => array(
+ 'Wikipédia' => 'Wikipédiáról',
+ 'Wikidézet' => 'Wikidézetről',
+ 'Wikiszótár' => 'Wikiszótárról',
+ 'Wikikönyvek' => 'Wikikönyvekről',
+ ),
+ 'ba' => array(
+ 'Wikipédia' => 'Wikipédiába',
+ 'Wikidézet' => 'Wikidézetbe',
+ 'Wikiszótár' => 'Wikiszótárba',
+ 'Wikikönyvek' => 'Wikikönyvekbe',
+ ),
+ 'k' => array(
+ 'Wikipédia' => 'Wikipédiák',
+ 'Wikidézet' => 'Wikidézetek',
+ 'Wikiszótár' => 'Wikiszótárak',
+ 'Wikikönyvek' => 'Wikikönyvek',
+ )
+ );
+
+ if ( isset( $localForms[$case][$word] ) ) {
+ return $localForms[$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'rol':
+ return $word . 'ról';
+ case 'ba':
+ return $word . 'ba';
+ case 'k':
+ return $word . 'k';
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageJa.php b/languages/classes/LanguageJa.php
new file mode 100644
index 00000000..800650b0
--- /dev/null
+++ b/languages/classes/LanguageJa.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Japanese (日本語)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageJa extends Language {
+ function stripForSearch( $string ) {
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+ $s = $string;
+
+ # Strip known punctuation ?
+ #$s = preg_replace( '/\xe3\x80[\x80-\xbf]/', '', $s ); # U3000-303f
+
+ # Space strings of like hiragana/katakana/kanji
+ $hiragana = '(?:\xe3(?:\x81[\x80-\xbf]|\x82[\x80-\x9f]))'; # U3040-309f
+ $katakana = '(?:\xe3(?:\x82[\xa0-\xbf]|\x83[\x80-\xbf]))'; # U30a0-30ff
+ $kanji = '(?:\xe3[\x88-\xbf][\x80-\xbf]'
+ . '|[\xe4-\xe8][\x80-\xbf]{2}'
+ . '|\xe9[\x80-\xa5][\x80-\xbf]'
+ . '|\xe9\xa6[\x80-\x99])';
+ # U3200-9999 = \xe3\x88\x80-\xe9\xa6\x99
+ $s = preg_replace( "/({$hiragana}+|{$katakana}+|{$kanji}+)/", ' $1 ', $s );
+
+ # Double-width roman characters: ff00-ff5f ~= 0020-007f
+ $s = preg_replace( '/\xef\xbc([\x80-\xbf])/e', 'chr((ord("$1") & 0x3f) + 0x20)', $s );
+ $s = preg_replace( '/\xef\xbd([\x80-\x99])/e', 'chr((ord("$1") & 0x3f) + 0x60)', $s );
+
+ # Do general case folding and UTF-8 armoring
+ return parent::stripForSearch( $s );
+ }
+
+ # Italic is not appropriate for Japanese script
+ # Unfortunately most browsers do not recognise this, and render <em> as italic
+ function emphasize( $text ) {
+ return $text;
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageKo.php b/languages/classes/LanguageKo.php
new file mode 100644
index 00000000..55d28117
--- /dev/null
+++ b/languages/classes/LanguageKo.php
@@ -0,0 +1,57 @@
+<?php
+/** Korean (한국어)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageKo extends Language {
+ function firstChar( $s ) {
+ preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})/', $s, $matches);
+
+ if ( isset( $matches[1] ) ) {
+ if ( strlen( $matches[1] ) != 3 ) {
+ return $matches[1];
+ }
+ $code = (ord($matches[1]{0}) & 0x0f) << 12;
+ $code |= (ord($matches[1]{1}) & 0x3f) << 6;
+ $code |= (ord($matches[1]{2}) & 0x3f);
+ if ( $code < 0xac00 || 0xd7a4 <= $code) {
+ return $matches[1];
+ } elseif ( $code < 0xb098 ) {
+ return "\xe3\x84\xb1";
+ } elseif ( $code < 0xb2e4 ) {
+ return "\xe3\x84\xb4";
+ } elseif ( $code < 0xb77c ) {
+ return "\xe3\x84\xb7";
+ } elseif ( $code < 0xb9c8 ) {
+ return "\xe3\x84\xb9";
+ } elseif ( $code < 0xbc14 ) {
+ return "\xe3\x85\x81";
+ } elseif ( $code < 0xc0ac ) {
+ return "\xe3\x85\x82";
+ } elseif ( $code < 0xc544 ) {
+ return "\xe3\x85\x85";
+ } elseif ( $code < 0xc790 ) {
+ return "\xe3\x85\x87";
+ } elseif ( $code < 0xcc28 ) {
+ return "\xe3\x85\x88";
+ } elseif ( $code < 0xce74 ) {
+ return "\xe3\x85\x8a";
+ } elseif ( $code < 0xd0c0 ) {
+ return "\xe3\x85\x8b";
+ } elseif ( $code < 0xd30c ) {
+ return "\xe3\x85\x8c";
+ } elseif ( $code < 0xd558 ) {
+ return "\xe3\x85\x8d";
+ } else {
+ return "\xe3\x85\x8e";
+ }
+ } else {
+ return "";
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageKsh.php b/languages/classes/LanguageKsh.php
new file mode 100644
index 00000000..412a00f4
--- /dev/null
+++ b/languages/classes/LanguageKsh.php
@@ -0,0 +1,35 @@
+<?php
+/** Ripuarian (Ripoarėsh)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Purodha Blissenbach
+ */
+
+class LanguageKsh extends Language {
+ /**
+ * Avoid grouping whole numbers between 0 to 9999
+ */
+ public function commafy( $_ ) {
+ if ( !preg_match( '/^\d{1,4}$/', $_ ) ) {
+ return strrev( (string)preg_replace( '/(\d{3})(?=\d)(?!\d*\.)/', '$1&nbsp;', strrev( $_ ) ) );
+ } else {
+ return $_;
+ }
+ }
+ /**
+ * Handle cases of (1, other, 0) or (1, other)
+ */
+ public function convertPlural( $count, $w1, $w2, $w3 ) {
+ $count = str_replace (' ', '', $count);
+ if ( $count == '1' ) {
+ return $w1;
+ } elseif ( $count == '0' && $w3 ) {
+ return $w3;
+ } else {
+ return $w2;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageLa.php b/languages/classes/LanguageLa.php
new file mode 100644
index 00000000..b9f69925
--- /dev/null
+++ b/languages/classes/LanguageLa.php
@@ -0,0 +1,37 @@
+<?php
+/** Latin (lingua Latina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageLa extends Language {
+ /**
+ * Convert from the nominative form of a noun to some other case
+ *
+ * Just used in a couple places for sitenames; special-case as necessary.
+ * Rules are far from complete.
+ *
+ * Cases: genitive
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['la'][$case][$word]) ) {
+ return $wgGrammarForms['la'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitive':
+ // 1st and 2nd declension singular only.
+ $in = array( '/a$/', '/u[ms]$/', '/tio$/' );
+ $out = array( 'ae', 'i', 'tionis' );
+ return preg_replace( $in, $out, $word );
+ default:
+ return $word;
+ }
+ }
+
+}
+
+
+?>
diff --git a/languages/classes/LanguageLt.php b/languages/classes/LanguageLt.php
new file mode 100644
index 00000000..53729006
--- /dev/null
+++ b/languages/classes/LanguageLt.php
@@ -0,0 +1,22 @@
+<?php
+/** Lithuanian (Lietuvių)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguageLt extends Language {
+ /* Word forms (with examples):
+ 1 - vienas (1) lapas
+ 2 - trys (3) lapai
+ 3 - penkiolika (15) lapų
+ */
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace (' ', '', $count);
+ if ($count%10==1 && $count%100!=11) return $wordform1;
+ if ($count%10>=2 && ($count%100<10 || $count%100>=20)) return $wordform2;
+ return $wordform3;
+ }
+}
+?>
diff --git a/languages/classes/LanguageLv.php b/languages/classes/LanguageLv.php
new file mode 100644
index 00000000..54cae487
--- /dev/null
+++ b/languages/classes/LanguageLv.php
@@ -0,0 +1,57 @@
+<?php
+/** Latvian (Latviešu)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Niklas Laxström
+ *
+ * @copyright Copyright © 2006, Niklas Laxström
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+class LanguageLv extends Language {
+ /**
+ * Plural form transformations. Using the first form for words with the last digit 1, but not for words with the last digits 11, and the second form for all the others.
+ *
+ * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
+ *
+ * @param integer $count
+ * @param string $wordform1
+ * @param string $wordform2
+ * @param string $wordform3 (not used)
+ * @return string
+ */
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3 ) {
+ return ( ( $count % 10 == 1 ) && ( $count % 100 != 11 ) ) ? $wordform1 : $wordform2;
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ # ģenitīvs - kā, datīvs - kam, akuzatīvs - ko, lokatīvs - kur.
+ /**
+ * Cases: ģenitīvs, datīvs, akuzatīvs, lokatīvs
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+
+ $wgGrammarForms['lv']['ģenitīvs' ]['Vikipēdija'] = 'Vikipēdijas';
+ $wgGrammarForms['lv']['ģenitīvs' ]['Vikivārdnīca'] = 'Vikivārdnīcas';
+ $wgGrammarForms['lv']['datīvs' ]['Vikipēdija'] = 'Vikipēdijai';
+ $wgGrammarForms['lv']['datīvs' ]['Vikivārdnīca'] = 'Vikivārdnīcai';
+ $wgGrammarForms['lv']['akuzatīvs']['Vikipēdija'] = 'Vikipēdiju';
+ $wgGrammarForms['lv']['akuzatīvs']['Vikivārdnīca'] = 'Vikivārdnīcu';
+ $wgGrammarForms['lv']['lokatīvs' ]['Vikipēdija'] = 'Vikipēdijā';
+ $wgGrammarForms['lv']['lokatīvs' ]['Vikivārdnīca'] = 'Vikivārdnīcā';
+
+ if ( isset($wgGrammarForms['lv'][$case][$word]) ) {
+ return $wgGrammarForms['lv'][$case][$word];
+ }
+
+ return $word;
+
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguagePt_br.php b/languages/classes/LanguagePt_br.php
new file mode 100644
index 00000000..6132aaa2
--- /dev/null
+++ b/languages/classes/LanguagePt_br.php
@@ -0,0 +1,17 @@
+<?php
+/** Brazilian Portugese (Portuguêsi do Brasil)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguagePt_br extends Language {
+ /**
+ * Use singular form for zero (see bug 7309)
+ */
+ function convertPlural( $count, $w1, $w2, $w3) {
+ return $count <= '1' ? $w1 : $w2;
+ }
+}
+?>
diff --git a/languages/classes/LanguageRmy.php b/languages/classes/LanguageRmy.php
new file mode 100644
index 00000000..bbf22d52
--- /dev/null
+++ b/languages/classes/LanguageRmy.php
@@ -0,0 +1,72 @@
+<?php
+
+class LanguageRmy extends Language {
+ /**
+ * Convert from the nominative form of a noun to some other case
+ * Invoked with {{GRAMMAR:case|word}}
+ *
+ * Cases: nominative, genitive-m-sg, genitive-f-sg, dative, locative, ablative, instrumental
+ */
+ public function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['rmy'][$case][$word]) ) {
+ return $wgGrammarForms['rmy'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitive-m-sg': # genitive (m.sg.)
+ if ( $word == 'Vikipidiya' ) {
+ $word = 'Vikipidiyako';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonaresko';
+ }
+ break;
+ case 'genitive-f-sg': # genitive (f.sg.)
+ if ( $word == 'Vikipidiya' ) {
+ $word = 'Vikipidiyaki';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareski';
+ }
+ break;
+ case 'genitive-pl': # genitive (pl.)
+ if ( $word == 'Vikipidiya' ) {
+ $word = 'Vikipidiyake';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareske';
+ }
+ break;
+ case 'dativ':
+ if ( $word == 'Vikipidiyake' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareske';
+ }
+ break;
+ case 'locative':
+ if ( $word == 'Vikipidiyate' ) {
+ $word = 'Wikipedijo';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareste';
+ }
+ break;
+ case 'ablative':
+ if ( $word == 'Vikipidiyatar' ) {
+ $word = 'o Wikipediji';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonarestar';
+ }
+ break;
+ case 'instrumental':
+ if ( $word == 'Vikipidiyasa' ) {
+ $word = 'z Wikipedijo';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonaresa';
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'nominative' and all undefined case values
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageRu.php b/languages/classes/LanguageRu.php
new file mode 100644
index 00000000..b64a4144
--- /dev/null
+++ b/languages/classes/LanguageRu.php
@@ -0,0 +1,87 @@
+<?php
+/** Russian (русский язык)
+ *
+ * You can contact Alexander Sigachov (alexander.sigachov at Googgle Mail)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/* Please, see Language.php for general function comments */
+class LanguageRu extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{grammar:case|word}}
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['ru'][$case][$word]) ) {
+ return $wgGrammarForms['ru'][$case][$word];
+ }
+
+ # These rules are not perfect, but they are currently only used for site names so it doesn't
+ # matter if they are wrong sometimes. Just add a special case for your site name if necessary.
+
+ #join and array_slice instead mb_substr
+ $ar = array();
+ preg_match_all( '/./us', $word, $ar );
+ if (!preg_match("/[a-zA-Z_]/us", $word))
+ switch ( $case ) {
+ case 'genitive': #родительный падеж
+ if ((join('',array_slice($ar[0],-4))=='вики') || (join('',array_slice($ar[0],-4))=='Вики'))
+ {}
+ elseif (join('',array_slice($ar[0],-1))=='ь')
+ $word = join('',array_slice($ar[0],0,-1)).'я';
+ elseif (join('',array_slice($ar[0],-2))=='ия')
+ $word=join('',array_slice($ar[0],0,-2)).'ии';
+ elseif (join('',array_slice($ar[0],-2))=='ка')
+ $word=join('',array_slice($ar[0],0,-2)).'ки';
+ elseif (join('',array_slice($ar[0],-2))=='ти')
+ $word=join('',array_slice($ar[0],0,-2)).'тей';
+ elseif (join('',array_slice($ar[0],-2))=='ды')
+ $word=join('',array_slice($ar[0],0,-2)).'дов';
+ elseif (join('',array_slice($ar[0],-3))=='ник')
+ $word=join('',array_slice($ar[0],0,-3)).'ника';
+ break;
+ case 'dative': #дательный падеж
+ #stub
+ break;
+ case 'accusative': #винительный падеж
+ #stub
+ break;
+ case 'instrumental': #творительный падеж
+ #stub
+ break;
+ case 'prepositional': #предложный падеж
+ #stub
+ break;
+ }
+ return $word;
+ }
+
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace (' ', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+ /*
+ * Russian numeric format is "12 345,67" but "1234,56"
+ */
+
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageSk.php b/languages/classes/LanguageSk.php
new file mode 100644
index 00000000..2fa8df0f
--- /dev/null
+++ b/languages/classes/LanguageSk.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Slovak (Slovenčina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageSk extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: genitív, datív, akuzatív, lokál, inštrumentál
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['sk'][$case][$word]) ) {
+ return $wgGrammarForms['sk'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitív':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédie';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníku';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátov';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikikníh';
+ }
+ break;
+ case 'datív':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédii';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníku';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátom';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihám';
+ }
+ break;
+ case 'akuzatív':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédiu';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovník';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitáty';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihy';
+ }
+ break;
+ case 'lokál':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédii';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníku';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátoch';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihách';
+ }
+ break;
+ case 'inštrumentál':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédiou';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníkom';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátmi';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihami';
+ }
+ break;
+ }
+ return $word;
+ }
+
+ function convertPlural( $count, $w1, $w2, $w3) {
+ $count = str_replace ('.', '', $count);
+ $forms = array( $w1, $w2, $w3);
+ if ( $count == 1 ) {
+ $index = 0;
+ } elseif ( $count == 2 || $count == 3 || $count == 4 ) {
+ $index = 1;
+ } else {
+ $index = 2;
+ }
+ return $forms[$index];
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageSl.php b/languages/classes/LanguageSl.php
new file mode 100644
index 00000000..35991caa
--- /dev/null
+++ b/languages/classes/LanguageSl.php
@@ -0,0 +1,124 @@
+<?php
+/** Slovenian (Slovenščina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+class LanguageSl extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: rodilnik, dajalnik, tožilnik, mestnik, orodnik
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['sl'][$case][$word]) ) {
+ return $wgGrammarForms['sl'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'rodilnik': # genitive
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipedije';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjig';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'Wikinovic';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'Wikinavedka';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'Wikivira';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'Wikislovarja';
+ }
+ break;
+ case 'dajalnik': # dativ
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjigam';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'Wikinovicam';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'Wikinavedku';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'Wikiviru';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'Wikislovarju';
+ }
+ break;
+ case 'tožilnik': # akuzatív
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipedijo';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjige';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'Wikinovice';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'Wikinavedek';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'Wikivir';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'Wikislovar';
+ }
+ break;
+ case 'mestnik': # locative
+ if ( $word == 'Wikipedija' ) {
+ $word = 'o Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'o Wikiknjigah';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'o Wikinovicah';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'o Wikinavedku';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'o Wikiviru';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'o Wikislovarju';
+ } else {
+ $word = 'o ' . $word;
+ }
+ break;
+ case 'orodnik': # instrumental
+ if ( $word == 'Wikipedija' ) {
+ $word = 'z Wikipedijo';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'z Wikiknjigami';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'z Wikinovicami';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'z Wikinavedkom';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'z Wikivirom';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'z Wikislovarjem';
+ } else {
+ $word = 'z ' . $word;
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'imenovalnik' (nominativ) and all undefined case values
+ }
+
+ function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ $forms = array( $w1, $w2, $w3, $w4, $w5 );
+ if ( $count % 100 == 1 ) {
+ $index = 0;
+ } elseif ( $count % 100 == 2 ) {
+ $index = 1;
+ } elseif ( $count % 100 == 3 || $count % 100 == 4 ) {
+ $index = 2;
+ } elseif ( $count != 0 ) {
+ $index = 3;
+ } else {
+ $index = 4;
+ }
+ return $forms[$index];
+ }
+
+
+}
+?>
diff --git a/languages/classes/LanguageSr.deps.php b/languages/classes/LanguageSr.deps.php
new file mode 100644
index 00000000..8fe354e0
--- /dev/null
+++ b/languages/classes/LanguageSr.deps.php
@@ -0,0 +1,10 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// LanguageSr.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+require_once( dirname(__FILE__).'/LanguageSr_ec.php' );
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+?>
diff --git a/languages/classes/LanguageSr.php b/languages/classes/LanguageSr.php
new file mode 100644
index 00000000..412463f8
--- /dev/null
+++ b/languages/classes/LanguageSr.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/*
+ There are two levels of conversion for Serbian: the script level
+ (Cyrillics <-> Latin), and the variant level (ekavian
+ <->iyekavian). The two are orthogonal. So we really only need two
+ dictionaries: one for Cyrillics and Latin, and one for ekavian and
+ iyekavian.
+*/
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+require_once( dirname(__FILE__).'/LanguageSr_ec.php' );
+require_once( dirname(__FILE__).'/LanguageSr_el.php' );
+
+class SrConverter extends LanguageConverter {
+ var $mToLatin = array(
+ 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd',
+ 'ђ' => 'đ', 'е' => 'e', 'ж' => 'ž', 'з' => 'z', 'и' => 'i',
+ 'ј' => 'j', 'к' => 'k', 'л' => 'l', 'љ' => 'lj', 'м' => 'm',
+ 'н' => 'n', 'њ' => 'nj', 'о' => 'o', 'п' => 'p', 'р' => 'r',
+ 'с' => 's', 'т' => 't', 'ћ' => 'ć', 'у' => 'u', 'ф' => 'f',
+ 'х' => 'h', 'ц' => 'c', 'ч' => 'č', 'џ' => 'dž', 'ш' => 'š',
+
+ 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D',
+ 'Ђ' => 'Đ', 'Е' => 'E', 'Ж' => 'Ž', 'З' => 'Z', 'И' => 'I',
+ 'Ј' => 'J', 'К' => 'K', 'Л' => 'L', 'Љ' => 'Lj', 'М' => 'M',
+ 'Н' => 'N', 'Њ' => 'Nj', 'О' => 'O', 'П' => 'P', 'Р' => 'R',
+ 'С' => 'S', 'Т' => 'T', 'Ћ' => 'Ć', 'У' => 'U', 'Ф' => 'F',
+ 'Х' => 'H', 'Ц' => 'C', 'Ч' => 'Č', 'Џ' => 'Dž', 'Ш' => 'Š',
+ );
+
+ var $mToCyrillics = array(
+ 'a' => 'а', 'b' => 'б', 'c' => 'ц', 'č' => 'ч', 'ć' => 'ћ',
+ 'd' => 'д', 'dž' => 'џ', 'đ' => 'ђ', 'e' => 'е', 'f' => 'ф',
+ 'g' => 'г', 'h' => 'х', 'i' => 'и', 'j' => 'ј', 'k' => 'к',
+ 'l' => 'л', 'lj' => 'љ', 'm' => 'м', 'n' => 'н', 'nj' => 'њ',
+ 'o' => 'о', 'p' => 'п', 'r' => 'р', 's' => 'с', 'š' => 'ш',
+ 't' => 'т', 'u' => 'у', 'v' => 'в', 'z' => 'з', 'ž' => 'ж',
+
+ 'A' => 'А', 'B' => 'Б', 'C' => 'Ц', 'Č' => 'Ч', 'Ć' => 'Ћ',
+ 'D' => 'Д', 'Dž' => 'Џ', 'Đ' => 'Ђ', 'E' => 'Е', 'F' => 'Ф',
+ 'G' => 'Г', 'H' => 'Х', 'I' => 'И', 'J' => 'Ј', 'K' => 'К',
+ 'L' => 'Л', 'LJ' => 'Љ', 'M' => 'М', 'N' => 'Н', 'NJ' => 'Њ',
+ 'O' => 'О', 'P' => 'П', 'R' => 'Р', 'S' => 'С', 'Š' => 'Ш',
+ 'T' => 'Т', 'U' => 'У', 'V' => 'В', 'Z' => 'З', 'Ž' => 'Ж',
+
+ 'DŽ' => 'Џ', 'd!ž' => 'дж', 'D!ž'=> 'Дж', 'D!Ž'=> 'ДЖ',
+ 'Lj' => 'Љ', 'l!j' => 'лј', 'L!j'=> 'Лј', 'L!J'=> 'ЛЈ',
+ 'Nj' => 'Њ', 'n!j' => 'нј', 'N!j'=> 'Нј', 'N!J'=> 'НЈ'
+ );
+
+ function loadDefaultTables() {
+ $this->mTables = array();
+ $this->mTables['sr-ec'] = $this->mToCyrillics;
+ $this->mTables['sr-jc'] = $this->mToCyrillics;
+ $this->mTables['sr-el'] = $this->mToLatin;
+ $this->mTables['sr-jl'] = $this->mToLatin;
+ $this->mTables['sr'] = array();
+ }
+
+ /* rules should be defined as -{ekavian | iyekavian-} -or-
+ -{code:text | code:text | ...}-
+ update: delete all rule parsing because it's not used
+ currently, and just produces a couple of bugs
+ */
+ function parseManualRule($rule, $flags=array()) {
+ // ignore all formatting
+ foreach($this->mVariants as $v) {
+ $carray[$v] = $rule;
+ }
+
+ return $carray;
+ }
+
+ /*
+ * Override function from LanguageConvertor
+ * Additional checks:
+ * - There should be no conversion for Talk pages
+ */
+ function getPreferredVariant(){
+ global $wgTitle;
+ if($wgTitle!=NULL && $wgTitle->isTalkPage()){
+ return $this->mMainLanguageCode;
+ }
+ return parent::getPreferredVariant();
+ }
+
+
+ /*
+ * A function wrapper, if there is no selected variant,
+ * leave the link names as they were
+ */
+ function findVariantLink( &$link, &$nt ) {
+ $oldlink=$link;
+ parent::findVariantLink($link,$nt);
+ if($this->getPreferredVariant()==$this->mMainLanguageCode)
+ $link=$oldlink;
+ }
+
+
+ /*
+ * We want our external link captions to be converted in variants,
+ * so we return the original text instead -{$text}-, except for URLs
+ */
+ function markNoConversion($text, $noParse=false) {
+ if($noParse || preg_match("/^https?:\/\/|ftp:\/\/|irc:\/\//",$text))
+ return parent::markNoConversion($text);
+ return $text;
+ }
+
+ /*
+ * An ugly function wrapper for parsing Image titles
+ * (to prevent image name conversion)
+ */
+ function autoConvert($text, $toVariant=false) {
+ global $wgTitle;
+ if($wgTitle->getNameSpace()==NS_IMAGE){
+ $imagename = $wgTitle->getNsText();
+ if(preg_match("/^$imagename:/",$text)) return $text;
+ }
+ return parent::autoConvert($text,$toVariant);
+ }
+
+ /**
+ * It translates text into variant, specials:
+ * - ommiting roman numbers
+ */
+ function translate($text, $toVariant){
+ $breaks = '[^\w\x80-\xff]';
+
+ // regexp for roman numbers
+ $roman = 'M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})';
+
+ $reg = '/^'.$roman.'$|^'.$roman.$breaks.'|'.$breaks.$roman.'$|'.$breaks.$roman.$breaks.'/';
+
+ $matches = preg_split($reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE);
+
+ $m = array_shift($matches);
+ $ret = strtr($m[0], $this->mTables[$toVariant]);
+ $mstart = $m[1]+strlen($m[0]);
+ foreach($matches as $m) {
+ $ret .= substr($text, $mstart, $m[1]-$mstart);
+ $ret .= parent::translate($m[0], $toVariant);
+ $mstart = $m[1] + strlen($m[0]);
+ }
+
+ return $ret;
+ }
+
+
+}
+
+class LanguageSr extends LanguageSr_ec {
+ function __construct() {
+ global $wgHooks;
+
+ parent::__construct();
+
+ // these variants are currently UNUSED:
+ // 'sr-jc', 'sr-jl'
+ $variants = array('sr', 'sr-ec', 'sr-el');
+ $variantfallbacks = array(
+ 'sr' => 'sr-ec',
+ 'sr-ec' => 'sr-ec',
+ 'sr-el' => 'sr-el',
+ );
+
+
+ $marker = array();//don't mess with these, leave them as they are
+ $flags = array(
+ 'S' => 'S', 'писмо' => 'S', 'pismo' => 'S',
+ 'W' => 'W', 'реч' => 'W', 'reč' => 'W', 'ријеч' => 'W', 'riječ' => 'W'
+ );
+ $this->mConverter = new SrConverter($this, 'sr', $variants, $variantfallbacks, $marker, $flags);
+ $wgHooks['ArticleSaveComplete'][] = $this->mConverter;
+ }
+}
+?>
diff --git a/languages/classes/LanguageSr_ec.php b/languages/classes/LanguageSr_ec.php
new file mode 100644
index 00000000..f84ebd06
--- /dev/null
+++ b/languages/classes/LanguageSr_ec.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageSr_ec extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageSr_el.deps.php b/languages/classes/LanguageSr_el.deps.php
new file mode 100644
index 00000000..f39da2f2
--- /dev/null
+++ b/languages/classes/LanguageSr_el.deps.php
@@ -0,0 +1,9 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// LanguageSr_el.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+require_once( dirname(__FILE__).'/LanguageSr_ec.php' );
+?>
diff --git a/languages/classes/LanguageSr_el.php b/languages/classes/LanguageSr_el.php
new file mode 100644
index 00000000..cba1b57e
--- /dev/null
+++ b/languages/classes/LanguageSr_el.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageSr_el extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageTr.php b/languages/classes/LanguageTr.php
new file mode 100644
index 00000000..67d68f60
--- /dev/null
+++ b/languages/classes/LanguageTr.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Turkish (Türkçe)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageTr extends Language {
+ function ucfirst ( $string ) {
+ if ( $string[0] == 'i' ) {
+ return 'İ' . substr( $string, 1 );
+ } else {
+ return parent::ucfirst( $string );
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageTyv.php b/languages/classes/LanguageTyv.php
new file mode 100644
index 00000000..aacfaff5
--- /dev/null
+++ b/languages/classes/LanguageTyv.php
@@ -0,0 +1,233 @@
+<?php
+/** Tyvan localization (Тыва дыл)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# From friends at tyvawiki.org
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageTyv extends Language {
+ /**
+ * Grammatical transformations, needed for inflected languages
+ * Invoked by putting {{grammar:case|word}} in a message
+ *
+ * @param string $word
+ * @param string $case
+ * @return string
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['tyv'][$case][$word]) ) {
+ return $wgGrammarForms['tyv'][$case][$word];
+ }
+
+
+ // Set up some constants...
+ $allVowels = array("е", "и", "э", "ө", "ү", "а", "ё", "о", "у", "ы", "ю", "я", "a", "e", "i", "o", "ö", "u", "ü", "y");
+ $frontVowels = array("е", "и", "э", "ө", "ү", "e", "i", "ö", "ü");
+ $backVowels = array("а", "ё", "о", "у", "ы", "ю", "я", "a", "o", "u", "y");
+ $unroundFrontVowels = array("е", "и", "э", "e", "i");
+ $roundFrontVowels = array("ө", "ү", "ö", "ü");
+ $unroundBackVowels = array("а", "ы", "я", "a", "y");
+ $roundBackVowels = array("ё", "о", "у", "ю", "o", "u");
+ $voicedPhonemes = array("д", "б", "з", "ж", "г", "d", "b", "z", "g");
+ $unvoicedPhonemes = array("т", "п", "с", "ш", "к", "ч", "х", "t", "p", "s", "k", "x");
+ $directiveUnvoicedStems = array("т", "п", "с", "ш", "к", "ч", "х", "л", "м", "н", "ң", "t", "p", "s", "k", "x", "l", "m", "n", "ŋ");
+ $directiveVoicedStems = array("д", "б", "з", "ж", "г", "р", "й", "d", "b", "z", "g", "r", "j");
+
+// $allSonants = array("л", "м", "н", "ң", "р", "й");
+// $allNasals = array("м", "н", "ң");
+
+ // Put the word in a form we can play with since we're using UTF-8
+ preg_match_all( '/./us', $word, $ar );
+
+ $wordEnding = $ar[0][count($ar[0]) - 1]; //Here's the last letter in the word
+ $wordReversed = array_reverse($ar[0]); //Here's an array with the order of the letters in the word reversed so we can find a match quicker *shrug*
+
+ // Find the last vowel in the word
+ $wordLastVowel = NULL;
+ foreach ( $wordReversed as $xvalue ) {
+ foreach ( $allVowels as $yvalue ) {
+ if ( strcmp($xvalue, $yvalue) == 0 ) {
+ $wordLastVowel = $xvalue;
+ break;
+ } else {
+ continue;
+ }
+ }
+ if ( $wordLastVowel !== NULL ) {
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ // Now convert the word
+ switch ( $case ) {
+ case "genitive":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "түң";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "тиң";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "туң";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "тың";
+ } else {
+ }
+ } elseif ( $wordEnding === "л" || $wordEnding === "l") {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "дүң";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "диң";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дуң";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дың";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "нүң";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ниң";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "нуң";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ның";
+ } else {
+ }
+ }
+ break;
+ case "dative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "ке";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "ка";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "ге";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "га";
+ } else {
+ }
+ }
+ break;
+ case "accusative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "тү";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ти";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ту";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ты";
+ } else {
+ }
+ } elseif ( $wordEnding === "л" || $wordEnding === "l") {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "дү";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ди";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ду";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ды";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "нү";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ни";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ну";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ны";
+ } else {
+ }
+ }
+ break;
+ case "locative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "те";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "та";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "де";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "да";
+ } else {
+ }
+ }
+ break;
+ case "ablative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "тен";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "тан";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "ден";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "дан";
+ } else {
+ }
+ }
+ break;
+ case "directive1":
+ if ( in_array($wordEnding, $directiveVoicedStems) ) {
+ $word = implode("",$ar[0]) . "же";
+ } elseif ( in_array($wordEnding, $directiveUnvoicedStems) ) {
+ $word = implode("",$ar[0]) . "че";
+ } else {
+ }
+ break;
+ case "directive2":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "түве";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "тиве";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "туве";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "тыве";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "дүве";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "диве";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дуве";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дыве";
+ } else {
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return $word;
+ }
+}
+?>
diff --git a/languages/classes/LanguageVi.php b/languages/classes/LanguageVi.php
new file mode 100644
index 00000000..4f9c4da3
--- /dev/null
+++ b/languages/classes/LanguageVi.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Based on Language.php 1.645
+ * @package MediaWiki
+ * @subpackage Language
+ * Compatible to MediaWiki 1.5
+ * Initial translation by Trần Thế Trung and Nguyễn Thanh Quang
+ * Last update 28 August 2005 (UTC)
+ */
+
+class LanguageVi extends Language {
+ function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
+ if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
+
+ $datePreference = $this->dateFormat( $format );
+
+ $month = $this->formatMonth( substr( $ts, 4, 2 ), $datePreference );
+ $day = $this->formatDay( substr( $ts, 6, 2 ), $datePreference );
+ $year = $this->formatNum( substr( $ts, 0, 4 ), true );
+
+ switch( $datePreference ) {
+ case 3:
+ case 4: return "$day/$month/$year";
+ case MW_DATE_ISO: return substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
+ default: return "$day $month năm $year";
+ }
+ }
+
+ function timeSeparator( $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '4': return 'h';
+ default: return ':';
+ }
+ }
+
+ function timeDateSeparator( $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '0':
+ case '1':
+ case '2': return ', ';
+ default: return ' ';
+ }
+ }
+
+ function formatMonth( $month, $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '0':
+ case '1': return 'tháng ' . ( 0 + $month );
+ case '2': return 'tháng ' . $this->getSpecialMonthName( $month );
+ default: return 0 + $month;
+ }
+ }
+
+ function formatDay( $day, $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '0':
+ case '1':
+ case '2': return 'ngày ' . (0 + $day);
+ default: return 0 + $day;
+ }
+ }
+
+ function getSpecialMonthName( $key ) {
+ $names = 'Một, Hai, Ba, Tư, Năm, Sáu, Bảy, Tám, Chín, Mười, Mười một, Mười hai';
+ $names = explode(', ', $names);
+ return $names[$key-1];
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageWa.php b/languages/classes/LanguageWa.php
new file mode 100644
index 00000000..541c6de8
--- /dev/null
+++ b/languages/classes/LanguageWa.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Walloon (Walon)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# NOTE: cweri après "NOTE:" po des racsegnes so des ratournaedjes
+# k' i gn a.
+
+class LanguageWa extends Language {
+ ###
+ ### Dates in Walloon are "1î d' <monthname>" for 1st of the month,
+ ### "<day> di <monthname>" for months starting by a consoun, and
+ ### "<day> d' <monthname>" for months starting with a vowel
+ ###
+ function date( $ts, $adj = false, $format = true, $tc = false ) {
+ global $wgUser;
+
+ if ( $adj ) { $ts = $this->userAdjust( $ts, $tc ); }
+ $datePreference = $this->dateFormat( $format );
+
+ # ISO (YYYY-mm-dd) format
+ #
+ # we also output this format for YMD (eg: 2001 January 15)
+ if ( $datePreference == 'ISO 8601' ) {
+ $d = substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
+ return $d;
+ }
+
+ # dd/mm/YYYY format
+ if ( $datePreference == 'walloon short' ) {
+ $d = substr($ts, 6, 2). '/' . substr($ts, 4, 2). '/' .substr($ts, 0, 4);
+ return $d;
+ }
+
+ # Walloon format
+ #
+ # we output this in all other cases
+ $m = substr( $ts, 4, 2 );
+ $n = substr( $ts, 6, 2 );
+ if ($n == 1) {
+ $d = "1î d' " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ } else if ($n == 2 || $n == 3 || $n == 20 || $n == 22 || $n == 23) {
+ $d = (0 + $n) . " d' " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ } else if ($m == 4 || $m == 8 || $m == 10) {
+ $d = (0 + $n) . " d' " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ } else {
+ $d = (0 + $n) . " di " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ }
+ return $d;
+ }
+
+ function timeanddate( $ts, $adj = false, $format = true, $tc = false ) {
+ if ( $adj ) { $ts = $this->userAdjust( $ts, $tc ); }
+ $datePreference = $this->dateFormat( $format );
+ if ( $datePreference == 'ISO 8601' ) {
+ return parent::timeanddate( $ts, $adj, $format, $tc );
+ } else {
+ return $this->date( $ts, $adj, $format, $tc ) . ' a ' .
+ $this->time( $ts, $adj, $format, $tc );
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageZh.deps.php b/languages/classes/LanguageZh.deps.php
new file mode 100644
index 00000000..1d736340
--- /dev/null
+++ b/languages/classes/LanguageZh.deps.php
@@ -0,0 +1,10 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// LanguageZh.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+require_once( dirname(__FILE__).'/LanguageZh_cn.php' );
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+?>
diff --git a/languages/classes/LanguageZh.php b/languages/classes/LanguageZh.php
new file mode 100644
index 00000000..c34315ac
--- /dev/null
+++ b/languages/classes/LanguageZh.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+require_once( dirname(__FILE__).'/LanguageZh_cn.php' );
+
+class ZhConverter extends LanguageConverter {
+ function loadDefaultTables() {
+ require( "includes/ZhConversion.php" );
+ $this->mTables = array();
+ $this->mTables['zh-cn'] = $zh2CN;
+ $this->mTables['zh-tw'] = $zh2TW;
+ $this->mTables['zh-sg'] = array_merge($zh2CN, $zh2SG);
+ $this->mTables['zh-hk'] = array_merge($zh2TW, $zh2HK);
+ $this->mTables['zh'] = array();
+ }
+
+ function postLoadTables() {
+ $this->mTables['zh-sg'] = array_merge($this->mTables['zh-cn'], $this->mTables['zh-sg']);
+ $this->mTables['zh-hk'] = array_merge($this->mTables['zh-tw'], $this->mTables['zh-hk']);
+ }
+
+ /* there shouldn't be any latin text in Chinese conversion, so no need
+ to mark anything
+ */
+ function markNoConversion($text) {
+ return $text;
+ }
+
+ function convertCategoryKey( $key ) {
+ return $this->autoConvert( $key, 'zh-cn' );
+ }
+}
+
+
+/* class that handles both Traditional and Simplified Chinese
+ right now it only distinguish zh_cn, zh_tw, zh_sg and zh_hk.
+*/
+class LanguageZh extends LanguageZh_cn {
+
+ function __construct() {
+ global $wgHooks;
+ parent::__construct();
+ $this->mConverter = new ZhConverter($this, 'zh',
+ array('zh', 'zh-cn', 'zh-tw', 'zh-sg', 'zh-hk'),
+ array('zh'=>'zh-cn',
+ 'zh-cn'=>'zh-sg',
+ 'zh-sg'=>'zh-cn',
+ 'zh-tw'=>'zh-hk',
+ 'zh-hk'=>'zh-tw'));
+ $wgHooks['ArticleSaveComplete'][] = $this->mConverter;
+ }
+
+
+ # this should give much better diff info
+ function segmentForDiff( $text ) {
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' ' .\"$1\"", $text);
+ }
+
+ function unsegmentForDiff( $text ) {
+ return preg_replace(
+ "/ ([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "\"$1\"", $text);
+ }
+
+ // word segmentation
+ function stripForSearch( $string ) {
+ $fname="LanguageZh::stripForSearch";
+ wfProfileIn( $fname );
+
+ // eventually this should be a word segmentation
+ // for now just treat each character as a word
+ $t = preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' ' .\"$1\"", $string);
+
+ //always convert to zh-cn before indexing. it should be
+ //better to use zh-cn for search, since conversion from
+ //Traditional to Simplified is less ambiguous than the
+ //other way around
+
+ $t = $this->mConverter->autoConvert($t, 'zh-cn');
+ $t = parent::stripForSearch( $t );
+ wfProfileOut( $fname );
+ return $t;
+
+ }
+
+ function convertForSearchResult( $termsArray ) {
+ $terms = implode( '|', $termsArray );
+ $terms = implode( '|', $this->mConverter->autoConvertToAllVariants( $terms ) );
+ $ret = array_unique( explode('|', $terms) );
+ return $ret;
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageZh_cn.php b/languages/classes/LanguageZh_cn.php
new file mode 100644
index 00000000..af94cb99
--- /dev/null
+++ b/languages/classes/LanguageZh_cn.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageZh_cn extends Language {
+ function stripForSearch( $string ) {
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+ # we also separate characters as "words"
+ if( function_exists( 'mb_strtolower' ) ) {
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( \"$1\" )",
+ mb_strtolower( $string ) );
+ } else {
+ list( , $wikiLowerChars ) = Language::getCaseMaps();
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
+ $string );
+ }
+ }
+}
+
+
+?>
diff --git a/languages/classes/LanguageZh_yue.php b/languages/classes/LanguageZh_yue.php
new file mode 100644
index 00000000..0e45508c
--- /dev/null
+++ b/languages/classes/LanguageZh_yue.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageZh_yue extends Language {
+ function stripForSearch( $string ) {
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+ # we also separate characters as "words"
+ if( function_exists( 'mb_strtolower' ) ) {
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( \"$1\" )",
+ mb_strtolower( $string ) );
+ } else {
+ list( , $wikiLowerChars ) = Language::getCaseMaps();
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
+ $string );
+ }
+ }
+}
+
+
+?>
diff --git a/languages/messages/MessagesAb.php b/languages/messages/MessagesAb.php
new file mode 100644
index 00000000..7be9a316
--- /dev/null
+++ b/languages/messages/MessagesAb.php
@@ -0,0 +1,5 @@
+<?php
+
+$fallback = 'ru';
+
+?>
diff --git a/languages/messages/MessagesAf.php b/languages/messages/MessagesAf.php
new file mode 100644
index 00000000..56f88087
--- /dev/null
+++ b/languages/messages/MessagesAf.php
@@ -0,0 +1,694 @@
+<?php
+
+$quickbarSettings = array(
+ 'Geen.', 'Links vas.', 'Regs vas.', 'Dryf links.'
+);
+
+$skinNames = array(
+ 'standard' => 'Standaard',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Keulen blou',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Spesiaal',
+ NS_MAIN => '',
+ NS_TALK => 'Bespreking',
+ NS_USER => 'Gebruiker',
+ NS_USER_TALK => 'Gebruikerbespreking',
+ # NS_PROJECT set by $wgMetaNamespace,
+ NS_PROJECT_TALK => '$1bespreking',
+ NS_IMAGE => 'Beeld',
+ NS_IMAGE_TALK => 'Beeldbespreking',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWikibespreking',
+ NS_TEMPLATE => 'Sjabloon',
+ NS_TEMPLATE_TALK => 'Sjabloonbespreking',
+ NS_HELP => 'Hulp',
+ NS_HELP_TALK => 'Hulpbespreking',
+ NS_CATEGORY => 'Kategorie',
+ NS_CATEGORY_TALK => 'Kategoriebespreking'
+);
+
+# South Africa uses space for thousands and comma for decimal
+# Reference: AWS Reël 7.4 p. 52, 2002 edition
+# glibc is wrong in this respect in some versions
+$separatorTransformTable = array( ',' => "\xc2\xa0", '.' => ',' );
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+$messages = array(
+# User Toggles
+
+"tog-underline" => "Onderstreep skakels.",
+"tog-highlightbroken" => "Wys gebroke skakels <a href=\"\" class=\"new\">so</a> of so<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Justeer paragrawe.",
+"tog-hideminor" => "Moenie klein wysigings in die nuwe wysigingslys wys nie.",
+"tog-usenewrc" => "Verbeterde nuwe wysigingslys (vir moderne blaaiers).",
+"tog-numberheadings" => "Automatiese nommer opskrifte.",
+"tog-showtoolbar" => "Show edit toolbar",
+"tog-rememberpassword" => "Onthou wagwoord oor sessies.",
+"tog-editwidth" => "Wysigingsboks met volle wydte.",
+"tog-editondblclick" => "Wysig blaaie met dubbelkliek (JavaScript).",
+"tog-watchdefault" => "Lys nuwe en gewysigde bladsye.",
+"tog-minordefault" => "Merk alle wysigings automaties as klein by verstek.",
+"tog-previewontop" => "Wys voorskou bo wysigingsboks.",
+
+# Dates
+'sunday' => 'Sondag',
+'monday' => 'Maandag',
+'tuesday' => 'Dinsdag',
+'wednesday' => 'Woensdag',
+'thursday' => 'Donderdag',
+'friday' => 'Vrydag',
+'saturday' => 'Saterdag',
+'january' => 'Januarie',
+'february' => 'Februarie',
+'march' => 'Maart',
+'april' => 'April',
+'may_long' => 'Mei',
+'june' => 'Junie',
+'july' => 'Julie',
+'august' => 'Augustus',
+'september' => 'September',
+'october' => 'Oktober',
+'november' => 'November',
+'december' => 'Desember',
+'jan' => '01',
+'feb' => '02',
+'mar' => '03',
+'apr' => '04',
+'may' => '05',
+'jun' => '06',
+'jul' => '07',
+'aug' => '08',
+'sep' => '09',
+'oct' => '10',
+'nov' => '11',
+'dec' => '12',
+
+
+# Bits of text used by many pages:
+#
+"mainpage" => "Tuisblad",
+"about" => "Omtrent",
+"aboutsite" => "Inligting oor {{SITENAME}}",
+"aboutpage" => "{{ns:4}}:Omtrent",
+"help" => "Help",
+"helppage" => "{{ns:4}}:Hulp",
+"bugreports" => "Foutrapporte",
+"bugreportspage" => "{{ns:4}}:FoutRapporte",
+"faq" => "Gewilde vrae",
+"faqpage" => "{{ns:4}}:GewildeVrae",
+"edithelp" => "Wysighulp",
+"edithelppage" => "{{ns:4}}:Hoe_word_'n_bladsy_gewysig",
+"cancel" => "Kanselleer",
+"qbfind" => "Vind",
+"qbbrowse" => "Snuffel",
+"qbedit" => "Wysig",
+"qbpageoptions" => "Bladsy opsies",
+"qbpageinfo" => "Bladsy inligting",
+"qbmyoptions" => "My opsies",
+"mypage" => "My bladsy",
+"mytalk" => "My besprekings",
+"currentevents" => "Huidige gebeure",
+"errorpagetitle" => "Fout",
+"returnto" => "Keer terug na $1.",
+"whatlinkshere" => "Bladsye wat hierheen skakel",
+"help" => "Hulp",
+"search" => "Soek",
+"searchbutton" => "Soek",
+"go" => "Wys",
+'searcharticle' => "Wys",
+"history" => "Ouer weergawes",
+"printableversion" => "Drukbare weergawe",
+"editthispage" => "Wysig hierdie bladsy",
+"deletethispage" => "Skrap bladsy",
+"protectthispage" => "Beskerm hierdie bladsy",
+"unprotectthispage" => "Laat toe dat bladsy gewysig word",
+"newpage" => "Nuwe bladsy",
+"talkpage" => "Bespreek hierdie bladsy",
+"articlepage" => "Lees artikel",
+"userpage" => "Lees gebruikersbladsy",
+"projectpage" => "Lees metabladsy",
+"imagepage" => "Lees bladsy oor prent",
+"viewtalkpage" => "Lees bespreking",
+"otherlanguages" => "Ander tale",
+"redirectedfrom" => "(Van $1 aangestuur.)",
+"lastmodifiedat" => "Laaste wysiging op $2, $1.",
+"viewcount" => "Hierdie bladsy is al $1 keer aangevra.",
+"protectedpage" => "Beskermde bladsy",
+
+"nbytes" => "$1 grepe",
+"ok" => "Aanvaar", #fixMe
+"retrievedfrom" => "Ontsluit van \"$1\"",
+"newmessageslink" => "nuwe boodskappe",
+
+# Main script and global functions
+#
+"nosuchaction" => "Ongeldige aksie",
+"nosuchactiontext" => "Onbekende aksie deur die adres gespesifeer",
+"nosuchspecialpage" => "Ongeldige spesiale bladsy",
+"nospecialpagetext" => "Ongeldige spesiale bladsy gespesifeer.",
+
+# General errors
+#
+"error" => "Fout",
+"databaseerror" => "Databasisfout",
+"dberrortext" => "Sintaksisfout in databasisnavraag.
+Die laaste navraag was:
+<blockquote><tt>$1</tt></blockquote>
+van funksie \"<tt>$2</tt>\".
+MySQL foutboodskap \"<tt>$3: $4</tt>\".",
+"noconnect" => "Kon nie met databasis op $1 konnekteer nie",
+"nodb" => "Kon nie databasis $1 selekteer nie",
+"readonly" => "Databasis gesluit",
+"enterlockreason" => "Rede vir die sluiting,
+en beraming van wanneer ontsluiting sal plaas vind",
+"readonlytext" => "Die {{SITENAME}} databasis is tans gesluit vir nuwe
+artikelwysigings, waarskynlik vir roetine databasisonderhoud,
+waarna dit terug sal wees na normaal.
+Die administreerder wat dit gesluit het se verduideliking:
+<p>$1",
+"missingarticle" => "Die databasis het nie die teks van die veronderstelde bladsy \"$1\" gekry nie.
+Nie databasisfout nie, moontlik sagtewarefout.
+Raporteer die adres asseblief aan enige administrateur.",
+"internalerror" => "Interne fout",
+"filecopyerror" => "Kon nie lêer van \"$1\" na \"$2\" kopieer nie.",
+"filerenameerror" => "Kon nie lêernaam van \"$1\" na \"$2\" wysig nie.",
+"filedeleteerror" => "Kon nie lêer \"$1\" skrap nie.",
+"filenotfound" => "Kon nie lêer \"$1\" vind nie.",
+"unexpected" => "Onverwagte waarde: \"$1\"=\"$2\".",
+"formerror" => "Fout: kon vorm nie stuur nie",
+"badarticleerror" => "Die aksie kon nie op hierdie bladsy uitgevoer word nie.",
+"cannotdelete" => "Kon nie die bladsy of prent skrap nie, iemand anders het dit miskien reeds geskrap.",
+"badtitle" => "Ongeldige titel",
+"badtitletext" => "Die bladsytitel waarvoor gevra is, is ongeldig, leeg, of
+'n verkeerd geskakelde tussen-taal of tussen-wiki titel.",
+"perfdisabled" => "Hierdie funksie is afgeskakel tydens spitstoegangsure vir verrigtingsredes, probeer weer tussen 02:00z en 14:00z (Universeel Gekoördineerde Tyd - UGT).",
+
+# Login and logout pages
+#
+"logouttitle" => "Teken uit",
+"logouttext" => "Jy is nou uitgeteken, en kan aanhou om
+{{SITENAME}} anoniem te gebruik; of jy kan inteken as dieselfde of 'n ander gebruiker.",
+
+"welcomecreation" => "<h2>Welkom, $1.</h2><p>Jou rekening is geskep;
+moenie vergeet om jou persoonlike voorkeure te stel nie.",
+
+"loginpagetitle" => "Teken in",
+"yourname" => "Jou gebruikersnaam",
+"yourpassword" => "Jou wagwoord",
+"yourpasswordagain" => "Tik weer jou wagwoord in",
+"remembermypassword" => "Onthou my wagwoord oor sessies.",
+"loginproblem" => "<b>Daar was probleme met jou intekening.</b><br />Probeer weer.",
+"alreadyloggedin" => "<strong>Gebruiker $1, jy is reeds ingeteken.</strong><br />",
+
+"login" => "Teken in",
+"userlogin" => "Teken in",
+"logout" => "Teken uit",
+"userlogout" => "Teken uit",
+"createaccount" => "Kies nuwe wagwoord",
+"badretype" => "Die wagwoorde wat jy ingetik het, is nie dieselfde nie.",
+"userexists" => "Die gebruikersnaam wat jy gebruik het, is alreeds gebruik. Kies asseblief 'n ander gebruikersnaam.",
+"youremail" => "Jou e-pos",
+"yournick" => "Jou bynaam (vir stempel)",
+"loginerror" => "Intekenfout",
+"noname" => "Ongeldige gebruikersnaam.",
+"loginsuccesstitle" => "Suksesvolle intekening",
+"loginsuccess" => "Jy is ingeteken by {{SITENAME}} as \"$1\".",
+"nosuchuser" => "Daar is geen \"$1\" gebruikersnaam nie.
+Maak seker dit is reg gespel, of gebruik die vorm hier onder om 'n nuwe rekening te skep.",
+"wrongpassword" => "Ongeldige wagwoord, probeer weer.",
+"mailmypassword" => "Stuur my wagwword na my e-pos adres.",
+"passwordremindertitle" => "Wagwoordwenk van {{SITENAME}}",
+"passwordremindertext" => "Iemand (waarskynlik jy, van IP-adres $1)
+het gevra dat ons vir jou 'n nuwe {{SITENAME}} wagwoord stuur.
+Die wagwoord vir gebruiker \"$2\" is nou \"$3\".
+Teken asseblief in en verander jou wagwoord.",
+"noemail" => "Daar is geen e-pos adres vir gebruiker \"$1\" nie.",
+"passwordsent" => "Nuwe wagwoord gestuur na e-posadres vir \"$1\".
+Teken asseblief in na jy dit ontvang het.",
+
+# Edit pages
+#
+"summary" => "Opsomming",
+"minoredit" => "Klein wysiging",
+"watchthis" => "Hou bladsy dop",
+"savearticle" => "Stoor bladsy",
+"preview" => "Voorskou",
+"showpreview" => "Wys voorskou",
+"blockedtitle" => "Gebruiker is geblokkeer",
+"blockedtext" => "Jou gebruikersnaam of IP-adres is deur $1 geblokkeer:
+<br />''$2''<p>Jy mag $1 of een van die ander [[{{ns:4}}:administreerders|administreerders]] kontak
+om dit te bespreek.",
+"newarticle" => "(Nuut)",
+"newarticletext" =>
+"Die bladsy waarna geskakel is, bestaan nie.
+Om 'n nuwe bladsy te skep, tik in die invoerboks hier onder. Lees die [[{{ns:4}}:Help|hulp bladsy]]
+vir meer inligting.
+Indien jy per ongeluk hier is, gebruik jou blaaier se '''terug''' knop.",
+"anontalkpagetext" => "---- ''Dit is die besprekingsbladsy vir 'n anonieme gebruiker wat nie 'n rekening geskep het nie. Ons moet dus hul [[IP-adres]] gebruik om hulle te identifiseer. So 'n IP-adres kan deur verskeie gebruikers gedeel word. Indien jy 'n anonieme gebruiker is wat voel dat oneerbiedige komentaar aan jou gerig is, [[Special:Userlogin|skep 'n rekening of teken in]] om verwarring te voorkom met ander anonieme gebruikers.'' ",
+"noarticletext" => "(Daar is tans geen inligting vir hierdie artikel nie.)",
+"updated" => "(Gewysig)",
+"note" => "<strong>Nota:</strong> ",
+"previewnote" => "Onthou dat dit slegs 'n voorskou is en nog nie gestoor is nie!",
+"previewconflict" => "Hierdie voorskou reflekteer die teks in die boonste invoerboks soos dit sal lyk as jy dit stoor.",
+"editing" => "Besig om $1 te wysig",
+'editinguser' => "Besig om $1 te wysig",
+"editconflict" => "Wysigingskonflik: $1",
+"explainconflict" => "Iemand anders het hierdie bladsy gewysig sedert jy dit begin verander het.
+Die boonste invoerboks het die teks wat tans bestaan.
+Jou wysigings word in die onderste invoerboks gewys.
+Jy sal jou wysigings moet saamsmelt met die huidige teks.
+<strong>Slegs</strong> die teks in die boonste invoerboks sal gestoor word wanneer jy \"Stoor bladsy\" druk.<br />",
+"yourtext" => "Jou teks",
+"storedversion" => "Gestoorde weergawe",
+"editingold" => "<strong>Waarskuwing: jy is besig om 'n ou weergawe van hierdie bladsy te wysig.
+As jy dit stoor, sal enige wysigings sedert hierdie wysiging verloor word.</strong>",
+"yourdiff" => "Wysigings",
+/*"copyrightwarning" => "Alle bydraes aan {{SITENAME}} word beskou as beskikbaar gestel onder
+die ''GNU Free Documentation License'' (lees $1 vir meer inligting).
+As jy nie wil hê dat jou werk ongemagtig gewysig of versprei mag word nie, moet jy dit nie hier indien nie.<br />
+Jy belowe ons ook dat jy dit self geskryf het, of verkry het van 'n bron wat toelaat dat dit hier mag wees.<br />
+<strong>Moenie werk beskerm deur kopiereg sonder toestemming indien nie!</strong>",*/
+"longpagewarning" => "Waarskuwing: hierdie bladsy is $1 kilogrepe lank; sekere blaaiers
+kan probleme hê met die wysiging va blaaie langer as 32 kilogrepe. Breek asseblief die bladsy op in kleiner dele.",
+
+# History pages
+#
+"revhistory" => "Wysigingsgeskiedenis",
+"nohistory" => "Daar is geen wysigingsgeskiedenis vir hierdie bladsy nie.",
+"revnotfound" => "Wysiging nie gevind nie.",
+"revnotfoundtext" => "Die ou wysiging waarvoor jy gevra het, kon nie gevind word nie. Maak asseblief seker dat die adres wat jy gebruik
+het om toegang te kry tot hierdie bladsy, reg is.",
+"loadhist" => "Besig om bladsy wysigingsgeskiedenis te laai.",
+"currentrev" => "Huidige wysiging",
+"revisionasof" => "Wysiging soos op $1",
+"cur" => "huidige",
+"next" => "volgende",
+"last" => "vorige",
+"orig" => "oorspronklike",
+"histlegend" => "Byskrif: (huidige) = verskil van huidige weergawe,
+(vorige) = verskil van vorige weergawe, M = klein wysiging",
+
+# Diffs
+#
+"difference" => "(Verksil tussen weergawes)",
+"loadingrev" => "Besig om weergawe van verskil te laai.",
+"lineno" => "Lyn $1:",
+"editcurrent" => "Wysig die huidige weergawe van hierdie bladsy.",
+
+# Search results
+#
+"searchresults" => "soekresultate",
+"searchresulttext" => "Vir meer inligting oor {{SITENAME}} soekresultate, lees [[Project:Soek|Soek in {{SITENAME}}]].",
+"searchsubtitle" => "Vir navraag \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Vir navraag \"$1\"",
+"badquery" => "Verkeerd gestelde navraag",
+"badquerytext" => "Ons kon nie jou naavraag prosesseer nie.
+Dit is miskien omdat jy gesoek het vir iets wat minder as drie letters bevat. Jy het miskien die navraag verkeerd ingetik.",
+"matchtotals" => "Die navraag \"$1\" pas $2 artikeltitels
+en teks in $3 artikels.",
+"noexactmatch" => "Geen bladsy met hierdie presiese titel bestaan nie, probeer 'n volteksnavraag. ",
+"titlematches" => "Artikeltitel resultate",
+"notitlematches" => "Geen artikeltitel resultate nie",
+"textmatches" => "Artikelteks resultate",
+"notextmatches" => "Geen artikelteks resultate nie",
+"prevn" => "vorige $1",
+"nextn" => "volgende $1",
+"viewprevnext" => "Kyk na ($1) ($2) ($3).",
+"showingresults" => "Onder <b>$1</b> resultate, beginende met #<b>$2</b>.",
+"nonefound" => "<strong>Nota</strong>: onsuksesvolle navrae word gewoonlik veroorsaak deur 'n soektog met algemene
+woorde wat nie geindekseer word nie, of spesifisering van meer as een woord (slegs blaaie wat alle navraagwoorde
+bevat, word gewys).",
+"powersearch" => "Soek",
+"powersearchtext" => "
+Search in namespaces :<br />
+$1<br />
+$2 List redirects Search for $3 $9", #fixMe
+
+
+# Preferences page
+#
+"preferences" => "Voorkeure",
+"prefsnologin" => "Nie ingeteken nie",
+"prefsnologintext" => "Jy moet [[Special:Userlogin|ingeteken wees]]
+om voorkeure te spesifiseer.",
+"prefsreset" => "Voorkeure is herstel.",
+"qbsettings" => "Snelbalkvoorkeure", #fixMe Quickbar settings
+"changepassword" => "Verander wagwoord",
+"skin" => "Omslag",
+"math" => "Verbeeld wiskunde",
+"math_failure" => "Kon nie verbeeld nie",
+"math_unknown_error" => "onbekende fout",
+"math_unknown_function" => "onbekende funksie ",
+"math_lexing_error" => "leksikale fout",
+"math_syntax_error" => "sintaksfout",
+"saveprefs" => "Stoor voorkeure",
+"resetprefs" => "Herstel voorkeure",
+"oldpassword" => "Ou wagwoord",
+"newpassword" => "Nuwe wagwoord",
+"retypenew" => "Tik nuwe wagwoord weer in",
+"textboxsize" => "Grootte van invoerboks",
+"rows" => "Rye",
+"columns" => "Kolomme",
+"searchresultshead" => "Soekresultaat voorkeure",
+"resultsperpage" => "Aantal resultate om te wys",
+"contextlines" => "Aantal lyne per resultaat",
+"contextchars" => "Karakters konteks per lyn",
+"stubthreshold" => "Drempel vir verkorte artikels",
+"recentchangescount" => "Aantal titels in onlangse wysigings",
+"savedprefs" => "Jou voorkeure is gestoor.",
+"timezonetext" => "Aantal ure wat plaaslike tyd verskil van UGT.",
+"localtime" => "Plaaslike tyd",
+"timezoneoffset" => "Teenrekening",
+
+# Recent changes
+#
+"changes" => "wysigings",
+"recentchanges" => "Onlangse wysigings",
+"rcnote" => "Hier onder is die laaste <strong>$1</strong> wysigings gedurende die laaste <strong>$2</strong> dae.",
+"rcnotefrom" => "Hier onder is die wysigings sedert <b>$2</b> (tot by <b>$1</b> word gewys).",
+"rclistfrom" => "Wys nuwe wysigings en begin by $1",
+"rclinks" => "Wys die laaste $1 wysigings in die laaste $2 dae.",
+"diff" => "verskil",
+"hist" => "geskiedenis",
+"hide" => "vat weg",
+"show" => "wys",
+"minoreditletter" => "K",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => "Laai lêer",
+"uploadbtn" => "Laai lêer",
+"reupload" => "Herlaai",
+"reuploaddesc" => "Keer terug na die laaivorm.",
+"uploadnologin" => "Nie ingeteken nie",
+"uploadnologintext" => "Teken eers in [[Special:Userlogin|logged in]]
+om lêers te laai.",
+"uploaderror" => "Laaifout",
+"uploadtext" => "'''STOP!''' Voor jy hier laai, lees en volg {{SITENAME}} se
+[[Project:Image_use_policy|beleid oor prentgebruik]].
+
+Om prente wat voorheen gelaai is te sien of te soek, gaan na die
+[[Special:Imagelist|lys van gelaaide prente]].
+Laai van lêers en skrappings word aangeteken in die
+[[Project:Upload_log|laailog]].
+
+Gebruik die vorm hier onder om nuwe prente te laai wat jy ter illustrasie in jou artikels wil gebruik.
+In die meeste webblaaiers sal jy 'n \"Browse...\" knop sien, wat jou bedryfstelsel se standaard lêeroopmaak dialoogblokkie sal oopmaak.
+Deur 'n lêer in hierdie dialoogkassie te kies, vul jy die teksboks naas die knop met die naam van die lêer.
+Jy moet ook die blokkie merk om te bevestig dat jy geen kopieregte skend deur die lêer op te laai nie.
+Kliek die \"Laai\" knop om die laai af te handel.
+Dit mag dalk 'n rukkie neem as jy 'n stadige internetverbinding het.
+
+Die voorkeurformate is JPEG vir fotografiese prente, PNG vir tekeninge en ander ikoniese prente, en OGG vir klanklêers.
+Gebruik asseblief beskrywende lêername om verwarring te voorkom.
+Om die prent in 'n artikel te gebruik, gebruik 'n skakel met die formaat '''<nowiki>[[image:file.jpg]]</nowiki>''' of
+'''<nowiki>[[image:file.png|alt text]]</nowiki>''' of
+'''<nowiki>[[media:file.ogg]]</nowiki>''' vir klanklêers.
+
+Let asseblief op dat, soos met {{SITENAME}} bladsye, mag ander jou gelaaide lêers redigeer as hulle dink dit dien die ensiklopedie, en jy kan verhoed word om lêers te laai as jy die stelsel misbruik.",
+"uploadlog" => "laailog",
+"uploadlogpage" => "laai_log",
+"uploadlogpagetext" => "Hier onder is 'n lys van die mees onlangse lêers wat gelaai is.
+Alle tye is bedienertyd (UGT).
+<ul>
+</ul>",
+"filename" => "Lêernaam",
+"filedesc" => "Opsomming",
+"copyrightpage" => "{{ns:4}}:kopiereg",
+"copyrightpagename" => "{{SITENAME}} kopiereg",
+"uploadedfiles" => "Gelaaide lêers",
+"minlength" => "Prentname moet ten minste drie letters lank wees.",
+"badfilename" => "Prentnaam is verander na \"$1\".",
+"badfiletype" => "\".$1\" is nie 'n aanbevole lêerformaat vir prente nie.",
+"successfulupload" => "Laai suksesvol",
+"fileuploaded" => "Lêer \"$1\" suksesvol gelaai.
+Volg asseblief hierdie skakel: ($2) na die beskrywingsbladsy en vul inligting in oor die die lêer, soos waar dit vandaan kom, wie het dit geskep en wanneer, en enige iets anders wat jy daarvan af weet.",
+"uploadwarning" => "Laaiwaarskuwing",
+"savefile" => "Stoor lêer",
+"uploadedimage" => "Het \"[[$1]]\" gelaai",
+
+# Image list
+#
+"imagelist" => "Prentelys",
+"imagelisttext" => "Hier onder is a lys van $1 prente gesorteer $2.",
+"getimagelist" => "Besig om prentelys te haal",
+"ilsubmit" => "Soek",
+"showlast" => "Wys laaste $1 prente gesorteer $2.",
+"byname" => "volgens naam",
+"bydate" => "volgens datum",
+"bysize" => "volgens grootte",
+"imgdelete" => "skrap",
+"imgdesc" => "beskrywing",
+"imglegend" => "Legende: (beskrywing) = wys/verander prent se beskrywing.",
+"imghistory" => "Prentgeskiedenis",
+"revertimg" => "gaan terug",
+"deleteimg" => "skrap",
+"deleteimgcompletely" => "skrap",
+"imghistlegend" => "Legende: (huidig) = dit is die huidige prent, (skrap) = skrap hierdie ou weergawe, (gaan terug) = gaan terug na hierdie ou weergawe.
+<br /><i>Kliek die datum om die prent te sien wat op daardie datum gelaai is</i>.",
+"imagelinks" => "Prentskakels",
+"linkstoimage" => "Die volgende bladsye gebruik hierdie prent:",
+"nolinkstoimage" => "Daar is geen bladsye wat hierdie prent gebruik nie.",
+
+# Statistics
+#
+"statistics" => "Statistiek",
+"sitestats" => "Werfstatistiek",
+"userstats" => "Gebruikerstatistiek",
+"sitestatstext" => "Daar is 'n totaal van <b>$1</b> bladsye in die databasis.
+Dit sluit \"bespreek\" bladsye in, bladsye oor {{SITENAME}}, minimale \"verkorte\"
+bladsye, wegwysbladsye, en ander wat waarskynlik nie as artikels kwalifiseer nie.
+Uitsluitend bogenoemde, is daar <b>$2</b> bladsye wat waarskynlik ware artikels is.<p>
+Bladsye is al <b>$3</b> kere aangevra, en <b>$4</b> keer verander sedert die sagteware opgegradeer is (July 20, 2002).
+Dit werk uit op gemiddeld <b>$5</b> veranderings per bladsy, en bladsye word <b>$6</b> keer per verandering aangevra.",
+"userstatstext" => "Daar is <b>$1</b> geregistreerde gebruikers.
+<b>$2</b> van hulle is administrateurs (sien $3).",
+
+# Maintenance Page
+#
+"disambiguations" => "Bladsye wat onduidelikhede opklaar",
+"disambiguationspage" => "{{ns:4}}:Links_to_disambiguating_pages",
+"disambiguationstext" => "Die volgende artikels skakel na 'n <i>bladsy wat onduidelikhede opklaar</i>. Hulle behoort eerder na die relevante onderwerp te skakel.<br />'n Bladsy word gesien as een wat onduidelikhede opklaar as $1 daarna toe skakel.<br />Skakels van ander naamkontekste is <i>nie</i> hier gelys nie.",
+"doubleredirects" => "Dubbele aansture",
+"doubleredirectstext" => "<b>Let op:</b> Hierdie lys bevat moontlik false positiewe. Dit beteken gewoonlik dat daar nog teks met skakels onder die eerste #REDIRECT is.<br />\nElke ry bevat skakels na die eerste en die tweede aanstuur, asook die eerste reël van van die tweede aanstuurteks, wat gewoonlik die \"regte\" teikenbladsy gee waarna die eerste aanstuur behoort te wys.",
+"brokenredirects" => "Stukkende aansture",
+"brokenredirectstext" => "Die volgende aansture skakel na 'n bladsy wat nie bestaan nie.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Weesbladsye",
+"unusedimages" => "Ongebruikte prente",
+"popularpages" => "Populêre bladsye",
+"nviews" => "$1 keer aangevra",
+"wantedpages" => "Gesogte bladsye",
+"nlinks" => "$1 skakels",
+"allpages" => "Alle bladsye",
+"randompage" => "Lukrake bladsy",
+"shortpages" => "Kort bladsye",
+"longpages" => "Lang bladsye",
+"listusers" => "Gebruikerslys",
+"specialpages" => "Spesiale bladsye",
+"spheading" => "Spesiale bladsye",
+"recentchangeslinked" => "Verwante veranderings",
+"rclsub" => "(na bladsye waarna \"$1\" skakel)",
+"newpages" => "Nuwe bladsye",
+"movethispage" => "Skuif hierdie bladsy",
+"unusedimagestext" => "<p>Let asseblief op dat ander webwerwe, soos die internasionale {{SITENAME}}s, dalk met 'n direkte URL na 'n prent skakel, so die prent sal dus hier verskyn al word dit aktief gebruik.", // TODO: grammar
+"booksources" => "Boekbronne",
+"booksourcetext" => "Hier onder is 'n lys van skakels na ander werwe wat nuwe en tweede handse boeke verkoop, en wat dalk ook verdere inligting het oor boeke waarna jy soek.
+{{SITENAME}} is nie geaffilieer aan enige van hierdie besighede nie en die lys moet nie as 'n aanbeveling gesien word nie.",
+
+# Email this user
+#
+"mailnologin" => "Geen verstuuradres",
+"mailnologintext" => "Jy moet [[Special:Userlogin|ingeteken]]
+wees en 'n geldige e-posadres in jou [[Special:Preferences|voorkeure]]
+hê om e-pos aan ander gebruikers te stuur.",
+"emailuser" => "Stuur e-pos na hierdie gebruiker",
+"emailpage" => "Stuur e-pos na gebruiker",
+"emailpagetext" => "As die gerbuiker 'n geldoge e-posadres in haar of sy gebruikersvoorkeure het, sal die vorm hier onder 'n enkele boodskap stuur.
+Die e-posadres wat jy in jou gebruikersvoorkeure het sal verkyn as die \"Van\" adres van die pos, so die ontvanger sal kan terug antwoord.",
+"noemailtitle" => "Geen e-posadres",
+"noemailtext" => "Hierdie gebruiker het nie 'n geldige e-posadres gespesifiseer nie of het gekies om nie e-pos van ander gebruikers te ontvang nie.",
+"emailfrom" => "Van",
+"emailto" => "Aan",
+"emailsubject" => "Onderwerp",
+"emailmessage" => "Boodskap",
+"emailsend" => "Stuur",
+"emailsent" => "E-pos gestuur",
+"emailsenttext" => "Jou e-pos is gestuur.",
+
+# Watchlist
+#
+"watchlist" => "My dophoulys",
+"nowatchlist" => "Jy het geen items in jou dophoulys nie.",
+"watchnologin" => "Nie ingeteken nie",
+"watchnologintext" => "Jy moet [[Special:Userlogin|ingeteken]]
+wees om jou dophoulys te verander.",
+"addedwatch" => "Bygevoeg tot dophoulys",
+"addedwatchtext" => "Die bladsy \"$1\" is by jou <a href=\"" .
+ "{{localurle:Special:Watchlist}}\">dophoulys</a> gevoeg.
+Toekomstige veranderinge aan hierdie bladsye en sy geassosieerde Bespreekbladsy sal hier verskyn en die bladsy sal in <b>vetdruk</b> verskyn in die <a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">lys van onlangse wysigings</a> om dit makliker te maak om dit raak te sien.</p>
+
+<p>As jy die bladsy later van jou dophoulys wil verwyder, kliek \"Moenie meer dophou\" in die kantbalk.",
+"removedwatch" => "Afgehaal van dophoulys",
+"removedwatchtext" => "Die bladsy \"$1\" is van jou dophoulys afgehaal.",
+"watchthispage" => "Hou hierdie bladsy dop",
+"unwatchthispage" => "Moenie meer dophou",
+"notanarticle" => "Nie 'n artikel",
+
+# Delete/protect/revert
+#
+"deletepage" => "Skrap bladsy",
+"confirm" => "Bevestig",
+"confirmdelete" => "Bevestig skrapping",
+"deletesub" => "(Besig om \"$1\" te skrap)",
+"confirmdeletetext" => "Jy staan op die punt om 'n bladsy of prent asook al hulle geskiedenis uit die databasis te skrap.
+Bevestig asseblief dat jy dit wil doen, dat jy die gevolge verstaan en dat jy dit doen in ooreenstemming met die [[{{ns:4}}:Policy]].",
+"actioncomplete" => "Aksie uitgevoer",
+"deletedtext" => "\"$1\" is geskrap.
+Kyk na $2 vir 'n rekord van onlangse skrappings.",
+"deletedarticle" => "\"$1\" geskrap",
+"dellogpage" => "Skrap_log",
+"dellogpagetext" => "Hier onder is 'n lys van die mees onlangse skrappings. Alle tye is bedienertyd (UGT).
+<ul>
+</ul>",
+"deletionlog" => "skrappingslog",
+"reverted" => "Het terug gegaan na vroeëre weergawe",
+"deletecomment" => "Rede vir skrapping",
+"imagereverted" => "Terugkeer na vorige weergawe was suksesvol.",
+"rollback" => "Rol veranderinge terug",
+"rollbacklink" => "Rol terug",
+"cantrollback" => "Kan nie na verandering terug keer nie; die laaste bydraer is die enigste outer van hierdie bladsy.",
+"revertpage" => "Het teruggegaan na laaste verandering wat $1 gemaak het",
+
+# Undelete
+"undelete" => "Herstel geskrapte bladsy",
+"undeletepage" => "Bekyk en herstel geskrapte bladsye",
+"undeletepagetext" => "Die volgende bladsye is geskrap, maar hulle is nog in die argief en kan herstel word. Die argief kan periodiek skoongemaak word.",
+"undeletearticle" => "Herstel geskrapte bladsy",
+"undeleterevisions" => "$1 weergawes in argief",
+"undeletehistory" => "As jy die bladsy herstel, sal alle weergawes herstel word.
+As 'n nuwe bladsy met dieselfde naam sedert die skrapping geskep is, sal die herstelde weergawes in die nuwe bladsy se voorgeskiedenis verskyn en die huidige weergawe van die lewendige bladsy sal nie outomaties vervang word nie.",
+"undeleterevision" => "Geskrape weergawes vanaf $1",
+"undeletebtn" => "Herstel!",
+"undeletedarticle" => "het \"$1\" herstel",
+
+# Contributions
+#
+"contributions" => "Gebruikersbydraes",
+"mycontris" => "My bydraes",
+"contribsub" => "Vir $1",
+
+"nocontribs" => "Geen veranderinge wat by hierdie kriteria pas, is gevind nie.",
+"ucnote" => "Hier onder is die gebruiker se laaste <b>$1</b> veranderings in die laaste <b>$2</b> dae.",
+"uclinks" => "Bekyk die laaste $1 veranderings; bekyk die laaste $2 dae.",
+"uctop" => " (boontoe)" ,
+
+# What links here
+#
+"whatlinkshere" => "Wat skakel hierheen",
+"notargettitle" => "Geen teiken",
+"notargettext" => "Jy het nie 'n teikenbladsy of gebruiker waarmee hierdie funksie moet werk, gespesifiseer nie.",
+"linklistsub" => "(Lys van skakels)",
+"linkshere" => "Die volgende bladsye skakel hierheen:",
+"nolinkshere" => "Geen bladsye skakel hierheen nie.",
+"isredirect" => "Stuur bladsy aan",
+
+# Block/unblock IP
+#
+"blockip" => "Blok IP-adres",
+"blockiptext" => "Gebruik die vorm hier onder om skryftoegang van 'n sekere IP-adres te blok.
+Dit moet net gedoen word om vandalisme te voorkom en in ooreenstemming met [[{{ns:4}}:Policy|{{SITENAME}} policy]].
+Vul 'n spesifieke rede hier onder in (haal byvoorbeeld spesifieke bladsye wat gevandaliseer is, aan).",
+"ipaddress" => "IP-Adres",
+"ipbreason" => "Rede",
+"ipbsubmit" => "Blok hierdie adres",
+"badipaddress" => "Die IP-adres is nie in die regte formaat nie.",
+"blockipsuccesssub" => "Blokkering het geslaag",
+"blockipsuccesstext" => "Die IP-adres \"$1\" is geblok.
+<br />Kyk na [[Special:Ipblocklist|IP block list]] vir 'n oorsig van blokkerings.",
+"unblockip" => "Maak IP-adres oop",
+"unblockiptext" => "Gebruik die vorm hier onder om skryftoegang te herstel vir 'n voorheen geblokkeerde IP-adres.",
+"ipusubmit" => "Maak hierdie adres oop",
+"ipblocklist" => "Lys van geblokkeerde IP-adresse",
+'blocklistline' => '$1, $2 het $3 geblok ($4)',
+"blocklink" => "blok",
+"unblocklink" => "maak oop",
+"contribslink" => "bydraes",
+
+# Developer tools
+#
+"lockdb" => "Sluit databasis",
+"unlockdb" => "Ontsluit databasis",
+"lockdbtext" => "As jy die databasis sluit, kan geen gebruiker meer bladsye redigeer nie, voorkeure verander nie, dophoulyste verander nie, of ander aksies uitvoer wat veranderinge in die databasis verg nie.
+Bevestig asseblief dat dit is wat jy wil doen en dat jy die databasis sal ontsluit sodra jy jou instandhouding afgehandel het.",
+"unlockdbtext" => "As jy die databasis ontsluit, kan gebruikers weer bladsye redigeer, voorkeure verander, dophoulyste verander, of ander aksies uitvoer wat veranderinge in die databasis verg.
+Bevestig asseblief dat dit is wat jy wil doen.",
+"lockconfirm" => "Ja, ek wil regtig die databasis sluit.",
+"unlockconfirm" => "Ja, ek wil regtig die databasis ontsluit.",
+"lockbtn" => "Sluit die databasis",
+"unlockbtn" => "Ontsluit die databasis",
+"locknoconfirm" => "Jy het nie die bevestigblokkie gemerk nie.",
+"lockdbsuccesssub" => "Databasissluit het geslaag",
+"unlockdbsuccesssub" => "Databasisslot is verwyder",
+"lockdbsuccesstext" => "Die {{SITENAME}} databasis is gesluit.
+<br />Onthou om dit te ontsluit wanneer jou onderhoud afgehandel is.",
+"unlockdbsuccesstext" => "Die {{SITENAME}} databasis is ontsluit.",
+
+# Move page
+#
+"movepage" => "Skuif bladsy",
+"movepagetext" => "Met die vorm hier onder kan jy 'n bladsy hernoem en so al sy geskiedenis na die nuwe naam skuif.
+Die ou titel sal 'n aanstuurbladsy na die nuwe titel word.
+Skakels na die ou bladsytitel sal nie verander nie; maak seker dat jy
+check vir dubbele of gebrekte aansture.
+Dis jou verantwoordelikheid om seker te maak dat skakels steeds wys waarheen hulle moet.
+
+Let op dat 'n bladsy '''nie''' geskuif sal word as daar reeds 'n bladsy met so 'n titel bestaan nie, tensy dit leeg is off 'n aanstuurbladsy is, en dit het geen veranderingsgeskiedenis nie. Dit beteken dat jy 'n bladsy kan hernoem na sy ou titel as jy 'n fout gemaak het, en jy kan nie oor 'n bestaande bladsy skryf nie.
+
+<b>WAARSKUWING!</b>
+Hierdie kan 'n drasitiese en onverwagte verandering vir 'n populêre bladsy wees;
+maak asseblief seker dat jy die gevolge verstaan voordat jy voortgaan.",
+"movepagetalktext" => "Die geassosieerde praatbladsy, indien enige, sal outomaties saam met dit geskuif word, '''behalwe as:'''
+*Jy die bladsy oor naamkontekste heen skuif,
+*'n Bespreekbladsy wat nie leeg is nie reeds onder die nuwe naam bestaan, of
+*Jy die merk uit blokkie hier onder wegneem.
+
+In hierdie gevalle, sal jy die bladsy met die hand moet skuif of saamsmelt as jy wil.",
+"movearticle" => "Skuif bladsy",
+"movenologin" => "Nie ingeteken nie",
+"movenologintext" => "Jy moet 'n geregistreerde gebruiker wees en [[Special:Userlogin|ingeteken]]
+wees om 'n bladsy te skuif.",
+"newtitle" => "Na nuwe titel",
+"movepagebtn" => "Skuif bladsy",
+"pagemovedsub" => "Verskuiwing het geslaag",
+"pagemovedtext" => "Bladsy \"[[$1]]\" geskuif na \"[[$2]]\".",
+"articleexists" => "'n Bladsy met daardie naam bestaan reeds, of die naam wat jy gekies het, is nie geldig nie.
+Kies asseblief 'n ander naam.",
+"talkexists" => "Die bladsy self is suksesvol verskuif, maar die bespreekbladsy kon nie geskuif word nie omdat een reeds bestaan met die nuwe titel. Smelt hulle asseblief met die hand saam.",
+"movedto" => "geskuif na",
+"movetalk" => "Skuif \"bespreek\"bladsy ook, indien van toepassing.",
+"talkpagemoved" => "Die ooreenkomstige bespreekbladsy is ook geskuif.",
+"talkpagenotmoved" => "Die ooreenkomstige bespreekbladsy is <strong>nie</strong> geskuif nie.",
+
+#Math
+'mw_math_png' => "Gebruik altyd PNG.",
+'mw_math_simple' => "Gebruik HTML indien dit eenvoudig is, andersins PNG.",
+'mw_math_html' => "Gebruik HTML wanneer moontlik, andersins PNG.",
+'mw_math_source' => "Los as TeX (vir teks blaaiers).",
+'mw_math_modern' => "Moderne blaaiers.",
+'mw_math_mathml' => 'MathML',
+
+);
+
+
+
+?>
diff --git a/languages/messages/MessagesAn.php b/languages/messages/MessagesAn.php
new file mode 100644
index 00000000..a10cd232
--- /dev/null
+++ b/languages/messages/MessagesAn.php
@@ -0,0 +1,24 @@
+<?php
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Espezial',
+ NS_MAIN => '',
+ NS_TALK => 'Descusión',
+ NS_USER => 'Usuario',
+ NS_USER_TALK => 'Descusión_usuario',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Descusión_$1',
+ NS_IMAGE => 'Imachen',
+ NS_IMAGE_TALK => 'Descusión_imachen',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Descusión_MediaWiki',
+ NS_TEMPLATE => 'Plantilla',
+ NS_TEMPLATE_TALK => 'Descusión_plantilla',
+ NS_HELP => 'Aduya',
+ NS_HELP_TALK => 'Descusión_aduya',
+ NS_CATEGORY => 'Categoría',
+ NS_CATEGORY_TALK => 'Descusión_categoría',
+);
+
+?>
diff --git a/languages/messages/MessagesAr.php b/languages/messages/MessagesAr.php
new file mode 100644
index 00000000..476b6621
--- /dev/null
+++ b/languages/messages/MessagesAr.php
@@ -0,0 +1,607 @@
+<?php
+/** Arabic (العربية)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$linkPrefixExtension = true;
+$fallback8bitEncoding = 'windows-1256';
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+ # Underlines seriously harm legibility. Force off:
+ 'underline' => 0,
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'ملف',
+ NS_SPECIAL => 'خاص',
+ NS_MAIN => '',
+ NS_TALK => 'نقاش',
+ NS_USER => 'مستخدم',
+ NS_USER_TALK => 'نقاش_المستخدم',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'نقاش' . '_$1',
+ NS_IMAGE => 'صورة',
+ NS_IMAGE_TALK => 'نقاش_الصورة',
+ NS_MEDIAWIKI => 'ميدياويكي',
+ NS_MEDIAWIKI_TALK => 'نقاش_ميدياويكي',
+ NS_TEMPLATE => 'قالب',
+ NS_TEMPLATE_TALK => 'نقاش_قالب',
+ NS_HELP => 'مساعدة',
+ NS_HELP_TALK => 'نقاش_المساعدة',
+ NS_CATEGORY => 'تصنيف',
+ NS_CATEGORY_TALK => 'نقاش_التصنيف'
+);
+
+
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#REDIRECT' , '#تحويل' ),
+ 'notoc' => array( 0, '__NOTOC__' , '__لافهرس__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__' , '__لصق_فهرس__' ),
+ 'toc' => array( 0, '__TOC__' , '__فهرس__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__' , '__لاتحريرقسم__' ),
+ 'start' => array( 0, '__START__' , '__ابدأ__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH' , 'شهر' , 'شهر_حالي' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME' , 'اسم_شهر', 'اسم_شهر_حالي'),
+# 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN' ),
+# 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV' ),
+ 'currentday' => array( 1, 'CURRENTDAY' , 'يوم' ),
+# 'currentday2' => array( 1, 'CURRENTDAY2' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME' , 'اسم_يوم' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR' , 'عام' ),
+ 'currenttime' => array( 1, 'CURRENTTIME' , 'وقت' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES' ,'عددالمقالات' , 'عدد_المقالات'),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES' , 'عددالملفات' , 'عدد_الملفات'),
+ 'pagename' => array( 1, 'PAGENAME' , 'اسم_صفحة' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE' , 'عنوان_صفحة' ),
+ 'namespace' => array( 1, 'NAMESPACE' , 'نطاق' ),
+ 'namespacee' => array( 1, 'NAMESPACEE' , 'عنوان_نطاق' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'اسم_كامل' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE' , 'عنوان_كامل' ),
+ 'msg' => array( 0, 'MSG:' , 'رسالة:' ),
+ 'subst' => array( 0, 'SUBST:' , 'نسخ:' , 'نسخ_قالب:' ),
+ 'msgnw' => array( 0, 'MSGNW:' , 'مصدر:' , 'مصدر_قالب:' ),
+ 'end' => array( 0, '__END__' , '__نهاية__', '__إنهاء__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' , 'تصغير' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1' ,'تصغير=$1' ),
+ 'img_right' => array( 1, 'right' , 'يمين' ),
+ 'img_left' => array( 1, 'left' , 'يسار' ),
+ 'img_none' => array( 1, 'none' , 'بدون' ),
+ 'img_width' => array( 1, '$1px' , '$1بك' ),
+ 'img_center' => array( 1, 'center', 'centre' , 'وسط' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame' , 'إطار', 'اطار'),
+ 'int' => array( 0, 'INT:' , 'محتوى:' ),
+ 'sitename' => array( 1, 'SITENAME' , 'اسم_الموقع' ),
+ 'ns' => array( 0, 'NS:' , 'نط:' ),
+ 'localurl' => array( 0, 'LOCALURL:' , 'عنوان:' ),
+# 'localurle' => array( 0, 'LOCALURLE:' ),
+ 'server' => array( 0, 'SERVER' , 'العنوان' ),
+ 'servername' => array( 0, 'SERVERNAME' , 'اسم_عنوان' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH' , 'مسار' ),
+# 'grammar' => array( 0, 'GRAMMAR:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', 'لاتحويل_عنوان'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', 'لاتحويل_محتوى' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK' , 'أسبوع' ),
+ 'currentdow' => array( 1, 'CURRENTDOW' , 'رقم_يوم' ),
+ 'revisionid' => array( 1, 'REVISIONID' , 'نسخة' ),
+# 'plural' => array( 0, 'PLURAL:' ),
+ 'fullurl' => array( 0, 'FULLURL:', 'عنوان_كامل:' ),
+# 'fullurle' => array( 0, 'FULLURLE:' ),
+# 'lcfirst' => array( 0, 'LCFIRST:' ),
+# 'ucfirst' => array( 0, 'UCFIRST:' ),
+# 'lc' => array( 0, 'LC:' ),
+# 'uc' => array( 0, 'UC:' ),
+# 'raw' => array( 0, 'RAW:' ),
+);
+
+$digitTransformTable = array(
+ '0' => '٠',
+ '1' => '١',
+ '2' => '٢',
+ '3' => '٣',
+ '4' => '٤',
+ '5' => '٥',
+ '6' => '٦',
+ '7' => '٧',
+ '8' => '٨',
+ '9' => '٩',
+ '.' => '٫', // wrong table?
+ ',' => '٬'
+);
+
+$messages = array(
+# Dates
+'sunday' => 'الأحد',
+'monday' => 'الإثنين',
+'tuesday' => 'الثلاثاء',
+'wednesday' => 'الأربعاء',
+'thursday' => 'الخميس',
+'friday' => 'الجمعة',
+'saturday' => 'السبت',
+'january' => 'يناير',
+'february' => 'فبراير',
+'march' => 'مارس',
+'april' => 'ابريل',
+'may_long' => 'مايو',
+'june' => 'يونيو',
+'july' => 'يوليو',
+'august' => 'أغسطس',
+'september' => 'سبتمبر',
+'november' => 'نوفمبر',
+'december' => 'ديسمبر',
+'jan' => 'يناير',
+'feb' => 'فبراير',
+'mar' => 'مارس',
+'apr' => 'ابريل',
+'may' => 'مايو',
+'jun' => 'يونيو',
+'jul' => 'يوليو',
+'aug' => 'أغسطس',
+'sep' => 'سبتمبر',
+'nov' => 'نوفمبر',
+'dec' => 'ديسمبر',
+
+# Bits of text used by many pages:
+#
+'mainpage' => 'الصفحة الرئيسية',
+'mytalk' => 'صفحة نقاشي',
+'history_short' => 'تاريخ الصفحة',
+'edit' => 'عدل هذه الصفحة',
+'delete' => 'حذف هذه الصفحة',
+'protect' => 'صفحة محمية',
+'talk' => 'ناقش هذه الصفحة',
+
+# Watchlist
+#
+'watch' => 'راقب هذه الصفحة',
+'watchthispage' => 'راقب هذه الصفحة',
+'unwatch' => 'توقف عن مراقبة الصفحة',
+'unwatchthispage' => 'توقف عن مراقبة الصفحة',
+
+'1movedto2' => '$1 تم نقلها إلى $2',
+'1movedto2_redir' => 'تم نقل $1 فوق التحويلة $2',
+'about' => 'حول',
+'aboutpage' => '{{ns:project}}:حول',
+'accmailtext' => 'تم إرسال كلمة السر الخاصة بـ \'$1\' إلى العنوان $2.',
+'accmailtitle' => 'تم إرسال كلمة السر.',
+'acct_creation_throttle_hit' => 'معذرة، لقد أقمت $1 حساب. لا يممكنك عمل المزيد.',
+'actioncomplete' => 'انتهاء العملية',
+'addedwatch' => 'تمت الإضافة لقائمة المراقبة',
+'allmessages' => 'كافة رسائل النظام',
+'allpages' => 'كل الصفحات',
+'allpagessubmit' => 'اذهب',
+'alphaindexline' => '$1 إلى $2',
+'alreadyloggedin' => '<strong>المستخدم $1, انت مسجل للدخول من قبل!</strong><br />',
+'ancientpages' => 'المقالات القديمة',
+'anontalkpagetext' => '----
+هذه صفحة نقاش لمستخدم مجهول، وهو المستخدم الذي لم يقم بإنشاء حساب في {{SITENAME}}، أو لا يستعمل ذلك الحساب.
+لذا يتم إستعمال رقم ال IP للتعريف به. من الممكن أن يشترك عدد من المستخدمين بنفس رقم ال IP. إذا كنت مستخدم مجهول
+وترى أن رسائل خير موجهة لك قد وصلتك، من الممكن أن تقوم [[Special:Userlogin|بإنشاء حساب أو القيام بالدخول]]
+حتى يزول الخلط بينك وبين المستخدمين المجهولين الآخرين.',
+'anonymous' => 'مستخدم مجهول ل{{SITENAME}}',
+'article' => 'مقالة',
+'articleexists' => 'يوجد صفحة بهذا الإسم،
+أو أن الإسم الذي تم إختياره غير صالح.
+يرجى إختيار إسم آخر.',
+'articlepage' => 'عرض المقالة',
+'badfilename' => 'تم تغيير إسم الصورة إلى "$1".',
+'badipaddress' => 'لا يوجد مستخدم بهذا الإسم',
+'badquery' => 'نص بحث خاطئ',
+'badretype' => 'كلمات السر التي أدخلتها غير متطابقة.',
+'badtitle' => 'عنوان خاطئ',
+'blanknamespace' => 'مقالات',
+'blockedtext' => 'إسم المستخدم أو عنوان ال IP الخاص بك تم منعه من قبل $1.
+سبب المنع هو: <br />\'\'$2\'\' <p>
+من الممكن الإتصال مع $1 للنقاش حول المنع، أو من الممكن الإتصال مع أحد [[{{ns:project}}:Administrators|الإداريين]] حول ذلك.
+
+تذكر أنه لا يمكن لك إستعمال خاصية إرسال رسائل إلكترونية للمستخدمين إلا إذا كنت قد وضعت عنوان بريدي صحيح في صفحة [[Special:Preferences|التفضيلات]] الخاصة بك.
+
+عنوان ال IP الخاص بك هو $3. يرجى إضافته في أي رسالة للتساؤل حول المنع.',
+'blockedtitle' => 'المستخدم ممنوع',
+'blockip' => 'منع مستخدم',
+'blocklink' => 'منع مستخدم',
+'blocklogentry' => 'منع "$1" لفترة زمنية مدتها $2',
+'bold_sample' => 'نص عريض',
+'bold_tip' => 'نص عريض',
+'booksources' => 'مصدر كتاب',
+'brokenredirects' => 'وصلات مكسورة',
+'brokenredirectstext' => 'الوصلات التالية تشير لصفحات غير موجودة.',
+'bugreports' => 'تقارير الأخطاء',
+'bydate' => 'على التاريخ',
+'byname' => 'على الإسم',
+'bysize' => 'على الحجم',
+'cancel' => 'إلغاء العملية',
+'categories' => 'تصنيفات الصفحة',
+'categoriespagetext' => 'التصنيفات التالية موجودة في {{SITENAME}}',
+'category_header' => 'المقالات في التصنيف "$1"',
+'categoryarticlecount' => 'يوجد $1 مقال في هذا التصنيف.',
+'changepassword' => 'غير كلمة السر',
+'changes' => 'تغييرات',
+'columns' => 'أعمدة',
+'compareselectedversions' => 'قارن بين النسخ المختارة',
+'confirm' => 'تأكيد',
+'confirmdelete' => 'تأكيد الحذف',
+'confirmprotect' => 'تأكيد الحماية',
+'confirmprotecttext' => 'هل أنت متأكد انك تريد حماية هذه الصفحة؟',
+'confirmunprotect' => 'تأكيد إزالة الحماية',
+'confirmunprotecttext' => 'هل أنت متأكد انك تريد إزالة الحماية عن هذه الصفحة؟',
+'contribslink' => 'مساهمات',
+'contribsub' => 'للمستخدم $1',
+'contributions' => 'مساهمات المستخدم',
+'copyright' => 'المحتويات تحت $1.',
+'copyrightpage' => '{{ns:project}}:حقوق النسخ',
+'copyrightpagename' => 'حقوق النسخ في {{SITENAME}}',
+/*'copyrightwarning' => 'يرجى الملاحظة أن جميع المساهمات هنا خاضعة وصادرة تحت ترخيص
+جنو للوثائق الحرة (أنظر في $1 للمزيد من التفاصيل)
+إذا لم ترد أن تخضع كتابتك للتعديل والتوزيع الحر، لا تضعها هنا.
+<br />
+كما أنك تتعهد بأنك قمت بكتابة ما هو موجود بنفسك، أو قمت بنسخها
+من مصدر يخضع ضمن الملكية العامة، أو مصدر حر آخر.
+<strong>لا ترسل أي عمل ذو حقوق محفوظة بدون الإذن من صاحب الحق</strong>.',*/
+'createaccount' => 'إنشاء حساب جديد',
+'createaccountmail' => 'عبر البريد الإلكتروني',
+'cur' => 'الحالي',
+'currentevents' => 'احداث حالية',
+'currentrev' => 'النسخة الحالية',
+'databaseerror' => 'خطأ في قاعدة البيانات',
+'dateformat' => 'صيغة التاريخ',
+'deadendpages' => 'صفحات نهاية مسدودة',
+'defaultns' => 'أبحث في هذه النطاقات بشكل أفتراضي:',
+'defemailsubject' => 'رسالة من {{SITENAME}}',
+'deletecomment' => 'سبب الحذف',
+'deletedarticle' => 'تم حذف "$1"',
+'deletedtext' => '"$1" تم حذفها.
+انظر في $2 لسجل آخر عمليات الحذف.',
+'deleteimg' => 'حذف',
+'deletepage' => 'حذف الصفحة',
+'deletesub' => '(حذف "$1")',
+'deletethispage' => 'حذف هذه الصفحة',
+'deletionlog' => 'سجل الحذف',
+'dellogpage' => 'سجل_الحذف',
+'diff' => 'فرق',
+'disclaimerpage' => '{{ns:project}}:عدم_مسؤولية_عام',
+'disclaimers' => 'عدم مسؤولية',
+'doubleredirects' => 'وصلات مزدوجة',
+'editcurrent' => 'حرر النسخة الحالية من هذه الصفحة',
+'edithelp' => 'مساعدة التحرير',
+'edithelppage' => '{{ns:project}}:مساعدة التحرير',
+'editing' => 'تحرير $1',
+'editinguser' => 'تحرير $1',
+'editingold' => '<strong> تحذير: أنت تقوم الآن بتحرير نسخة قديمة من هذه الصفحة. إذا قمت بحفظها، سيتم فقدات كافة التغييرات التي حدثت بعد هذه النسخة. </strong>',
+'editsection' => 'تحرير',
+'editold' => 'تحرير',
+'editthispage' => 'عدل هذه الصفحة',
+'emailfrom' => 'من',
+'emailmessage' => 'نص الرسالة',
+'emailpage' => 'أرسل رسالة للمستخدم',
+'emailpagetext' => 'لو أن هذا المستخدم قد قام بإدخال عنوان بريدي صحيح في تفضيلاته،
+فسيتم إرسال رسالة واحدة له بالنموذج أدناه.
+العنوان الذي قمت أنت بإدخاله لك في تفضيلات المستخدم،
+سيظهر في مكان المرسل في الرسالة التي سترسل له، ليتمكن من الرد عليك.',
+'emailsend' => 'إرسال',
+'emailsent' => 'تم إرسال الرسالة',
+'emailsenttext' => 'تم إرسال رسالتك الإلكترونية.',
+'emailsubject' => 'العنوان',
+'emailto' => 'إلى',
+'emailuser' => 'أرسل رسالة لهذا المستخدم',
+'error' => 'خطأ',
+'errorpagetitle' => 'خطأ',
+'excontent' => 'المحتوى كان: \'$1\'',
+'excontentauthor' => 'المحتوى كان: \'$1\' (و المساهم الوحيد كان \'$2\')',
+'explainconflict' => 'لقد قام أحد ما بتعديل الصفحة بعد أن بدأت انت بتحريرها.
+صندوق النصوص العلوي يحتوي على النص الموجود حاليا في الصفحة.
+والتغييرات التي قمت أنت بها موجودة في الصندوق في أسفل الصفحة.
+يجب أن تقوم بدمج تغييراتك في النص الموجود حاليا.
+<b>فقط</b> ما هو موجود في الصندوق العلوي هو ما سيتم حفظه وإستعاله عند الضغط على زر "حفظ الصفحة".
+<p>',
+'export' => 'صدّر صفحات',
+'faq' => 'الأسئلة الأكثر تكرارا',
+'faqpage' => '{{ns:project}}:أسئلة متكررة',
+'filecopyerror' => 'لا يمكن نسخ الملف من "$1" إلى "$2".',
+'filedeleteerror' => 'لا يمكن حذف الملف "$1".',
+'filedesc' => 'وصف قصير',
+'filename' => 'إسم الملف',
+'filenotfound' => 'لا يمكن إيجاد الملف "$1".',
+'filerenameerror' => 'لا يمكن غيير إسم الملف من "$1" إلى "$2".',
+'filesource' => 'مصدر',
+'go' => 'إذهب',
+'searcharticle' => 'إذهب',
+'headline_sample' => 'نص عنوان رئيسي',
+'headline_tip' => 'عنوان من المستوى الثاني',
+'help' => 'مساعدة',
+'helppage' => '{{ns:project}}:مساعدة',
+'hide' => 'إخفاء',
+'hidetoc' => 'إخفاء',
+'hist' => 'تاريخ',
+'histlegend' => 'مفتاح: (الحالي) = الفرق مع النسخة الحالية
+(السابق) = الفروقات مع النسخة السابقة، ط = تغيير طفيف',
+'history' => 'تاريخ الصفحة',
+'ilsubmit' => 'بحث',
+'imagelist' => 'قائمة الصور',
+'imagepage' => 'عرض صفحة الصورة',
+'imgdelete' => 'حذف',
+'imgdesc' => 'وصف',
+'imghistory' => 'تاريخ الصورة',
+'internalerror' => 'خطأ داخلي',
+'intl' => 'وصلات بين لغات الموسوعة',
+'invert' => 'عكس الإختيار',
+'ipblocklist' => 'قائمة أسماء الأعضاء و عناوين ال IP الممنوعة',
+'ipbreason' => 'السبب',
+'isredirect' => 'صفحة تحويل',
+'italic_sample' => 'نص مائل',
+'italic_tip' => 'نص مائل',
+'last' => 'السابق',
+'lastmodifiedat' => 'أخر تعديل لهذه الصفحة كان في $2, $1.',
+'lineno' => 'سطر $1:',
+'link_sample' => 'عنوان وصلة',
+'linkshere' => 'الصفحات التالية تحتوي على وصلة إلى هنا:',
+'linkstoimage' => 'الصفحات التالية تحتوي على وصلة لهذه الصورة:',
+'listusers' => 'قائمة الأعضاء',
+'loadhist' => 'تحميل تاريخ الصفحة',
+'localtime' => 'عرض الوقت المحلي',
+'log' => 'تحميل و حذف',
+'login' => 'دخول',
+'loginerror' => 'خطأ في الدخول',
+'loginpagetitle' => 'تسجيل الدخول للمستخدم',
+'loginproblem' => '<b>حدثت مشكلة أثناء الدخول.</b><br />يرجى المحاولة مرى أخرى!',
+'loginprompt' => 'يجب أن يدعم متصفحك الكوكيز Cookies لتتمكن من الدخول.',
+'loginsuccess' => 'لقد قمت بتسجيل الدخول ل{{SITENAME}} بإسم "$1".',
+'loginsuccesstitle' => 'تم الدخول بشكل صحيح',
+'logout' => 'خروج',
+'logouttext' => 'أنت الآن غير مسجل الدخول للنظام.
+تستطيع المتابعة بإستعمال {{SITENAME}} كمجهول، أو الدخول مرة أخرى بنفس الإسم أو بإسم آخر. من الممكن أن ترى بعض الصفحات في الموسوعة كما وأنك مسجل في النظام.، وذلك بسبب إستعمال الصفحات المخبأة Cache في المنتصفح لديك.',
+'logouttitle' => 'تسجيل الخروج للمستخدم',
+'lonelypages' => 'صفحات يتيمة',
+'longpages' => 'صفحات طويلة',
+'mailmypassword' => 'أرسل لي كلمة السر عبر البريد الإلكتروني.',
+'mailnologin' => 'لا يوجد عنوان للإرسال',
+'minoredit' => 'هذا تعديل طفيف',
+'minoreditletter' => 'ط',
+'moredotdotdot' => 'المزيد...',
+'move' => 'نقل',
+'movearticle' => 'نقل صفحة',
+'movedto' => 'تم نقلها إلى',
+'movelogpage' => 'سجل النقل',
+'movenologin' => 'غير مسجل',
+'movepage' => 'نقل صفحة',
+'movepagebtn' => 'أنقل الصفحة',
+'movepagetalktext' => 'صفحة النقاش المرفقة بالمقالة سيتم نقلها كذلك، إذا وجدت. ولكن لا يتم نقل صفحة النقاش في الحالات التالية:
+* نقل الصفحة عبر نطاقات namespaces مختلفة.
+* يوجد صفحة نقاش غير فارغة تحت العنوان الجديد للمقالة.
+* قمت بإزالة إختيار نقل صفحة النقاش في الأسفل.
+
+وفي الحالات أعلاه، يجب عليك نقل أو دمج محتويات صفحة النقاش يدويا، إذا رغب في ذلك.',
+'movereason' => 'السبب',
+'movetalk' => 'أنقل صفحة \'\'\'النقاش\'\'\' أن أمكن.',
+'movethispage' => 'أنقل هذه الصفحة',
+'mycontris' => 'مساهماتي',
+'mypage' => 'صفحتي',
+'namespace' => 'النطاق:',
+'namespacesall' => 'الكل',
+'navigation' => 'تصفح',
+'nbytes' => '$1 بايت',
+'newarticle' => '(جديد)',
+'newarticletext' => 'لقد تبعت وصلة لصفحة لم يتم إنشائها بعد.
+لإنشاء هذه الصفحة إبدأ بالكتابة في الصندوق بالأسفل.
+(أنظر في [[{{ns:project}}:مساعدة|صفحة المساعدة]] للمزيد من المعلومات)
+إذا كانت زيارتك لهذه الصفحة بالخطأ، إضغم على زر \'\'رجوع\'\' في متصفح الإنترنت لديك.',
+'newimages' => 'معرض الصور الجديدة',
+'newmessageslink' => 'رسائل جديدة',
+'newpage' => 'صفحة جديدة',
+'newpageletter' => 'ج',
+'newpages' => 'صفحات جديدة',
+'newpassword' => 'كلمة السر الجديدة',
+'newtitle' => 'إلى العنوان الجديد',
+'newwindow' => '(يفتح في شباك جديد)',
+'next' => 'التالي',
+'nextn' => '$1 التالية',
+'nlinks' => '$1 وصلة',
+'noarticletext' => '(لا يوجد حاليا أي نص في هذه الصفحة)',
+'noemail' => 'لا يوجد أي عنوان بريدي مسجل للمستخدم "$1".',
+'noemailtext' => 'لم يحدد هذا المستخدم عنوان بريد إلكتروني صحيح،
+أو طلب عدم إستلام الرسائل من المستخدمين الآخرين.',
+'noemailtitle' => 'لا يوجد عنوان بريد إلكتروني',
+'noexactmatch' => 'لا يوجد صفحة بنفس العنوان، حاول البحث بشكل مفصل أكثر من خلال إستعمال صندوق البحث أدناه. بإمكانك أيضاً إنشاء [[:1|صفحة جديدة]] بالعنوان الذي طلبته.',
+'nohistory' => 'لا يوجد تاريخ للتغييرات لهذه الصفحة.',
+'nolinkshere' => 'لا يوجد صفحات تصل لهذه الصفحة.',
+'nolinkstoimage' => 'لا يوجد صفحات تصل لهذه الصورة.',
+'noname' => 'لم تحدد إسم مستخدم صحيح.',
+'nospecialpagetext' => 'لقد طلبت صفحة خاصة لا يمكن التعرف عليها من قبل نظام الويكي.',
+'nosuchspecialpage' => 'لا يوجد صفحة خاصة بهذا الإسم',
+'nosuchuser' => 'لا يوجد مستخدم بالإسم "$1".
+تأكد من إملاء الإسم، أو إستعمل النموذج الموجود في الأسفل لإنشاء مستخدم جديد.',
+'note' => '<strong>ملاحظة:</strong>',
+'notextmatches' => 'لم يتم إيجاد أي نص مطابق',
+'notitlematches' => 'لم يتم إيجاد أي عنوان مطابق',
+'notloggedin' => 'غير مسجل',
+'nowatchlist' => 'لا يوجد شيء في قائمة مراقبتك.',
+'nowiki_tip' => 'أهمل تهيئة الويكي',
+'nstab-category' => 'تصنيف',
+'nstab-help' => 'مساعدة',
+'nstab-image' => 'صورة',
+'nstab-main' => 'مقالة',
+'nstab-mediawiki' => 'رسالة',
+'nstab-special' => 'خاص',
+'nstab-template' => 'قالب',
+'nstab-user' => 'صفحة مستخدم',
+'nstab-project' => 'حول',
+'ok' => 'موافق',
+'oldpassword' => 'كلمة السر القديمة',
+'orig' => 'الأصلي',
+'otherlanguages' => ' لغات أخرى',
+'pagemovedsub' => 'تم النقل بنجاح',
+'pagemovedtext' => 'تم نقل الصفحة "[[$1]]" إلى "[[$2]]".',
+'passwordremindertitle' => 'تذكير بكلمة السر من {{SITENAME}}',
+'passwordsent' => 'تم إرسال كلمة سر جديدة إلى العنوان البريدي المسجل للمستخدم "$1".
+يرجى محاولة تسجيل الدخول مرة أخرى عند إستلامها.',
+'popularpages' => 'الصفحات المشهورة',
+'portal' => 'بوابة المجتمع',
+'portal-url' => '{{ns:project}}:بوابة المجتمع',
+'postcomment' => 'أرسل تعليق',
+'powersearch' => 'بحث',
+'preferences' => 'تفضيلات',
+'prefsnologin' => 'غير مسجل',
+'preview' => 'عرض مسبق',
+'previewnote' => 'تذكر، هذا فقط عرض مسبق للصفحة، ولم يتم حفظه بعد!',
+'prevn' => '$1 السابقة',
+'printableversion' => 'نسخة للطباعة',
+'protectcomment' => 'سبب الحماية',
+'protectedarticle' => 'حماية [[$1]]',
+'protectedpage' => 'صفحة محمية',
+'protectlogpage' => 'سجل_الحماية',
+'protectthispage' => 'حماية هذه الصفحة',
+'qbbrowse' => 'تصفح',
+'qbedit' => 'تحرير',
+'qbfind' => 'بحث',
+'qbmyoptions' => 'صفحاتي',
+'qbpageinfo' => 'سياق النص',
+'qbpageoptions' => 'هذه الصفحة',
+'qbsettings' => 'خيارات لوحة الوصلات',
+'qbspecialpages' => 'الصفحات الخاصّة',
+'randompage' => 'صفحة عشوائية',
+'rclinks' => 'أظهر آخر $1 تعديل في آخر $2 يوم، $3',
+'rclistfrom' => 'أظهر التغييرات بدأ من $1',
+'rclsub' => '(لصفحات تصل بها الصفحة "$1")',
+'rcnote' => 'في الأسفل ستجد آخر <strong>$1</strong> تعديل في آخر <strong>$2</strong> أيام.',
+'rcnotefrom' => 'في الأسفل التغييرات منذ <b>$2</b> (ولغاية <b>$1</b>).',
+'readonly' => 'قاعدة البيانات مغلقة',
+'readonlytext' => 'قاعدة البيانات مغلقة حاليا أمام الإضافات والتعديلات، السبب غالبا ما يكون الصيانة، وستعود قاعدة البيانات للوضع الطبيعي قريبا.
+عندما تم أغلاق قاعدة البيانات أمام التعديلات والإضافات تم أعطاء ال