Wiktionary
viwiktionary
https://vi.wiktionary.org/wiki/Wiktionary:Trang_Ch%C3%ADnh
MediaWiki 1.47.0-wmf.15
case-sensitive
Phương tiện
Đặc biệt
Thảo luận
Thành viên
Thảo luận Thành viên
Wiktionary
Thảo luận Wiktionary
Tập tin
Thảo luận Tập tin
MediaWiki
Thảo luận MediaWiki
Bản mẫu
Thảo luận Bản mẫu
Trợ giúp
Thảo luận Trợ giúp
Thể loại
Thảo luận Thể loại
Phụ lục
Thảo luận Phụ lục
TimedText
TimedText talk
Mô đun
Thảo luận Mô đun
Event
Event talk
космология
0
76852
2514195
1962534
2026-08-15T11:56:48Z
Kelly zhrm
58416
2514195
wikitext
text/x-wiki
{{also|космологія}}
=={{langname|bg}}==
{{wp|bg:}}
==={{ĐM|etym}}===
{{internationalism|bg}}, cuối cùng từ {{der+|bg|grc|nocap=1|κόσμος}} + {{m|grc|-λογία}}. {{surf|bg|ко́смо-|-ло́гия}}.
==={{ĐM|pron}}===
{{bg-pr|космоло́гия|a=[KK]}}
==={{ĐM|n}}===
{{bg-noun|космоло́гия|f|adj=космологи́чески}} {{tlb|bg|singular only}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|decl}}====
{{bg-ndecl|космоло́гия</n:sg>}}
==={{ĐM|ref}}===
* {{R:bg:RBE}}
* {{R:bg:RBE2}}
{{C|bg|Vũ trụ học}}
=={{langname|ru}}==
{{wp|ru:}}
==={{ĐM|pron}}===
* {{ru-IPA|космоло́гия}}
==={{ĐM|n}}===
{{ru-noun+|космоло́гия|adj=космологи́ческий}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|decl}}====
{{ru-noun-table|космоло́гия}}
==={{ĐM|ref}}===
{{R:FVDP|db=rv}}
{{topics|ru|Vũ trụ học}}
5x915cww3lz09ajdt76azowb0mz6xcq
2514196
2514195
2026-08-15T11:57:08Z
Kelly zhrm
58416
2514196
wikitext
text/x-wiki
{{also|космологія}}
=={{langname|bg}}==
{{wp|bg:}}
==={{ĐM|etym}}===
{{internationalism|bg}}, cuối cùng từ {{der+|bg|grc|nocap=1|κόσμος}} + {{m|grc|-λογία}}. {{surf|bg|ко́смо-|-ло́гия}}.
==={{ĐM|pron}}===
{{bg-pr|космоло́гия|a=[KK]}}
==={{ĐM|n}}===
{{bg-noun|космоло́гия|f|adj=космологи́чески}} {{tlb|bg|chỉ số ít}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|decl}}====
{{bg-ndecl|космоло́гия</n:sg>}}
==={{ĐM|ref}}===
* {{R:bg:RBE}}
* {{R:bg:RBE2}}
{{C|bg|Vũ trụ học}}
=={{langname|ru}}==
{{wp|ru:}}
==={{ĐM|pron}}===
* {{ru-IPA|космоло́гия}}
==={{ĐM|n}}===
{{ru-noun+|космоло́гия|adj=космологи́ческий}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|decl}}====
{{ru-noun-table|космоло́гия}}
==={{ĐM|ref}}===
{{R:FVDP|db=rv}}
{{topics|ru|Vũ trụ học}}
cpi3mkh9d1de87tcxoob6kz9c0fnzlp
水
0
214859
2514095
2428600
2026-08-15T03:33:50Z
WhoAlone
40420
2514095
wikitext
text/x-wiki
{{zho-prefix}}
{{-Hani-}}
{{character info}}
{{character info|⽔}}
{{zho-so}}
* {{hanviet|[[thủy]]}}
* {{zh-sn|4}}
* {{zh-rad|水|0}}
* {{unihan|6C34}}
{{-etymology-}}
{{zho-etym}}
=={{langname|lay}}==
==={{ĐM|pron}}===
* {{IPA4|lay|/ɕy³³/}}
==={{ĐM|noun}}===
{{head|lay|Danh từ}}
# [[nước]].
{{c|lay|Nước}}
=={{langname|bfs}}==
==={{ĐM|noun}}===
{{head|bfs|Danh từ|tr=[[xuix]]}}
# [[nước]].
{{c|bfs|Nước}}
=={{langname|bca}}==
==={{ĐM|noun}}===
{{head|bca|Danh từ|tr=[[xuix]]}}
# [[nước]].
{{c|bca|Nước}}
=={{langname|jpx-hcj}}==
==={{ĐM|Kanji}}===
{{jpx-hcj-kanji}}
==={{ĐM|etym}}===
Cùng gốc với {{cog|ja|頭|tr=mizu}}.
==={{ĐM|noun}}===
{{jpx-hcj-head|noun|みづ}}
# [[nước]].
{{C|jpx-hcj|Nước}}
{{-cmn-}}
[[Hình:Stilles Mineralwasser.jpg|nhỏ|phải|水]]
{{-pron-}}
* [[Wiktionary:Bính âm|Bính âm]]: shuǐ (shui<sup>3</sup>)
* [[Wiktionary:Wade-Giles|Wade–Giles]]: shui<sup>3</sup>
{{-noun-}}
'''水'''
# [[nước|Nước]], [[chất lỏng]] có [[công thức]] [[hoá học]] [[hiđrô|H]]<sub>2</sub>[[ôxy|O]], cần cho [[sự sống]].
#: [[不]][[透]]'''水''' – không thấm nước
# [[sông|Sông]], [[suối]].
#: [[寄]][[情]][[山]]'''水''' – thả mình vào giữa chốn nước non
#: [[千]][[山]][[萬]]'''水''' – xa cách nghìn núi nghìn sông
# [[chất lỏng|Chất lỏng]], [[rượu]], [[nước]] [[trái cây]].
#: [[桔]][[子]]'''水''' – nước [[cam]]
#: [[淚]]'''水''' – nước mắt
{{zh-forms|alt=𡿭,𣸕}}
{{-syn-}}
* [[氵]]
{{-trans-}}
; nước
{{đầu}}
* {{eng}}: [[water]]
{{giữa}}
* {{spa}}: [[agua]] {{g-old|f}}
{{cuối}}
; sông, suối
{{đầu}}
* {{eng}}: [[river]]; [[stream]]
{{giữa}}
* {{spa}}: [[río]] {{g-old|m}}
{{cuối}}
; chất lỏng
{{đầu}}
* {{eng}}: [[liquid]]
{{giữa}}
* {{spa}}: [[líquido]] {{g-old|m}}
{{cuối}}
{{-adj-}}
'''水'''
# Có [[tính chất]] [[nước]].
## theo [[đường]] [[sông]], [[đường biển]]
##: '''水'''[[程]] – đi đường biển
## dùng [[nước]]
##: '''水'''[[稻]] – lúa nước
# Có [[tính]] [[lỏng]].
#: '''水'''[[动]][[力]][[学]] – [[thủy động lực học]]
{{-trans-}}
; có tính chất nước
{{đầu}}
* {{eng}}: [[aquatic]]
{{giữa}}
* {{spa}}: [[acuático]] {{g-old|m}}, [[acuática]] {{g-old|f}}
{{cuối}}
; tính lỏng
{{đầu}}
* {{eng}}: [[hydro-]]
{{giữa}}
* {{spa}}: [[hidro-]]
{{cuối}}
{{-ref-}}
{{R:Unihan}}
{{R:Thiều Chửu}}
{{-vie-n-}}
{{quốc ngữ|[[nước]], [[thủy]]}}
{{-pron-}}
{{vie-pron|nước|thuỷ}}
[[Thể loại:Danh từ tiếng Quan Thoại]]
[[Thể loại:Tính từ tiếng Quan Thoại]]
c41j9yga4gcrl76nilycxcbeisbweke
anno
0
249996
2514183
1991754
2026-08-15T10:07:18Z
Kelly zhrm
58416
2514183
wikitext
text/x-wiki
=={{langname|it}}==
{{wp|it:}}
==={{ĐM|etym}}===
{{inh+|it|la|annus}}, từ {{inh|it|itc-pro|*atnos}}, từ {{der|it|ine-pro|*h₂et-no-}}, có lẽ là từ {{m|ine-pro|*h₂et-|t=đi}}.
==={{ĐM|pron}}===
{{it-pr|ànno<audio:it-anno.ogg><hmp:hanno>}}
==={{ĐM|n}}===
{{it-noun|m|dim=annetto}}
# [[năm|Năm]].
# [[tuổi|Tuổi]].
===={{ĐM|drv}}====
{{col4|it|anni di piombo|anni ruggenti|anno bisestile|anno fiscale|anno giuliano|anno luce|anno lunare|anno sabbatico|Anno Santo|anno scolastico|anno solare|anno tropico|anno zero|anno-uomo|buon anno|capodanno|compiere gli anni|compleanno|malanno|sopranno}}
===={{ĐM|rel}}====
{{col4|it|annale|annali|annata|annecchia|annecchio|anniversario|annona|annoso|annotino|annuale|annuo|annualmente|annualità|annuario|annutolo|biennale|bienne|biennio|centennale|centennio|decennale|decennio|-enne|-ennio|millennio|nicchio|novennale|novennio|ottennale|ottennio|perenne|quadriennale|quadriennio|quinquennale|quinquennio|uguanno|sessennale|sessennio|settennale|settennio|solenne|triennale|triennio|ventennale|Ventennio|ventennio|vicennale|vicennio}}
===={{ĐM|see}}====
* {{l|it|decade|dècade}}
* {{l|it|giorno}}
* {{l|it|mese}}, {{l|it|-mestre}}
* {{l|it|secolo}}, {{l|it|centuria}}
* {{l|it|settimana}}
* {{l|it|lustro}}
==={{ĐM|v}}===
{{head|it|Từ sai chính tả}}
# {{misspelling of|it|hanno}}
==={{ĐM|ana}}===
* {{anagrams|it|a=anno|Nona|nano|nano-|nona}}
{{C|it|Thời gian}}
n1ge6c70wocvn1lihfad52is3qi5fwy
niveau de la mer
0
256920
2514190
2501224
2026-08-15T11:21:32Z
Kelly zhrm
58416
2514190
wikitext
text/x-wiki
=={{langname|fr}}==
{{wp|fr:}}
==={{ĐM|pron}}===
* {{fr-IPA}}
==={{ĐM|n}}===
{{fr-noun|m|-}}
# [[mực|Mực]] [[nước biển]].
09k2gqlnwwr11ejdkkpm8cj7sj3nwkf
nature morte
0
257965
2514189
2500554
2026-08-15T11:18:45Z
Kelly zhrm
58416
2514189
wikitext
text/x-wiki
=={{langname|en}}==
[[Image:Raphaelle Peale - Blackberries (c.1813).jpg|thumb|250px|a nature morte]]
==={{ĐM|etym}}===
Vay mượn từ {{bor|en|fr|nature morte|lit=thiên nhiên chết}}.
==={{ĐM|n}}===
{{en-noun|natures mortes|nolink=1}}
# [[tranh|Tranh]] [[tĩnh vật]].
=={{langname|fr}}==
{{wp|fr:}}
==={{ĐM|etym}}===
{{literally|thiên nhiên chết}}.
==={{ĐM|pron}}===
* {{fr-IPA}}
* {{audio|fr|LL-Q150 (fra)-WikiLucas00-nature morte.wav|a=Lyon}}
* {{audio|fr|LL-Q150 (fra)-DSwissK-nature morte.wav|a=Valais}}
==={{ĐM|n}}===
{{fr-noun|f}}
# [[tranh|Tranh]] [[tĩnh vật]].
===={{ĐM|desc}}====
* {{desc|az|natürmort|bor=1}}
* {{desc|bg|натюрмо́рт|bor=1}}
* {{desc|ca|natura morta|clq=1}}
* {{desc|en|nature morte|bor=1}}
* {{desc|et|natüürmort|bor=1}}
* {{desc|ka|ნატურმორტი|bor=1}}
* {{desctree|ru|натюрмо́рт|bor=1}}
* {{desc|tr|natürmort|bor=1}}
==={{ĐM|further}}===
* {{R:fr:TLFi}}
==={{ĐM|ana}}===
* {{l|fr|tourmentera}}
=={{langname|it}}==
==={{ĐM|n}}===
{{head|it|Biến thể hình thái danh từ|g=f}}
# {{plural of|it|natura morta}}
fdhy5rs3qkwl5ego6pfl2tzdzup7c1d
segatura
0
258752
2514187
2043350
2026-08-15T11:08:07Z
Kelly zhrm
58416
2514187
wikitext
text/x-wiki
=={{langname|it}}==
==={{ĐM|etym}}===
{{ety|it|:af|segare|-tura}}
Từ {{affix|it|segare|-tura}}.
==={{ĐM|pron}}===
{{it-pr}}
==={{ĐM|n}}===
{{it-noun|f}}
# [[mạt cưa|Mạt cưa]], [[mùn cưa]].
===={{ĐM|rel}}====
* {{l|it|sega}}
==={{ĐM|further}}===
* {{R:it:Treccani}}
==={{ĐM|ana}}===
* {{anagrams|it|a=aaegrstu|aguraste|guastare|guasterà}}
dl701m9hmurolsny6hsz0v5e9nawtg0
†
0
260146
2514184
2127969
2026-08-15T10:58:48Z
TheHighFighter2
42988
2514184
wikitext
text/x-wiki
{{also|✝|✞|✟|‡|⸶|⸷|⸸|⹋|𐘁|𒾓|uni=auto}}
{{character info}}
=={{langname|mul}}==
==={{ĐM|symbol}}===
{{mul-symbol}}
# [[chết|Chết]], [[mất]].
#: {{syn|mul|🌈<q:từ lóng internet, dùng cho thú cưng>}}
#: {{ux|mul|Joseph Smith, '''†'''1956|Joseph Smith, '''mất''' năm 1956}}
# {{lb|mul|typography}} Đánh dấu [[cước chú]] thứ hai.
#: {{coord|mul|*|‡|⹋}}
# {{lb|mul|sinh học|ngôn ngữ học}} [[tuyệt chủng|Tuyệt chủng]].
# {{lb|mul|ký hiệu|_|cờ vua}} [[chiếu|Chiếu]].
#: {{syn|mul|+}}
{{C|mul|Chết}}
[[Thể loại:Khối ký tự General Punctuation|20]]
8o6kh1n066kh5se69lvxpsfppq9f4mw
cosmologia
0
261211
2514192
2458898
2026-08-15T11:46:45Z
Kelly zhrm
58416
2514192
wikitext
text/x-wiki
{{also|cosmología}}
=={{langname|pt}}==
==={{ĐM|pron}}===
{{pt-IPA}}
* {{hyph|pt|cos|mo|lo|gi|a}}
==={{ĐM|n}}===
{{pt-noun|f|-,+}}
# [[vũ trụ học|Vũ trụ học]].
==={{ĐM|further}}===
* {{R:pt:Aulete}}
* {{R:pt:Priberam}}
=={{langname|ca}}==
==={{ĐM|etym}}===
Từ {{confix|ca|cosmo|logia}}.
==={{ĐM|pron}}===
* {{ca-IPA}}
* {{audio|ca|LL-Q7026 (cat)-Marvives-cosmologia.wav|a=Barcelona}}
==={{ĐM|n}}===
{{ca-noun|f}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|drv}}====
* {{l|ca|cosmològic}}
===={{ĐM|rel}}====
* {{l|ca|cosmos}}
* {{l|ca|cosmòleg}}
{{C|ca|Khoa học}}
=={{langname|la}}==
{{wp|la:}}
==={{ĐM|etym}}===
Tiếng Tân Latinh, từ {{suffix|la|κόσμος|lang1=grc|logia|alt2=-ologia}}.
==={{ĐM|pron}}===
* {{la-IPA|cosmologia}}
==={{ĐM|n}}===
{{la-noun|cosmologia<1>}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|decl}}====
{{la-ndecl|cosmologia<1>}}
==={{ĐM|ref}}===
* {{R:la:NLW}}
=={{langname|it}}==
{{wp|it:}}
==={{ĐM|etym}}===
Từ {{confix|it|cosmo|logia}}.
==={{ĐM|pron}}===
* {{rhymes|it|ia|s=5}}
{{it-pr}}
==={{ĐM|n}}===
{{it-noun|f|cosmologie}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|rel}}====
* {{l|it|cosmo}}
* {{l|it|cosmologico}}
* {{l|it|cosmologo}}
hesx0wzqpqkf1jdmqz8dxnuaxrvcq47
2514193
2514192
2026-08-15T11:50:37Z
Kelly zhrm
58416
/* {{ĐM|etym}} */
2514193
wikitext
text/x-wiki
{{also|cosmología}}
=={{langname|pt}}==
==={{ĐM|pron}}===
{{pt-IPA}}
* {{hyph|pt|cos|mo|lo|gi|a}}
==={{ĐM|n}}===
{{pt-noun|f|-,+}}
# [[vũ trụ học|Vũ trụ học]].
==={{ĐM|further}}===
* {{R:pt:Aulete}}
* {{R:pt:Priberam}}
=={{langname|ca}}==
==={{ĐM|etym}}===
Từ {{confix|ca|cosmo|logia}}.
==={{ĐM|pron}}===
* {{ca-IPA}}
* {{audio|ca|LL-Q7026 (cat)-Marvives-cosmologia.wav|a=Barcelona}}
==={{ĐM|n}}===
{{ca-noun|f}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|drv}}====
* {{l|ca|cosmològic}}
===={{ĐM|rel}}====
* {{l|ca|cosmos}}
* {{l|ca|cosmòleg}}
{{C|ca|Khoa học}}
=={{langname|la}}==
{{wp|la:}}
==={{ĐM|etym}}===
Tiếng Latinh Tân thời, từ {{suffix|la|κόσμος|lang1=grc|logia|alt2=-ologia}}.
==={{ĐM|pron}}===
* {{la-IPA|cosmologia}}
==={{ĐM|n}}===
{{la-noun|cosmologia<1>}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|decl}}====
{{la-ndecl|cosmologia<1>}}
==={{ĐM|ref}}===
* {{R:la:NLW}}
=={{langname|it}}==
{{wp|it:}}
==={{ĐM|etym}}===
Từ {{confix|it|cosmo|logia}}.
==={{ĐM|pron}}===
* {{rhymes|it|ia|s=5}}
{{it-pr}}
==={{ĐM|n}}===
{{it-noun|f|cosmologie}}
# [[vũ trụ học|Vũ trụ học]].
===={{ĐM|rel}}====
* {{l|it|cosmo}}
* {{l|it|cosmologico}}
* {{l|it|cosmologo}}
19p27gw05sqez3ejcj4w4479f2ff1o1
သိူဝ်
0
261789
2514038
2039680
2026-08-14T12:40:39Z
Kelly zhrm
58416
2514038
wikitext
text/x-wiki
=={{langname|shn}}==
==={{ĐM|etym}}===
Từ {{inh|shn|tai-swe-pro|*sɯəᴬ||hổ}}. Cùng gốc với {{cog|th|เสือ}}, {{cog|nod|ᩈᩮᩬᩥᩋ}}, {{cog|lo|ເສືອ}}, {{cog|kkh|ᩈᩮᩬᩧ}}, {{cog|khb|ᦵᦉᦲ}}, {{cog|blt|ꪹꪎ}}, {{cog|tdd|ᥔᥫᥴ}}, {{cog|aio|ꩬိုဝ်}}, {{cog|aho|𑜏𑜢𑜤𑜈𑜫}} hoặc {{m|aho|𑜏𑜢𑜤𑜰𑜫}}.
==={{ĐM|pron}}===
{{shn-pron}}
==={{ĐM|n}}===
{{shn-noun|တူဝ်}}
# Con [[hổ]].
{{c|shn|Họ Mèo}}
diaf6gryoj3d7r9dea05zhhyzg9738p
ဢႃႇပေႃႇ
0
261793
2514042
2039703
2026-08-14T12:55:17Z
Kelly zhrm
58416
2514042
wikitext
text/x-wiki
=={{langname|shn}}==
==={{ĐM|etym}}===
{{bor+|shn|pi|āpo}}. Cùng gốc với {{cog|my|အာပေါ}}.
==={{ĐM|pron}}===
{{shn-pron|ဢႃႇ-ပေႃႇ}}
==={{ĐM|n}}===
{{shn-noun}}
# [[nước|Nước]].
s17oeo49f7ewnlynjpcuju4p9o01o23
∀
0
264145
2514065
2127981
2026-08-14T15:13:41Z
TheHighFighter2
42988
2514065
wikitext
text/x-wiki
{{also|Ɐ|Phụ lục:Biến thể của "a"}}
{{character info}}
=={{langname|mul}}==
==={{ĐM|description}}===
Chữ [[A]] in hoa bị lộn ngược.
==={{ĐM|symbol}}===
{{head|mul|symbol}}
# {{nhãn|mul|toán học|logic}} [[ký hiệu|Ký hiệu]] có nghĩa "với mọi".
#: {{ux|mul|x - x {{=}} 0, '''∀'''x|x trừ x bằng 0 với mọi x.}}
==={{ĐM|see also}}===
* {{l|mul|∃}}
[[Thể loại:Khối ký tự Mathematical Operators|00]]
4j4org66m0ktmz75lydponi632miflt
Mô đun:languages/data/3/c
828
272284
2514031
2480105
2026-08-14T12:16:06Z
Lcsnes
40261
2514031
Scribunto
text/plain
local m_langdata = require("Module:languages/data")
-- Loaded on demand, as it may not be needed (depending on the data).
local function u(...)
u = require("Module:string utilities").char
return u(...)
end
local c = m_langdata.chars
local p = m_langdata.puaChars
local s = m_langdata.shared
local m = {}
m["caa"] = {
"tiếng Ch'orti'",
35177,
"myn",
"Latn",
"Tiếng Ch'orti'",
"Ch'orti'",
}
m["cab"] = {
"tiếng Garifuna",
35490,
"awd-taa",
"Latn",
"Tiếng Garifuna",
"Garifuna",
ancestors = "crb",
}
m["cac"] = {
"Chuj",
35233,
"myn",
"Latn",
}
m["cad"] = {
"Caddo",
56756,
"cdd",
"Latn",
}
m["cae"] = {
"tiếng Laalaa",
35564,
"alv-cng",
"Latn",
"Tiếng Laalaa",
"Laalaa",
}
m["caf"] = {
"tiếng Carrier Nam",
12953426,
"ath-nor",
"Latn, Cans",
"Tiếng Carrier Nam",
"Carrier Nam",
}
m["cag"] = {
"tiếng Nivaclé",
3182557,
"sai-mtc",
"Latn",
"Tiếng Nivaclé",
"Nivaclé",
}
m["cah"] = {
"Cahuarano",
2933175,
"sai-zap",
"Latn",
}
m["caj"] = {
"Chané",
56721,
"awd",
"Latn",
}
m["cak"] = {
"tiếng Kaqchikel",
35115,
"myn",
"Latn",
"Tiếng Kaqchikel",
"Kaqchikel",
}
m["cal"] = {
"Carolinian",
28427,
"poz-mic",
"Latn",
}
m["cam"] = {
"Cemuhî",
3009690,
"poz-cln",
"Latn",
}
m["can"] = {
"Chambri",
5069707,
"paa-lsp",
"Latn",
}
m["cao"] = {
"Chácobo",
2591202,
"sai-pan",
"Latn",
}
m["cap"] = {
"Chipaya",
35235,
"sai-ucp",
"Latn",
}
m["caq"] = {
"tiếng Nicobar Car",
35156,
"aav-nic",
"Latn, Deva",
"Tiếng Nicobar Car",
"Nicobar Car",
}
m["car"] = {
"tiếng Kari'na",
56611,
"sai-gui",
"Latn",
"Tiếng Kari'na",
"Kari'na",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. "`" .. "'%-%s"},
entry_name = {
remove_diacritics = c.acute,
from = {"â", "ê", "î", "ô", "û", "ŷ"},
to = {"à", "è", "ì", "ò", "ù", "ỳ"}
},
}
m["cas"] = {
"Tsimané",
35950,
"qfa-iso",
"Latn",
}
m["cav"] = {
"Cavineña",
524102,
"sai-tac",
"Latn",
}
m["caw"] = {
"Callawalla",
266417,
"qfa-mix",
"Latn",
}
m["cax"] = {
"Chiquitano",
1844993,
"qfa-iso",
"Latn",
}
m["cay"] = {
"tiếng Cayuga",
32967,
"iro-nor",
"Latn",
"Tiếng Cayuga",
"Cayuga",
}
m["caz"] = {
"Canichana",
2936374,
"qfa-iso",
"Latn",
}
m["cbb"] = {
"Cabiyarí",
3450660,
"awd-nwk",
"Latn",
}
m["cbc"] = {
"Carapana",
924405,
"sai-tuc",
"Latn",
}
m["cbd"] = {
"Carijona",
3446655,
"sai-tar",
"Latn",
}
m["cbg"] = {
"Chimila",
2963680,
"cba",
"Latn",
}
m["cbi"] = {
"tiếng Chachi",
2591329,
"sai-bar",
"Latn",
"Tiếng Chachi",
"Chachi",
}
m["cbj"] = {
"Ede Cabe",
33112829,
"alv-ede",
"Latn",
}
m["cbk"] = {
"tiếng Chavacano",
33281,
"crp",
"Latn",
"Tiếng Chavacano",
"Chavacano",
ancestors = "es",
entry_name = {Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer}},
sort_key = {
Latn = {
from = {"ch", "ll", "ñ", "r"},
to = {"c" .. p[1], "l" .. p[1], "n" .. p[1], "r" .. p[1]}
},
},
standardChars = {
Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnÑñOoPpQqRrSsTtUuVvWwXxYyZz",
c.punc
},
}
m["cbl"] = {
"Bualkhaw Chin",
9229830,
"tbq-kuk",
"Latn",
}
m["cbn"] = {
"tiếng Nyah Kur",
116849,
"mkh-mnc",
"Thai",
"Tiếng Nyah Kur",
"Nyah Kur",
ancestors = "omx",
sort_key = "Thai-sortkey",
}
m["cbo"] = {
"Izora",
3915454,
"nic-jer",
"Latn",
}
m["cbq"] = {
"Shuba",
nil,
"nic-knj",
"Latn",
ancestors = "lan",
}
m["cbr"] = {
"Cashibo-Cacataibo",
5359560,
"sai-pan",
"Latn",
}
m["cbs"] = {
"Cashinahua",
2591230,
"sai-pan",
"Latn",
}
m["cbt"] = {
"Chayahuita",
1526525,
"sai-cah",
"Latn",
}
m["cbu"] = {
"Candoshi-Shapra",
642843,
"qfa-iso",
"Latn",
}
m["cbv"] = {
"Cacua",
3192052,
"sai-nad",
"Latn",
ancestors = "mbr",
}
m["cbw"] = {
"Kinabalian",
6410324,
"phi",
"Latn",
}
m["cby"] = {
"Carabayo",
3441762,
"sai-tyu",
"Latn",
}
m["cca"] = {
"Cauca",
5054242,
"sai-chc",
"Latn",
}
m["ccc"] = {
"tiếng Chamicuro",
2155119,
"awd",
"Latn",
"Tiếng Chamicuro",
"Chamicuro",
}
m["ccd"] = {
"Cafundó",
3331506,
"roa-ibe",
"Latn",
ancestors = "pt",
}
m["cce"] = {
"Chopi",
3437616,
"bnt-bso",
"Latn",
}
m["ccg"] = {
"Chamba Daka",
33120805,
"nic-dak",
"Latn",
}
m["cch"] = {
"Atsam",
34794,
"nic-kne",
"Latn",
}
m["ccj"] = {
"Kasanga",
35542,
"alv-nyn",
"Latn",
}
m["ccl"] = {
"Cutchi-Swahili",
5196729,
"crp",
"Latn",
ancestors = "sw",
}
m["ccm"] = {
"Malaccan Creole Malay",
12636092,
"crp",
"Latn",
ancestors = "ms",
}
m["cco"] = {
"Comaltepec Chinantec",
2963735,
"omq-chi",
"Latn",
}
m["ccp"] = {
"tiếng Chakma",
32952,
"inc-eas",
"Cakm, Beng, Latn",
"Tiếng Chakma",
"Chakma",
ancestors = "inc-obn",
translit = {
Cakm = "Cakm-translit",
--Beng = "Beng-translit",
},
}
m["ccr"] = {
"Cacaopera",
3438338,
"nai-min",
"Latn",
}
m["cda"] = {
"tiếng Trác Ni",
2964447,
"sit-tib",
"Tibt",
"Tiếng Trác Ni",
"Trác Ni",
translit = "Tibt-translit",
override_translit = true,
display_text = s["Tibt-displaytext"],
entry_name = s["Tibt-entryname"],
sort_key = "Tibt-sortkey",
}
m["cde"] = {
"tiếng Chenchu",
32981,
"dra-tel",
"Telu",
"Tiếng Chenchu",
"Chenchu",
translit = "te-translit",
}
m["cdf"] = {
"tiếng Chiru",
5102016,
"tbq-kuk",
"Latn, Beng",
"Tiếng Chiru",
"Chiru",
}
m["cdh"] = {
"tiếng Chamba",
12953424,
"him",
"Deva, Takr",
"Tiếng Chamba",
"Chamba",
translit = {Deva = "hi-translit"},
}
m["cdi"] = {
"tiếng Chodri",
5103788,
"inc-bhi",
"Gujr",
"Tiếng Chodri",
"Chodri",
}
m["cdj"] = {
"tiếng Churah",
12629039,
"him",
"Deva, Takr",
"Tiếng Churah",
"Churah",
translit = {Deva = "hi-translit"},
}
m["cdm"] = {
"tiếng Chepang",
5091700,
"sit-gma",
"Deva",
"Tiếng Chepang",
"Chepang",
}
m["cdn"] = {
"Chaudangsi",
5088056,
"sit-alm",
}
m["cdo"] = {
"tiếng Mân Đông",
36455,
"zhx-com",
"Hants",
"Tiếng Mân Đông",
"Mân Đông",
generate_forms = "zh-generateforms",
translit = "zh-translit",
sort_key = "Hani-sortkey",
}
m["cdr"] = {
"Cinda-Regi-Tiyal",
35596,
"nic-kmk",
"Latn",
}
m["cds"] = {
"Chadian Sign Language",
10322099,
"sgn",
"Latn", -- when documented
}
m["cdy"] = {
"tiếng Trà Động",
926742,
"qfa-kms",
}
m["cdz"] = {
"tiếng Koda",
6425038,
"mun",
"Beng",
"Tiếng Koda",
"Koda",
}
m["cea"] = {
"Lower Chehalis",
6693377,
"sal",
"Latn",
}
m["ceb"] = {
"tiếng Cebu",
33239,
"phi",
"Latn, Tglg",
"Tiếng Cebu",
"Cebu",
translit = {
Tglg = "ceb-translit"
},
override_translit = true,
entry_name = {
Latn = {
remove_diacritics = c.grave .. c.acute .. c.circ
}
},
standardChars = {
Latn = "AaBbKkDdEeGgHhIiLlMmNnOoPpRrSsTtUuWwYy",
c.punc
},
sort_key = {Latn = "tl-sortkey"},
}
m["ceg"] = {
"Chamacoco",
3436637,
"sai-zam",
"Latn",
}
m["cen"] = {
"Cen",
12628777,
"nic-plc",
"Latn",
ancestors = "izr",
}
m["cet"] = {
"Centúúm",
33608,
"qfa-iso",
"Latn",
}
m["cfa"] = {
"Dijim-Bwilim",
3438350,
"alv-wjk",
"Latn",
}
m["cey"] = {
"tiếng Chin Ekai",
62603115,
"tbq-kuk",
"Mymr",
"Tiếng Chin Ekai",
"Chin Ekai",
}
m["cfd"] = {
"Cara",
35048,
"nic-beo",
"Latn",
}
m["cfg"] = {
"Como Karim",
35304,
"nic-jkn",
"Latn",
}
m["cfm"] = {
"tiếng Chin Falam",
56815,
"tbq-kuk",
"Beng, Latn",
"Tiếng Chin Falam",
"Chin Falam",
}
m["cga"] = {
"Changriwa",
5072105,
"paa-yua",
"Latn",
}
m["cgc"] = {
"tiếng Kagayanen",
6346422,
"mno",
"Latn",
"Tiếng Kagayanen",
"Kagayanen",
}
m["cgg"] = {
"Rukiga",
3270727,
"bnt-nyg",
"Latn",
}
m["cgk"] = {
"tiếng Chocangacakha",
56604,
"sit-tib",
"Tibt",
"Tiếng Chocangacakha",
"Chocangacakha",
ancestors = "xct",
translit = "Tibt-translit",
override_translit = true,
display_text = s["Tibt-displaytext"],
entry_name = s["Tibt-entryname"],
sort_key = "Tibt-sortkey",
}
m["chb"] = {
"tiếng Chibcha",
2356431,
"cba",
nil,
"Tiếng Chibcha",
"Chibcha",
}
m["chc"] = {
"tiếng Catawba",
5051602,
"nai-cat",
"Latn",
"Tiếng Catawba",
"Catawba",
}
m["chd"] = {
"Highland Oaxaca Chontal",
2964457,
"nai-tqn",
"Latn",
}
m["chf"] = {
"Tabasco Chontal",
35175,
"myn",
"Latn",
}
m["chg"] = {
"tiếng Chagatai",
36831,
"trk-kar",
"Arab",
"Tiếng Chagatai",
"Chagatai",
ancestors = "zkh",
entry_name = {
remove_diacritics = c.kashida .. c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef,
from = {u(0x0671)},
to = {u(0x0627)}
},
}
m["chh"] = {
"tiếng Chinook",
6693380,
"nai-ckn",
"Latn",
"Tiếng Chinook",
"Chinook",
}
m["chj"] = {
"tiếng Chinantec Ojitlán",
5100110,
"omq-chi",
"Latn",
"Tiếng Chinantec Ojitlán",
"Chinantec Ojitlán",
}
m["chk"] = {
"tiếng Chuuk",
33161,
"poz-mic",
"Latn",
"Tiếng Chuuk",
"Chuuk",
}
m["chl"] = {
"tiếng Cahuilla",
56438,
"azc-cup",
"Latn",
"Tiếng Cahuilla",
"Cahuilla",
entry_name = {remove_diacritics = c.acute .. c.macron},
}
-- chm "Mari" is not recognized as a language, but it is a family code
m["chn"] = {
"biệt ngữ Chinook",
35173,
"crp",
"Latn, Dupl",
"Biệt ngữ Chinook",
"biệt ngữ Chinook",
ancestors = "chh, nuk",
}
m["cho"] = {
"tiếng Choctaw",
32979,
"nai-mus",
"Latn",
"Tiếng Choctaw",
"Choctaw",
sort_key = {remove_diacritics = c.macronbelow .. "-"},
entry_name = {remove_diacritics = c.acute .. c.dotbelow},
}
m["chp"] = {
"tiếng Denesuline",
27692,
"ath-nor",
"Latn, Cans",
"Tiếng Denesuline",
"Denesuline",
}
m["chq"] = {
"Quiotepec Chinantec",
5758709,
"omq-chi",
"Latn",
}
m["chr"] = {
"tiếng Cherokee",
33388,
"iro",
"Cher",
"Tiếng Cherokee",
"Cherokee",
translit = "Cher-translit",
}
m["cht"] = {
"Cholón",
2591243,
nil,
"Latn",
}
m["chw"] = {
"Chuabo",
5118412,
"bnt-mak",
"Latn",
}
m["chx"] = {
"tiếng Chantyal",
4926344,
"sit-tam",
"Deva",
"Tiếng Chantyal",
"Chantyal",
}
m["chy"] = {
"tiếng Cheyenne",
33265,
"alg",
"Latn",
"Tiếng Cheyenne",
"Cheyenne",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.macron .. c.dotabove .. "-"},
standardChars = "AaÁáÀàĀāȦȧEeÉéÈèĒēĖėHhKkMmNnOoÓóÒòŌōȮȯPpSsŠšTtVvXx" .. c.punc, --umlaut and circumflex not allowed
}
m["chz"] = {
"tiếng Chinantec Ozumacín",
5100111,
"omq-chi",
"Latn",
"Tiếng Chinantec Ozumacín",
"Chinantec Ozumacín",
entry_name = {remove_diacritics = "ˈˊˉꜗꜘꜙꜚ˜ˋ"},
}
m["cia"] = {
"tiếng Cia-Cia",
35284,
"poz-mun",
"Hang, Latn, Arab",
"Tiếng Cia-Cia",
"Cia-Cia"
}
m["cib"] = {
"Ci Gbe",
12952445,
"alv-gbe",
"Latn",
}
m["cic"] = {
"tiếng Chickasaw",
33192,
"nai-mus",
"Latn",
"Tiếng Chickasaw",
"Chickasaw",
}
m["cid"] = {
"Chimariko",
1294251,
"qfa-iso",
"Latn",
}
m["cie"] = {
"Cineni",
56243,
"cdc-cbm",
"Latn",
}
m["cih"] = {
"tiếng Chinal",
11855245,
"inc",
"Deva, Takr",
"Tiếng Chinal",
"Chinal",
ancestors = "sa",
}
m["cik"] = {
"Chitkuli Kinnauri",
15615982,
"sit-kin",
}
m["cim"] = {
"tiếng Cimbri",
37053,
"gmw-hgm",
"Latn",
"Tiếng Cimbri",
"Cimbri",
ancestors = "bar",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.ringabove .. c.caron},
}
m["cin"] = {
"Cinta Larga",
5121095,
"tup",
"Latn",
}
m["cip"] = {
"Chiapanec",
3364475,
"omq",
"Latn",
}
m["cir"] = {
"Tiri",
7862281,
"poz-cln",
"Latn",
}
m["ciy"] = {
"tiếng Chaima",
12628867,
"sai-ven",
"Latn",
"Tiếng Chaima",
"Chaima",
}
m["cja"] = {
"tiếng Chăm Tây",
12645578,
"cmc",
"Latn, Arab, Khmr", -- Western Cham script is not yet available. Also, Arabic script is missing some glyphs.
"Tiếng Chăm Tây",
"Chăm Tây",
}
m["cje"] = {
"tiếng Chu Ru",
2967321,
"cmc",
"Latn",
"Tiếng Chu Ru",
"Chu Ru",
}
m["cjh"] = {
"Upper Chehalis",
2962074,
"sal",
"Latn",
}
m["cji"] = {
"tiếng Chamalal",
56567,
"cau-and",
"Cyrl",
"Tiếng Chamalal",
"Chamalal",
translit = "cau-nec-translit",
override_translit = true,
display_text = {Cyrl = s["cau-Cyrl-displaytext"]},
entry_name = {Cyrl = s["cau-Cyrl-entryname"]},
}
m["cjk"] = {
"Chokwe",
2422065,
"bnt-clu",
"Latn",
}
m["cjm"] = {
"tiếng Chăm Đông",
2948019,
"cmc",
"Latn, Cham",
"Tiếng Chăm Đông",
"Chăm Đông",
}
m["cjn"] = {
"Chenapian",
5091044,
"paa-spk",
"Latn",
}
m["cjo"] = {
"tiếng Ashéninka Pajonal",
3450481,
"awd",
"Latn",
}
m["cjp"] = {
"Cabécar",
27878,
"cba",
"Latn",
}
m["cjs"] = {
"tiếng Shor",
34139,
"trk-ssb",
"Cyrl",
"Tiếng Shor",
"Shor",
translit = "cjs-translit",
}
m["cjv"] = {
"Chuave",
5115226,
"ngf",
"Latn",
}
m["cjy"] = {
"tiếng Tấn",
56479,
"zhx",
"Hants",
"Tiếng Tấn",
"Tấn",
ancestors = "ltc",
generate_forms = "zh-generateforms",
translit = "zh-translit",
sort_key = "Hani-sortkey",
}
m["ckb"] = {
"tiếng Soran",
36811,
"ku",
"ku-Arab",
"Tiếng Soran",
"Soran",
translit = "ckb-translit",
entry_name = {remove_diacritics = c.kasra .. c.sukun},
}
m["ckh"] = {
"tiếng Chak",
12628870,
"sit-luu",
"Latn, Mymr",
"Tiếng Chak",
"Chak",
ancestors = "kdv",
}
m["ckl"] = {
"Cibak",
56279,
"cdc-cbm",
"Latn",
}
m["ckn"] = {
"Kaang Chin",
6343432,
"tbq-kuk",
"Latn",
}
m["cko"] = {
"Anufo",
34845,
"alv-ctn",
"Latn",
}
m["ckq"] = {
"Kajakse",
3440422,
"cdc-est",
"Latn",
}
m["ckr"] = {
"Kairak",
3503002,
"paa-bng",
"Latn",
}
m["cks"] = {
"Tayo",
1133089,
"crp",
"Latn",
ancestors = "fr",
sort_key = s["roa-oil-sortkey"],
}
m["ckt"] = {
"tiếng Chukot",
33170,
"qfa-ckn",
"Cyrl",
"Tiếng Chukot",
"Chukot",
entry_name = {
from = {"['’]"},
to = {"ʼ"}
},
sort_key = {
from = {"ё", "ӄ", "ԓ", "ӈ"},
to = {"е" .. p[1], "к" .. p[1], "л" .. p[1], "н" .. p[1]}
},
}
m["cku"] = {
"Koasati",
35162,
"nai-mus",
"Latn",
}
m["ckv"] = {
"tiếng Kavalan",
716627,
"map",
"Latn",
"Tiếng Kavalan",
"Kavalan",
}
m["ckx"] = {
"Caka",
5018037,
"nic-tvc",
"Latn",
}
m["cky"] = {
"Cakfem-Mushere",
3441199,
"cdc-wst",
"Latn",
}
m["ckz"] = {
"Cakchiquel-Quiché Mixed Language",
5054550,
"myn",
"Latn",
}
m["cla"] = {
"Ron",
3440432,
"cdc-wst",
"Latn",
}
m["clc"] = {
"tiếng Chilcotin",
28535,
"ath-nor",
"Latn",
"Tiếng Chilcotin",
"Chilcotin",
}
m["cld"] = {
"tiếng Tân Aram Chaldea",
33236,
"sem-are",
"Syrc",
"Tiếng Tân Aram Chaldea",
"Tân Aram Chaldea",
entry_name = "Syrc-entryname",
}
m["cle"] = {
"Lealao Chinantec",
6509365,
"omq-chi",
"Latn",
}
m["clh"] = {
"Chilisso",
3250629,
"inc-koh",
}
m["cli"] = {
"Chakali",
35206,
"nic-gnw",
"Latn",
}
m["clj"] = {
"Laitu Chin",
6474196,
"tbq-kuk",
}
m["clk"] = {
"tiếng Idu",
56412,
"sit-gsi",
"Tibt, Deva, Latn",
"Tiếng Idu",
"Idu",
translit = {Tibt = "Tibt-translit"},
override_translit = true,
display_text = {Tibt = s["Tibt-displaytext"]},
entry_name = {Tibt = s["Tibt-entryname"], Latn = {remove_diacritics = c.grave .. c.acute .. c.macron}},
sort_key = {Tibt = "Tibt-sortkey"},
}
m["cll"] = {
"Chala",
35190,
"nic-gne",
"Latn",
}
m["clm"] = {
"tiếng Klallam",
33404,
"sal",
"Latn",
"Tiếng Klallam",
"Klallam",
}
m["clo"] = {
"Lowland Oaxaca Chontal",
2964450,
"nai-tqn",
"Latn",
}
m["clt"] = {
"tiếng Lutuv",
6502107,
"tbq-kuk",
"Latn",
"Tiếng Lutuv",
"Lutuv",
}
m["clu"] = {
"Caluyanun",
32964,
"phi",
"Latn",
}
m["clw"] = {
"tiếng Chulym",
33125,
"trk-ssb",
"Latn, Cyrl",
"Tiếng Chulym",
"Chulym",
}
m["cly"] = {
"Eastern Highland Chatino",
12642078,
"omq-cha",
"Latn",
}
m["cma"] = {
"tiếng Mạ",
12953680,
"mkh-ban",
"Latn",
"Tiếng Mạ",
"Mạ",
}
m["cme"] = {
"Cerma",
35074,
"nic-gur",
"Latn",
}
m["cmg"] = {
"tiếng Mông Cổ cổ điển",
5128303,
"xgn-cen",
"Mong, Soyo, Zanb",
"Tiếng Mông Cổ cổ điển",
"Mông Cổ cổ điển",
translit = {Mong = "Mong-translit"},
display_text = {Mong = s["Mong-displaytext"]},
entry_name = {Mong = s["Mong-entryname"]},
}
m["cmi"] = {
"tiếng Emberá-Chamí",
3052042,
"sai-chc",
"Latn",
"Tiếng Emberá-Chamí",
"Emberá-Chamí",
}
m["cml"] = {
"Campalagian",
5027893,
"poz-ssw",
"Latn",
}
m["cmm"] = {
"Michigamea",
12636809,
"sio-msv",
"Latn",
}
m["cmn"] = {
"tiếng Quan Thoại",
9192,
"zhx-man",
"Hants, Latn, Bopo",
"Tiếng Quan Thoại",
"Quan Thoại",
wikimedia_codes = "zh",
generate_forms = "zh-generateforms",
translit = {
Hani = "zh-translit",
Bopo = "zh-translit",
},
sort_key = {
Hani = "Hani-sortkey",
Latn = {
from = {
-- Sort terms with tone numbers immediately after equivalent terms with diacritics.
"[aeiouv][" .. c.circ .. c.diaer .. "]?[nr]?g?[0-5]",
-- Add temporary breaks between syllables.
"([aeiouvmn][" .. c.circ .. c.diaer .. "]?[" .. c.macron .. c.acute .. c.caron .. c.grave .. "]?n?ŋ?g?r?)([bpmfdtnlgkhjqxzcsywrv']h?[aeiouvmn ])", p[1] .. "([ngr])$", p[1] .. "([ngr][%s%-'" .. p[1] .. "])",
-- Substitute diacritics for syllable-final tone numbers, and add tone 0 where necessary.
c.macron, c.acute, c.caron, c.grave, "([1-4])([^%s%p" .. p[1] .. "]+)", "([^0-5])%f[%z%s%p" .. p[1] .. "]",
-- Substitute "v" shorthand for "ü" for a temporary placeholder, so that the (very rare) "v" initial is not affected by the later shorthand substitutions.
"([^ " .. p[1] .. "])v",
-- Remove temporary breaks.
p[1],
-- Substitute shorthands for full forms, and sort them immediately after equivalent terms.
"%S*[csz]" .. c.circ .. "%S*", "%S*[ŋ" .. p[2] .. "]%S*", "ĉ", "ŝ", "ŋ", p[2], "ẑ",
-- "ê" comes after "e", "ü" comes after "u" and apostrophes are removed (as their function is replaced by tone numbers).
"[" .. c.circ .. c.diaer .. "]", "'",
-- Sort numbered tone 5 after tone 0.
"5!"
},
to = {
"%0!",
"%1" .. p[1] .. "%2", "%1", "%1",
"1", "2", "3", "4", "%2%1", "%10",
"%1" .. p[2],
"",
"%0\"", "%0\"", "ch", "sh", "ng", "ü", "zh",
p[1], "",
"0!!"
}
},
},
}
m["cmo"] = {
"tiếng M'Nông Trung",
33369881,
"mkh-ban",
"Latn, Khmr",
"Tiếng M'Nông Trung",
"M'Nông Trung",
}
m["cmr"] = {
"Mro Chin",
16889978,
"tbq-kuk",
}
m["cms"] = {
"tiếng Messapio",
36383,
"ine",
"Latn, Ital, Grek",
"Tiếng Messapio",
"Messapio",
translit = {Ital = "Ital-translit"},
}
m["cmt"] = {
"Camtho",
10441336,
"crp",
"Latn",
ancestors = "fly, zu"
}
m["cna"] = {
"tiếng Khương Đường",
12952322,
"sit-lab",
"Tibt",
"Tiếng Khương Đường",
"Khương Đường",
translit = "Tibt-translit",
override_translit = true,
display_text = s["Tibt-displaytext"],
entry_name = s["Tibt-entryname"],
sort_key = "Tibt-sortkey",
}
m["cnb"] = {
"Chinbon Chin",
12952327,
"tbq-kuk",
}
m["cnc"] = {
"tiếng Cống",
5202780,
"tbq-bis",
"Latn",
"Tiếng Cống",
"Cống",
}
m["cng"] = {
"tiếng Khương Bắc",
56559,
"sit-qia",
"Latn",
"Tiếng Khương Bắc",
"Khương Bắc",
}
m["cnh"] = {
"tiếng Chin Hakha",
3250286,
"tbq-kuk",
"Latn, Mymr",
"Tiếng Chin Hakha",
"Chin Hakha",
}
m["cni"] = {
"Asháninka",
3437230,
"awd",
"Latn",
}
m["cnk"] = {
"Khumi Chin",
56308,
"tbq-kuk",
}
m["cnl"] = {
"Lalana Chinantec",
12953437,
"omq-chi",
"Latn",
}
m["cno"] = {
"Con",
3440883,
"mkh-pal",
}
m["cnp"] = {
"Northern Pinghua",
84302463,
"zhx-pin",
"Hants",
generate_forms = "zh-generateforms",
sort_key = "Hani-sortkey",
}
m["cns"] = {
"Central Asmat",
11732048,
"ngf",
"Latn",
}
m["cnt"] = {
"Tepetotutla Chinantec",
5100113,
"omq-chi",
"Latn",
}
m["cnu"] = {
"tiếng Chenoua",
33276,
"ber",
"Latn, Tfng",
"Tiếng Chenoua",
"Chenoua",
translit = {Tfng = "Tfng-translit"},
}
m["cnw"] = {
"Ngawn Chin",
6583675,
"tbq-kuk",
}
m["cnx"] = {
"tiếng Cornwall trung đại",
12642603,
"cel-brs",
"Latn",
ancestors = "oco",
}
m["coa"] = {
"Cocos Islands Malay",
3441699,
"crp",
"Latn",
ancestors = "ms",
}
m["cob"] = {
"Chicomuceltec",
3307204,
"myn",
"Latn",
}
m["coc"] = {
"Cocopa",
33044,
"nai-yuc",
"Latn",
}
m["cod"] = {
"tiếng Cocama",
33317,
"tup",
"Latn",
"Tiếng Cocama",
"Cocama",
}
m["coe"] = {
"Koreguaje",
3198924,
"sai-tuc",
"Latn",
}
m["cof"] = {
"Tsafiki",
2567055,
"sai-bar",
"Latn",
}
m["cog"] = {
"tiếng Chong",
3914630,
"mkh-pea",
"Thai, Khmr",
"Tiếng Chong",
"Chong",
sort_key = {Thai = "Thai-sortkey"},
}
m["coh"] = {
"Chichonyi-Chidzihana-Chikauma",
12629011,
"bnt-mij",
"Latn",
}
m["coj"] = {
"tiếng Cochimi",
3915551,
"nai-yuc",
"Latn",
"Tiếng Cochimi",
"Cochimi",
}
m["cok"] = {
"Santa Teresa Cora",
12641754,
"azc",
"Latn",
}
m["col"] = {
"Columbia-Wenatchi",
3324744,
"sal",
"Latn",
}
m["com"] = {
"tiếng Comanche",
32972,
"azc-num",
"Latn",
"Tiếng Comanche",
"Comanche",
}
m["con"] = {
"tiếng Cofán",
2669254,
"qfa-iso",
"Latn",
"Tiếng Cofán",
"Cofán",
}
m["coo"] = {
"tiếng Comox",
13583746,
"sal",
"Latn",
"Tiếng Comox",
"Comox",
}
m["cop"] = {
"tiếng Copt",
36155,
"egx",
"Copt",
"Tiếng Copt",
"Copt",
translit = "Copt-translit",
ancestors = "egx-dem",
entry_name = {remove_diacritics = c.grave .. c.macron .. c.overline .. c.diaer .. "ˋ"},
sort_key = "cop-sortkey",
}
m["coq"] = {
"Coquille",
12953452,
"ath-pco",
"Latn",
}
m["cot"] = {
"Caquinte",
3915557,
"awd",
"Latn",
}
m["cou"] = {
"tiếng Wamey",
36935,
"alv-ten",
"Latn",
"Tiếng Wamey",
"Wamey",
}
m["cov"] = {
"Cao Miao",
2936935,
"qfa-tak",
}
m["cow"] = {
"tiếng Cowlitz",
3001877,
"sal",
"Latn",
"Tiếng Cowlitz",
"Cowlitz",
}
m["cox"] = {
"Nanti",
15342275,
"awd",
"Latn",
}
m["coy"] = {
"Coyaima",
56450,
"sai-car",
"Latn",
}
m["coz"] = {
"Chochotec",
2964262,
"omq-pop",
"Latn",
}
m["cpa"] = {
"Palantla Chinantec",
5100112,
"omq-chi",
"Latn",
}
m["cpb"] = {
"Ucayali-Yurúa Ashéninka",
3501858,
"awd",
"Latn",
}
m["cpc"] = {
"Ajyíninka Apurucayali",
3327405,
"awd",
"Latn",
}
m["cpg"] = {
"tiếng Hy Lạp Cappadocia",
853414,
"grk",
"Grek, fa-Arab",
"Tiếng Hy Lạp Cappadocia",
"Hy Lạp Cappadocia",
ancestors = "gkm",
translit = {Grek = "el-translit"},
entry_name = {Grek = {remove_diacritics = c.caron .. c.diaerbelow .. c.brevebelow}},
sort_key = {Grek = s["Grek-sortkey"]},
}
m["cpi"] = {
"Chinese Pidgin English",
3435078,
"crp",
"Latn, Hant",
ancestors = "en",
sort_key = {Hant = "Hani-sortkey"},
}
m["cpn"] = {
"Cherepon",
35181,
"alv-gng",
"Latn",
}
m["cpo"] = {
"Kpee",
6435722,
"dmn-jje",
}
m["cps"] = {
"Capiznon",
2937525,
"phi",
"Latn",
}
m["cpu"] = {
"Pichis Ashéninka",
7190661,
"awd",
"Latn",
}
m["cpx"] = {
"tiếng Phổ Hiền",
56583,
"zhx-com",
"Hants",
"Tiếng Phổ Hiền",
"Phổ Hiền",
generate_forms = "zh-generateforms",
sort_key = "Hani-sortkey",
}
m["cpy"] = {
"South Ucayali Ashéninka",
3501868,
"awd",
"Latn",
}
m["cqd"] = {
"Chuanqiandian Cluster Miao",
3307894,
"hmn",
"Latn, Plrd",
}
m["cra"] = {
"Chara",
5073694,
"omv",
"Latn",
}
m["crb"] = {
"Kalinago",
3450735,
"awd-taa",
"Latn",
}
m["crc"] = {
"Lonwolwol",
3259216,
"poz-oce",
"Latn",
}
m["crd"] = {
"tiếng Coeur d'Alene",
32915,
"sal",
"Latn",
"Tiếng Coeur d'Alene",
"Coeur d'Alene",
}
m["crf"] = {
"Caramanta",
3504195,
"sai-chc",
"Latn",
}
m["crg"] = {
"Michif",
13315,
"qfa-mix",
"Latn",
ancestors = "cr, fr",
}
m["crh"] = {
"tiếng Tatar Crưm",
33357,
"trk-kcu",
"Latn, Cyrl, Arab",
"Tiếng Tatar Crưm",
"Tatar Crưm",
dotted_dotless_i = true,
sort_key = {
Latn = {
from = {
"[ıi]" .. c.breve, -- Convert ĭ into PUA so that the decomposed form does not get caught by the next step. Also cover decomposed forms with ı and i, as decomposed Ĭ is converted to ı + ̆ due to the dotted dotless I logic).
"i", -- Ensure "i" comes after "ı".
"â", "ç", "ğ", "ı", p[3], "ñ", "ö", "ş", "ü"
},
to = {
p[3],
"i" .. p[1],
"a", "c" .. p[1], "g" .. p[1], "i", "i" .. p[2], "n" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1],
}
},
Cyrl = {
from = {"гъ", "ё", "къ", "нъ", "дж"},
to = {"г" .. p[1], "е" .. p[1], "к" .. p[1], "н" .. p[1], "ч" .. p[1]}
},
},
}
m["cri"] = {
"Sãotomense",
36536,
"crp",
"Latn",
ancestors = "pt",
}
m["crj"] = {
"tiếng Cree Đông Nam",
12953464,
"alg",
"Latn, Cans",
"Tiếng Cree Đông Nam",
"Cree Đông Nam",
ancestors = "cr",
translit = "cr-translit",
}
m["crk"] = {
"tiếng Cree đồng bằng",
56699,
"alg",
"Cans, Latn",
"Tiếng Cree đồng bằng",
"Cree đồng bằng",
ancestors = "cr",
}
m["crl"] = {
"tiếng Cree Đông Bắc",
12642195,
"alg",
"Cans",
"Tiếng Cree Đông Bắc",
"Cree Đông Bắc",
ancestors = "cr",
translit = "cr-translit",
}
m["crm"] = {
"tiếng Cree Moose",
3446671,
"alg",
"Cans",
"Tiếng Cree Moose",
"Cree Moose",
ancestors = "cr",
translit = "cr-translit",
}
m["crn"] = {
"Cora",
12953454,
"azc",
"Latn",
}
m["cro"] = {
"tiếng Crow",
1207611,
"sio-mor",
"Latn",
"Tiếng Crow",
"Crow",
}
m["crq"] = {
"Iyo'wujwa Chorote",
3540927,
"sai-mtc",
"Latn",
}
m["crr"] = {
"Carolina Algonquian",
16113723,
"alg-eas",
"Latn",
}
m["crs"] = {
"Seychellois Creole",
34015,
"crp",
"Latn",
ancestors = "fr",
sort_key = s["roa-oil-sortkey"],
}
m["crt"] = {
"Iyojwa'ja Chorote",
3504118,
"sai-mtc",
"Latn",
}
m["crv"] = {
"tiếng Chaura",
2605680,
"aav-nic",
nil,
"Tiếng Chaura",
"Chaura",
}
m["crw"] = {
"tiếng Chơ Ro",
5105629,
"mkh-ban",
"Latn",
"Tiếng Chơ Ro",
"Chơ Ro",
}
m["crx"] = {
"tiếng Carrier",
12953431,
"ath-nor",
"Latn, Cans",
"Tiếng Carrier",
"Carrier",
}
m["cry"] = {
"Cori",
35204,
"nic-plc",
"Latn",
}
m["crz"] = {
"Cruzeño",
2967636,
"nai-chu",
"Latn",
}
m["csa"] = {
"Chiltepec Chinantec",
12953435,
"omq-chi",
"Latn",
}
m["csb"] = {
"tiếng Kaszëb",
33690,
"zlw-pom",
"Latn",
"Tiếng Kaszëb",
"Kaszëb",
}
m["csc"] = {
"Catalan Sign Language",
35768,
"sgn",
"Latn", -- when documented
}
m["csd"] = {
"Chiangmai Sign Language",
5095211,
"sgn",
}
m["cse"] = {
"Czech Sign Language",
5201809,
"sgn",
"Latn", -- when documented
}
m["csf"] = {
"Cuban Sign Language",
5192046,
"sgn",
"Latn", -- when documented
}
m["csg"] = {
"Chilean Sign Language",
3322112,
"sgn",
"Latn", -- when documented
}
m["csh"] = {
"tiếng Chin Asho",
12627282,
"tbq-kuk",
"Latn, Mymr",
"Tiếng Chin Asho",
"Chin Asho",
}
m["csi"] = {
"Coast Miwok",
2981109,
"nai-you",
"Latn",
}
m["csj"] = {
"tiếng Chin Songlai",
7561280,
"tbq-kuk",
"Mymr",
"Tiếng Chin Songlai",
"Chin Songlai",
}
m["csk"] = {
"Jola-Kasa",
3446622,
"alv-jol",
"Latn",
}
m["csl"] = {
"Chinese Sign Language",
1094190,
"sgn",
}
m["csm"] = {
"Central Sierra Miwok",
2944443,
"nai-you",
"Latn",
}
m["csn"] = {
"Colombian Sign Language",
2748229,
"sgn",
"Latn", -- when documented
}
m["cso"] = {
"Sochiapam Chinantec",
7550388,
"omq-chi",
"Latn",
}
m["csp"] = {
"Southern Pinghua",
84302019,
"zhx-pin",
"Hants",
generate_forms = "zh-generateforms",
sort_key = "Hani-sortkey",
}
m["csq"] = {
"Croatian Sign Language",
3507506,
"sgn",
}
m["csr"] = {
"Costa Rican Sign Language",
5174901,
"sgn",
"Latn", -- when documented
}
m["css"] = {
"Southern Ohlone",
25559664,
"nai-you",
"Latn",
}
m["cst"] = {
"Northern Ohlone",
25559666,
"nai-you",
"Latn",
}
m["csv"] = {
"Sumtu Chin",
7638087,
"tbq-kuk",
}
m["csw"] = {
"Swampy Cree",
56696,
"alg",
"Latn, Cans",
ancestors = "cr",
}
m["csy"] = {
"Siyin Chin",
7533375,
"tbq-kuk",
}
m["csz"] = {
"Coos",
3126783,
"nai-coo",
"Latn",
}
m["cta"] = {
"Tataltepec Chatino",
7687853,
"omq-cha",
"Latn",
}
m["ctc"] = {
"Chetco-Tolowa",
12628946,
"ath-pco",
"Latn",
}
m["ctd"] = {
"tiếng Chin Tedim",
56357,
"tbq-kuk",
"Latn, Pauc",
"Tiếng Chin Tedim",
"Chin Tedim",
}
m["cte"] = {
"tiếng Chinantec Tepinapa",
12953443,
"omq-chi",
"Latn",
"Tiếng Chinantec Tepinapa",
"Chinantec Tepinapa",
}
m["ctg"] = {
"tiếng Chittagong",
33173,
"inc-eas",
"Beng",
"Tiếng Chittagong",
"Chittagong",
ancestors = "inc-obn",
}
m["cth"] = {
"Thaiphum Chin",
16912048,
"tbq-kuk",
}
m["ctl"] = {
"Tlacoatzintepec Chinantec",
12643657,
"omq-chi",
"Latn",
}
m["ctm"] = {
"Chitimacha",
1294227,
"qfa-iso",
"Latn",
}
m["ctn"] = {
"Chhintange",
32994,
"sit-kie",
"Deva",
}
m["cto"] = {
"Emberá-Catío",
3052039,
"sai-chc",
"Latn",
}
m["ctp"] = {
"tiếng Chatino cao nguyên Tây",
32861734,
"omq-cha",
"Latn",
"Tiếng Chatino cao nguyên Tây",
"Chatino cao nguyên Tây",
entry_name = {remove_diacritics = "¹²³⁴⁵"},
sort_key = {remove_diacritics = c.acute},
}
m["cts"] = {
"tiếng Bắc Catanduanes Bikol",
7130477,
"phi",
"Latn",
"Tiếng Bắc Catanduanes Bikol",
"Bắc Catanduanes Bikol",
}
m["ctt"] = {
"tiếng Chetti Wayanad",
7975850,
"dra-mal",
"Taml",
"Tiếng Chetti Wayanad",
"Chetti Wayanad",
translit = "ta-translit",
}
m["ctu"] = {
"tiếng Chol",
35179,
"myn",
"Latn",
"Tiếng Chol",
"Chol",
}
m["cty"] = {
"tiếng Chetti Moundadan",
105288428,
"dra-kan",
"Taml",
"Tiếng Chetti Moundadan",
"Chetti Moundadan",
translit = "ta-translit",
}
m["ctz"] = {
"tiếng Zacatepec Chatino",
8063754,
"omq-cha",
"Latn",
"Tiếng Zacatepec Chatino",
"Zacatepec Chatino"
}
m["cua"] = {
"tiếng Co",
3441115,
"mkh-ban",
"Latn",
"Tiếng Co",
"Co",
}
m["cub"] = {
"Cubeo",
3006705,
"sai-tuc",
"Latn",
}
m["cuc"] = {
"Usila Chinantec",
7901979,
"omq-chi",
"Latn",
}
m["cug"] = {
"Cung",
35194,
"nic-bbe",
"Latn",
}
m["cuh"] = {
"Chuka",
12952344,
"bnt-kka",
"Latn",
}
m["cui"] = {
"Cuiba",
2980421,
"sai-guh",
"Latn",
}
m["cuj"] = {
"Mashco Piro",
3446596,
"awd",
"Latn",
}
m["cuk"] = {
"tiếng Kuna",
12953659,
"cba",
"Latn",
"Tiếng Kuna",
"Kuna",
}
m["cul"] = {
"Culina",
2475442,
"auf",
"Latn",
}
m["cuo"] = {
"tiếng Cumanagoto",
5193784,
"sai-cpc",
"Latn",
"Tiếng Cumanagoto",
"Cumanagoto",
}
m["cup"] = {
"tiếng Cupeño",
143130,
"azc-cup",
"Latn",
"Tiếng Cupeño",
"Cupeño",
}
m["cuq"] = {
"Cun",
2475478,
"qfa-lic",
"Latn",
}
m["cur"] = {
"Chhulung",
5116126,
"sit-kie",
"Deva",
}
m["cut"] = {
"Teutila Cuicatec",
12953453,
"omq-cui",
"Latn",
}
m["cuu"] = {
"Tai Ya",
3441122,
"qfa-tak",
"Latn",
}
m["cuv"] = {
"Cuvok",
3515056,
"cdc-cbm",
"Latn",
}
m["cuw"] = {
"Chukwa",
12629033,
"sit-kic",
}
m["cux"] = {
"Tepeuxila Cuicatec",
20527242,
"omq-cui",
"Latn",
}
m["cuy"] = {
"Cuitlatec",
2030998,
"qfa-iso",
"Latn",
}
m["cvg"] = {
"Chug",
47683644,
"sit-khb",
}
m["cvn"] = {
"Valle Nacional Chinantec",
12953442,
"omq-chi",
"Latn",
}
m["cwa"] = {
"Kabwa",
6344537,
"bnt-lok",
"Latn",
}
m["cwb"] = {
"Maindo",
11002891,
"bnt-mak",
"Latn",
ancestors = "chw",
}
m["cwd"] = {
"tiếng Cree rừng",
56305,
"alg",
"Latn, Cans",
"Tiếng Cree rừng",
"Cree rừng",
ancestors = "cr",
translit = "cr-translit",
}
m["cwe"] = {
"Kwere",
779632,
"bnt-ruv",
"Latn",
}
m["cwg"] = {
"tiếng Chewong",
646718,
"mkh-asl",
"Latn",
"Tiếng Chewong",
"Chewong"
}
m["cwt"] = {
"Kuwaataay",
35699,
"alv-jol",
"Latn",
}
m["cya"] = {
"Nopala Chatino",
15616302,
"omq-cha",
"Latn",
}
m["cyb"] = {
"Cayubaba",
3183382,
"qfa-iso",
"Latn",
}
m["cyo"] = {
"tiếng Cuyunon",
33153,
"phi",
"Latn",
"Tiếng Cuyunon",
"Cuyunon",
}
m["czh"] = {
"tiếng Huy",
56546,
"zhx",
"Hants", -- ?
"Tiếng Huy",
"Huy",
ancestors = "ltc",
generate_forms = "zh-generateforms",
sort_key = "Hani-sortkey",
}
m["czk"] = {
"tiếng Knaan",
56384,
"zlw",
"Hebr",
"Tiếng Knaan",
"Knaan",
ancestors = "zlw-ocs",
entry_name = {Hebr = {remove_diacritics = u(0x0591) .. "-" .. u(0x05BD) .. u(0x05BF) .. "-" .. u(0x05C5) .. u(0x05C7) .. c.CGJ}},
}
m["czn"] = {
"Zenzontepec Chatino",
603106,
"omq-cha",
"Latn",
}
m["czo"] = {
"tiếng Mân Trung",
56435,
"zhx-inm",
"Hants",
"Tiếng Mân Trung",
"Mân Trung",
generate_forms = "zh-generateforms",
sort_key = "Hani-sortkey",
}
m["czt"] = {
"Zotung Chin",
8074599,
"tbq-kuk",
"Latn",
}
return require("Module:languages").finalizeData(m, "language")
1y8recwmzzv47qzciik1wyh7taszzpe
me pá
0
274887
2514075
2085468
2026-08-15T03:11:01Z
Hiyuune
50834
2514075
wikitext
text/x-wiki
=={{langname|tys}}==
==={{section|n}}===
{{head|tys|Danh từ}}
# [[bác|Bác]] [[gái]].
2voge0vtpywc48c4nrrsbf6l7xxwkfj
Thể loại:Mục từ tiếng Mao Nam
14
277816
2514105
2092307
2026-08-15T03:41:32Z
WhoAlone
40420
Thay cả nội dung bằng “{{auto cat}}”
2514105
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
laeg van
0
277837
2514108
2092345
2026-08-15T03:43:59Z
WhoAlone
40420
2514108
wikitext
text/x-wiki
{{-mmd-}}
{{-noun-}}
{{pn}}
# [[mặt trời]].
{{catname|Danh từ|tiếng Mao Nam}}
{{c|mmd|Thiên thể}}
belgj81m23r4pzqzacevr7uwea169gh
2514128
2514108
2026-08-15T03:56:07Z
Hiyuune
50834
/* */
2514128
wikitext
text/x-wiki
=={{langname|mmd}}==
==={{section|n}}===
{{head|mnd|Danh từ}}
# [[Mặt Trời]].
{{c|mmd|Thiên thể}}
d6obm6vhq6u5n74ndftd3qdtrcbs2pc
2514129
2514128
2026-08-15T03:56:48Z
Hiyuune
50834
/* Tiếng Mao Nam */
2514129
wikitext
text/x-wiki
=={{langname|mmd}}==
==={{section|n}}===
{{head|mmd|Danh từ}}
# [[Mặt Trời]].
{{c|mmd|Thiên thể}}
l07w1mt6nxcnqggpnj62ga1fziv8u5w
nis nienz
0
277838
2514133
2092346
2026-08-15T03:59:26Z
WhoAlone
40420
2514133
wikitext
text/x-wiki
{{-mmd-}}
{{-noun-}}
{{pn}}
# [[mặt trăng]].
{{catname|Danh từ|tiếng Mao Nam}}
{{c|mmd|Thiên thể}}
92r0fe0qj8sigiye6r3w3e2f7u11mde
2514182
2514133
2026-08-15T09:54:10Z
Hiyuune
50834
2514182
wikitext
text/x-wiki
=={{langname|mmd}}==
==={{section|noun}}===
{{head|mmd|Danh từ}}
# [[Mặt Trăng]].
{{c|mmd|Thiên thể}}
svg6eyszrbqwypm3out9hex9nhd934n
duengx
0
277860
2514134
2092408
2026-08-15T03:59:39Z
WhoAlone
40420
2514134
wikitext
text/x-wiki
{{-mmd-}}
{{-noun-}}
{{pn}}
# [[băng]].
{{catname|Danh từ|tiếng Mao Nam}}
{{c|mmd|Nước}}
2c46xlq47dk4wp8o0bhou5t63tg97vf
2514179
2514134
2026-08-15T09:27:50Z
Hiyuune
50834
2514179
wikitext
text/x-wiki
=={{lagname|mmd}}==
==={{section|noun}}===
{{head|mmd|Danh từ}}
# [[băng|Băng]].
{{c|mmd|Nước}}
fuab3wturjc8yvky07nnxzyg8geyjfa
2514180
2514179
2026-08-15T09:27:59Z
Hiyuune
50834
/* {{lagname|mmd}} */
2514180
wikitext
text/x-wiki
=={{langname|mmd}}==
==={{section|noun}}===
{{head|mmd|Danh từ}}
# [[băng|Băng]].
{{c|mmd|Nước}}
1bwncrzqni1rzpqk4jbiduqojsi7hx3
Thể loại:Danh từ tiếng Mao Nam
14
277861
2514106
2092409
2026-08-15T03:43:00Z
WhoAlone
40420
2514106
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Động từ tiếng Mao Nam
14
277956
2514107
2092613
2026-08-15T03:43:03Z
WhoAlone
40420
2514107
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
tốc sloé
0
282787
2514145
2103758
2026-08-15T04:53:00Z
Hiyuune
50834
/* */
2514145
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[hoảng hốt]], [[hãi hùng]].
==={{section|ref}}===
* {{R:Lương Bèn}}
6pboaf6lvb1mqy9yawg73ay8lof25qg
fộng
0
282788
2514143
2103759
2026-08-15T04:03:10Z
Hiyuune
50834
/* */
2514143
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[hốt hoảng|Hốt hoảng]].
==={{section|ref}}===
* {{R:Lương Bèn}}
hc8mkuefa2eqbjwq10trk1205jyk060
fọp ma̱o
0
282789
2514142
2103760
2026-08-15T04:02:37Z
Hiyuune
50834
/* */
2514142
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[hoảng hốt]].
==={{section|ref}}===
* {{R:Lương Bèn}}
l90u0895ps6xjdb55jo298ujyvgaxrl
ma̱o mi̱nh
0
282791
2514140
2103763
2026-08-15T04:02:12Z
Hiyuune
50834
/* */
2514140
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[hoảng hồn]], [[hoảng hốt]].
==={{section|ref}}===
* {{R:Lương Bèn}}
7obzjpfq2dfe20wd75zdahfudvgt2wj
lùng áo
0
282890
2514044
2104058
2026-08-14T14:02:50Z
Hiyuune
50834
2514044
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|n}}===
{{tyz-IPA}}
==={{section|n}}===
{{tyz-noun}}
# [[anh em]] [[trai]], [[chú]] [[bác]].
==={{section|ref}}===
* {{R:Lương Bèn}}
ba4cw40n2h3g4iiem91b8qo5yccv8wl
pút mò
0
282895
2514059
2104064
2026-08-14T14:28:07Z
Hiyuune
50834
2514059
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|noun}}===
{{tyz-noun}}
# [[gỗ|Gỗ]] [[mục]].
==={{section|ref}}===
* {{R:Lương Bèn}}
07lc3awxthvtnr7w6njoyjslum4hawk
chá
0
282911
2514072
2104165
2026-08-15T03:08:33Z
Hiyuune
50834
2514072
wikitext
text/x-wiki
=={{langname|pt}}==
{{wp|pt:}}
[[Image:Cup of tea, Scotland.jpg|thumb|250px|chá]]
==={{section|pron}}===
{{pt-IPA}}
* {{audio|pt|LL-Q5146 (por)-Santamarcanda-chá.wav|a=Porto}}
* {{rhymes|pt|a|s=1}}
* {{homophones|pt|xá}}
* {{hyph|pt|chá}}
==={{section|n}}===
{{pt-noun|m}}
# [[trà]], [[chè]]
# [[nước trà]], [[nước chè]].
===={{section|drv}}====
{{col|pt|chá preto
|chá verde
|chá de bebê
|chá de revelação
|colher de chá
|chá gelado
|cerimônia do chá
|casa de chá
|chá da tarde
|chá branco
|tomar chá de sumiço
|chazinho
|chaleira
|dar um chá}}
===={{section|rel}}====
{{col|pt|chávena}}
===={{section|desc}}====
{{top2}}
* {{desc|apy|xa|bor=1}}
* {{desc|gu|ચા|bor=1}}
* {{desc|hrx|Scha|bor=1}}
* {{desc|yrl|xaa|bor=1}}
* {{desc|es|cha|alt1=cha / chá|bor=1|qq=tiếng Tây Ban Nha Philippines}}
** {{desc|tl|tsaa|bor=1|unc=1|alts=1}}
** {{desc|ceb|tsa|bor=1|unc=1}}
* {{desc|tet|xá|bor=1}}
{{bottom}}
==={{section|further}}===
* {{R:pt:Aulete}}
* {{R:pt:DLP-ACL}}
* {{R:pt:Infopédia}}
* {{R:pt:Michaelis}}
* {{R:pt:Priberam}}
=={{langname|tyz}}==
==={{section|pron}}===
* {{tyz-IPA}}
==={{section|etym}} 1===
Từ {{bor|tyz|zh|-}} {{ltc-l|價||giá cả}}. Cùng gốc với {{cog|nod|ᨣ᩵ᩤ}}, {{cog|lo|ຄ່າ}}, {{cog|khb|ᦅᦱᧈ}}, {{cog|shn|ၵႃႈ}}, {{cog|th|ค่า}}. So sánh với {{cog|vi|cả}} (như {{m|vi|giá cả}}).
===={{section|n}}====
{{tyz-noun|價}}
# [[giá cả|Giá cả]].
====={{section|drv}}=====
{{col3|tyz|khửn chá}}
==={{section|etym}} 2===
===={{section|n}}====
{{tyz-noun}}
# Cái [[giá]] để [[đồ]].
==={{section|ref}}===
* {{R:tyz:Hoàng Văn Ma, Lục Văn Pảo, Hoàng Chí}}
* {{R:tyz:Lương Bèn}}
* {{R:tyz:tdcnt}}
cot9pi9jgla5oa0fll9py0gvuwbt7h3
tha quác
0
282912
2514048
2104115
2026-08-14T14:05:04Z
Hiyuune
50834
2514048
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|n}}===
{{tyz-noun}}
# [[mắt|Mắt]] [[cáo]].
44rqtov67w3mg3u4gcvz7gpqauvrjqy
cuôi
0
282914
2514049
2104118
2026-08-14T14:06:01Z
Hiyuune
50834
2514049
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|n}}===
{{tyz-noun}}
# [[cái|Cái]] [[sọt]].
0gxdhzqu2ajol3cj94mpvu3ltd1r54g
tài tảm
0
283047
2514045
2104440
2026-08-14T14:03:22Z
Hiyuune
50834
2514045
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|n}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[gan dạ]], [[dũng cảm]].
==={{section|ref}}===
* {{R:Lương Bèn}}
c3jlzz359zft8z97xdteu1dk7b2jppo
la̱n
0
283048
2514130
2104441
2026-08-15T03:58:15Z
Hiyuune
50834
/* */
2514130
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[nhát|Nhát]], [[nhút nhát]].
==={{section|ref}}===
* {{R:Lương Bèn}}
dnjy3s6c4vrhejmpk0kur9yuookgrcd
rạy rạy
0
283049
2514138
2104443
2026-08-15T04:00:25Z
Hiyuune
50834
/* */
2514138
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# Nói [[liên tục]].
# [[luôn tay]].
==={{section|ref}}===
* {{R:Lương Bèn}}
pymwqdxijup6ervmlz7s86sgdf1exib
lịch lịch
0
283065
2514050
2104472
2026-08-14T14:06:24Z
Hiyuune
50834
2514050
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[liên tục]], [[liên miên]].
# [[nườm nượp]].
==={{section|ref}}===
* {{R:Lương Bèn}}
6uiuchipi1b7ss4pl15egvhwch7ykym
quặc quặc
0
283066
2514073
2104473
2026-08-15T03:09:44Z
Hiyuune
50834
2514073
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[liên tục|Liên tục]].
# [[quần quật|Quần quật]].
==={{section|ref}}===
* {{R:Lương Bèn}}
8o813npiclqk84gxbtb7s7qnvqo7ia1
lúc loác
0
283067
2514074
2104474
2026-08-15T03:10:09Z
Hiyuune
50834
2514074
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[cẩu thả|Cẩu thả]].
==={{section|ref}}===
* {{R:Lương Bèn}}
t88dkl1chov96sv0b1pjgzcubzsziqj
nga̱i ngựt
0
283114
2514051
2104562
2026-08-14T14:06:50Z
Hiyuune
50834
cập nhật
2514051
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[dễ dàng|Dễ dàng]].
==={{section|ref}}===
* {{R:Lương Bèn}}
fvok2zp9c42qgi76hvij6zkp5r4rmli
cột ngoáng
0
283116
2514047
2104567
2026-08-14T14:04:32Z
Hiyuune
50834
2514047
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[cong queo|Cong queo]], [[cong vênh]].
==={{section|ref}}===
* {{R:Lương Bèn}}
f5u1qxlmujnncqhtp3lf9wgoorurszb
kho ngoóng
0
283117
2514046
2104568
2026-08-14T14:04:03Z
Hiyuune
50834
2514046
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[cong queo|Cong queo]].
==={{section|ref}}===
* {{R:Lương Bèn}}
aq61lbsaset4ecicupt6xuh6si9u0e3
ngàn ngàn
0
283118
2514135
2104569
2026-08-15T03:59:47Z
Hiyuune
50834
/* */
2514135
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[ngổng]], [[cong]] [[vổng]] [[lên]].
==={{section|ref}}===
* {{R:Lương Bèn}}
mcf5owilrd5kp2m90xa5d13cdatc5e0
dàu doạt
0
283119
2514132
2104571
2026-08-15T03:59:05Z
Hiyuune
50834
/* */
2514132
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[thẳng đuỗn]], [[thẳng tưng]].
==={{section|ref}}===
* {{R:Lương Bèn}}
fd72bnaj67nzoxvp4t4xv4lqbkzmgw3
nă̱n
0
283121
2514060
2104574
2026-08-14T14:37:07Z
Hiyuune
50834
2514060
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|adj}}===
{{tyz-adj}}
# [[thẳng|Thẳng]].
==={{section|ref}}===
* {{R:Lương Bèn}}
b06hge89pmrpjbex2p2z4kk6gpjdzkv
to̱n dàu
0
283125
2514053
2104605
2026-08-14T14:09:57Z
Hiyuune
50834
2514053
wikitext
text/x-wiki
=={{langname|tyz}}==
==={{section|pron}}===
{{tyz-IPA}}
==={{section|n}}===
{{tyz-noun}}
# [[đoạn thẳng|Đoạn thẳng]].
==={{section|ref}}===
* {{R:Lương Bèn}}
mwks46ts12q8iebj8pv6vdirzgaiss3
Mô đun:labels/data/lang/ja
828
287768
2514076
2331137
2026-08-15T03:16:07Z
Hiyuune
50834
2514076
Scribunto
text/plain
local labels = {}
labels["Akita"] = {
Wikipedia = "Akita dialect",
regional_categories = true,
}
labels["Amami"] = {
Wikipedia = "Amami Japanese",
regional_categories = true,
}
labels["Awa"] = {
Wikipedia = "Shikoku dialect",
regional_categories = true,
}
labels["Awaji"] = {
Wikipedia = "Awaji dialect",
regional_categories = true,
}
labels["Banshū"] = {
aliases = {"Banshu"},
Wikipedia = "Banshū dialect",
regional_categories = true,
}
labels["Chikugo"] = {
Wikipedia = "Hichiku dialect",
regional_categories = true,
}
labels["Chikuhō"] = {
aliases = {"Chikuho"},
Wikipedia = "Hichiku dialect",
regional_categories = true,
}
labels["Chūgoku"] = {
aliases = {"Chugoku"},
Wikipedia = "Chūgoku dialect",
regional_categories = true,
}
labels["Edo"] = {
aliases = {"Edo Japanese", "Edo period"},
Wikipedia = "Edo period",
regional_categories = true,
}
labels["extended shinjitai"] = {
aliases = {"eshin"},
Wikipedia = "Extended shinjitai",
}
labels["Fukui"] = {
Wikipedia = "Hokuriku dialect#Fukui",
regional_categories = true,
}
labels["Gunma"] = {
Wikipedia = "Kantō dialect",
regional_categories = true,
}
labels["Hachijō"] = {
aliases = {"Hachijo"},
Wikipedia = "Hachijō language",
regional_categories = true,
}
labels["Hakata"] = {
Wikipedia = "Hakata dialect",
regional_categories = true,
}
labels["Hata"] = {
Wikipedia = "Shikoku dialect",
regional_categories = true,
}
labels["Hawaii"] = {
aliases = {"Hawaiian"},
Wikipedia = true,
regional_categories = "Hawaiian",
}
labels["Hichiku"] = {
Wikipedia = "Hichiku dialect",
regional_categories = true,
}
labels["Hida"] = {
Wikipedia = "Hida dialect",
regional_categories = true,
}
labels["Hokkaidō"] = {
aliases = {"Hokkaido"},
Wikipedia = "Hokkaidō dialect",
regional_categories = true,
}
labels["Hokuriku"] = {
Wikipedia = "Hokuriku dialect",
regional_categories = true,
}
labels["Hōnichi"] = {
aliases = {"Honichi"},
Wikipedia = "Hōnichi dialect",
regional_categories = true,
}
labels["Ibaraki"] = {
Wikipedia = "Ibaraki dialect",
regional_categories = true,
}
labels["Iyo"] = {
Wikipedia = "Iyo dialect",
regional_categories = true,
}
labels["Kagoshima"] = {
aliases = {"Satsugu", "Satsugū", "Satsuma"},
Wikipedia = "Kagoshima dialect",
regional_categories = true,
}
labels["Kansai"] = {
Wikipedia = "Kansai dialect",
regional_categories = true,
}
labels["Kantō"] = {
aliases = {"Kanto"},
Wikipedia = "Kantō dialect",
regional_categories = true,
}
labels["Kesen"] = {
Wikipedia = "Kesen dialect",
regional_categories = true,
}
labels["Kumamoto"] = {
Wikipedia = "Kumamoto dialect",
regional_categories = true,
}
labels["Kyōto"] = {
aliases = {"Kyoto"},
Wikipedia = "Kansai dialect",
regional_categories = true,
}
labels["Kyūshū"] = {
aliases = {"Kyushu"},
Wikipedia = "Japanese dialects#Kyushu Japanese",
regional_categories = true,
}
labels["Mikawa"] = {
Wikipedia = "Mikawa dialect",
regional_categories = true,
}
labels["Mino"] = {
Wikipedia = "Mino dialect",
regional_categories = true,
}
labels["Nagaoka"] = {
Wikipedia = "Nagaoka dialect",
regional_categories = true,
}
labels["Nagasaki"] = {
Wikipedia = "Nagasaki dialect",
regional_categories = true,
}
labels["Nagoya"] = {
Wikipedia = "Nagoya dialect",
regional_categories = true,
}
labels["Ōita"] = {
aliases = {"Oita"},
Wikipedia = "Ōita dialect",
regional_categories = true,
}
labels["Okinawa"] = {
Wikipedia = "Okinawan Japanese",
regional_categories = true,
}
labels["Ōsaka"] = {
aliases = {"Osaka"},
Wikipedia = "Kansai dialect",
regional_categories = true,
}
labels["Saga"] = {
Wikipedia = "Saga dialect",
regional_categories = true,
}
labels["Sanuki"] = {
Wikipedia = "Sanuki dialect",
regional_categories = true,
}
labels["Shikoku"] = {
Wikipedia = "Shikoku dialect",
regional_categories = true,
}
labels["Shitamachi"] = {
Wikipedia = "Tokyo dialect",
regional_categories = true,
}
labels["Shizuoka"] = {
regional_categories = true,
}
labels["Đài Loan"] = {
aliases = {"Taiwan", "Taiwanese"},
Wikipedia = true,
plain_categories = "Tiếng Nhật Đài Loan"
}
labels["Tōhoku"] = {
aliases = {"Tohoku"},
Wikipedia = "Tōhoku dialect",
regional_categories = true,
}
labels["Tōkai–Tōsan"] = {
aliases = {"Tōkai", "Tokai", "Tōsan", "Tosan", "Tōkai-Tōsan", "Tōkai-Tosan", "Tokai-Tōsan", "Tokai-Tosan"},
Wikipedia = "Tōkai–Tōsan dialect",
regional_categories = true,
}
labels["Tōkyō"] = {
aliases = {"Tokyo"},
Wikipedia = "Tokyo dialect",
regional_categories = true,
}
labels["Tosa"] = {
Wikipedia = "Tosa dialect",
regional_categories = true,
}
labels["Toyama"] = {
Wikipedia = "Hokuriku dialect#Toyama",
regional_categories = true,
}
labels["Tsugaru"] = {
Wikipedia = "Tsugaru dialect",
regional_categories = true,
}
labels["Tsushima"] = {
Wikipedia = "Tsushima dialect",
regional_categories = true,
}
labels["Umpaku"] = {
Wikipedia = "Umpaku dialect",
regional_categories = true,
}
labels["Yamagata"] = {
Wikipedia = "Yamagata dialect",
regional_categories = true,
}
return require("Module:labels").finalize_data(labels)
elpk0d2fd8lt1jx7wxtjpit0ki2ugb3
Thể loại:Danh từ tiếng Mông Cổ cổ điển
14
292354
2514146
2131172
2026-08-15T05:12:23Z
WhoAlone
40420
2514146
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
ᠤᠯᠠᠭ᠋ᠠᠨ ᠯᠤᠤᠪᠠᠩ
0
295808
2514147
2156337
2026-08-15T05:12:53Z
WhoAlone
40420
2514147
wikitext
text/x-wiki
{{-cmg-}}
{{-noun-}}
{{head|cmg|Danh từ}}
# [[củ cải|Củ cải]].
{{c|cmg|Rau}}
ppvxzfr4807gtxbznpo8cc3hthtwnn6
🔞
0
300046
2514064
2205110
2026-08-14T15:01:39Z
TheHighFighter2
42988
/* Đa ngữ */
2514064
wikitext
text/x-wiki
{{character info}}
=={{langname|mul}}==
==={{ĐM|symbol}}===
{{head|mul|Ký hiệu}}
# [[cấm|Cấm]] người dưới 18 tuổi.
#: {{synonyms|mul|18+}}
# Biểu tượng chỉ nội dung người lớn/[[NSFW]].
==={{ĐM|see also}}===
* {{l|mul|🛇}} {{q|biểu tượng thể hiện sự không cho phép/cấm}}
[[Thể loại:Khối ký tự Miscellaneous Symbols and Pictographs|51E]]
{{C|mul|Mười tám}}
dv9871gswlzivxyw3hfx0lbzzfob3vf
ຊ້າງ
0
309424
2514036
2173814
2026-08-14T12:37:36Z
Kelly zhrm
58416
2514036
wikitext
text/x-wiki
{{also|ຊ່າງ}}
=={{langname|lo}}==
==={{ĐM|etym}}===
Từ {{inh|lo|tai-pro|*ɟaːŋꟲ||elephant}}, từ {{der|lo|ltc|-}} {{ltc-l|象|voi}}. Cùng gốc với {{cog|th|ช้าง}}, {{cog|nod|ᨩ᩶ᩣ᩠ᨦ}}, {{cog|tts|ซ่าง}}, {{cog|khb|ᦋᦱᧂᧉ}}, {{cog|blt|ꪋ꫁ꪱꪉ}}, {{cog|shn|ၸၢင်ႉ}}, {{cog|tdd|ᥓᥣᥒᥳ}}, {{cog|aho|𑜋𑜂𑜫}}, {{cog|za|ciengh}}, {{cog|skb|ซาง}}.
==={{ĐM|pron}}===
{{lo-pron}}
==={{ĐM|n}}===
{{lo-noun|ໂຕ|ເຊືອກ}}
# [[voi|Voi]].
==={{ĐM|ref}}===
* {{R:lo:Kerr}}
{{C|lo|Lớp Thú}}
ba16etorqucetlyjuuyzplmlc8dx2kv
2514037
2514036
2026-08-14T12:37:50Z
Kelly zhrm
58416
/* {{ĐM|etym}} */
2514037
wikitext
text/x-wiki
{{also|ຊ່າງ}}
=={{langname|lo}}==
==={{ĐM|etym}}===
Từ {{inh|lo|tai-pro|*ɟaːŋꟲ||voi}}, từ {{der|lo|ltc|-}} {{ltc-l|象|voi}}. Cùng gốc với {{cog|th|ช้าง}}, {{cog|nod|ᨩ᩶ᩣ᩠ᨦ}}, {{cog|tts|ซ่าง}}, {{cog|khb|ᦋᦱᧂᧉ}}, {{cog|blt|ꪋ꫁ꪱꪉ}}, {{cog|shn|ၸၢင်ႉ}}, {{cog|tdd|ᥓᥣᥒᥳ}}, {{cog|aho|𑜋𑜂𑜫}}, {{cog|za|ciengh}}, {{cog|skb|ซาง}}.
==={{ĐM|pron}}===
{{lo-pron}}
==={{ĐM|n}}===
{{lo-noun|ໂຕ|ເຊືອກ}}
# [[voi|Voi]].
==={{ĐM|ref}}===
* {{R:lo:Kerr}}
{{C|lo|Lớp Thú}}
jgfjg5vbiphil07fnr48jxi6lf50ppu
copulabam
0
324434
2514194
2200258
2026-08-15T11:52:06Z
Kelly zhrm
58416
2514194
wikitext
text/x-wiki
=={{langname|la}}==
==={{ĐM|pron}}===
* {{la-IPA|cōpulābam}}
==={{ĐM|v}}===
{{head|la|Biến thể hình thái động từ|head=cōpulābam}}
# {{inflection of|la|cōpulō||1|s|impf|actv|indc}}
jdesuo7i0a8678wdk0ccsm8p5kmm9mr
ಆನೆ
0
327141
2514033
2208388
2026-08-14T12:25:38Z
Kelly zhrm
58416
2514033
wikitext
text/x-wiki
=={{langname|kn}}==
==={{ĐM|etym}}===
{{inh+|kn|dra-pro|*yĀnay||voi}}. Cùng gốc với {{cog|ta|யானை}}, {{cog|ml|ആന}}, {{cog|te|ఏనుగు}}.
==={{ĐM|pron}}===
{{kn-IPA}}
==={{ĐM|n}}===
{{kn-noun}}
# [[voi|Voi]].
# {{lb|kn|chess}} [[tượng|Tượng]].
===={{ĐM|decl}}====
{{kn-decl-e-i-ai|ಆನೆ}}
==={{ĐM|see}}===
{{bảng:quân cờ vua/kn}}
{{C|kn|Lớp Thú}}
=={{langname|kfa}}==
==={{ĐM|etym}}===
{{inh+|kfa|dra-pro|*yĀnay||voi}}.
==={{ĐM|noun}}===
{{head|kfa|Danh từ}}
# [[voi|Voi]].
{{C|kfa|Lớp Thú}}
isjao2y03jpl53gl5yhtc6z1rw0oler
Thành viên:Hiyuune/common.js
2
329942
2514177
2513946
2026-08-15T09:19:11Z
Hiyuune
50834
2514177
javascript
text/javascript
importScript("en:User:Erutuon/scripts/addAutoCat.js");
mw.loader.load("//vi.wiktionary.org/w/index.php?title=Th%C3%A0nh_vi%C3%AAn:Veritas_Sapientiae/twinkle.js&action=raw&ctype=text/javascript");
mw.loader.load("//vi.wiktionary.org/w/index.php?title=Th%C3%A0nh_vi%C3%AAn:Hiyuune/Gadget-popups.js&action=raw&ctype=text/javascript");
mw.loader.load("//vi.wiktionary.org/w/index.php?title=Th%C3%A0nh_vi%C3%AAn:Hiyuune/Gadget-PagePreviews.js&action=raw&ctype=text/javascript");
9slnuh8hpqwej4ijg7xfy347phttdi0
Thể loại:Tiếng Nhật Hokkaidō
14
397697
2514170
2354246
2026-08-15T09:04:44Z
Hiyuune
50834
2514170
wikitext
text/x-wiki
{{auto cat|1=Hokkaidō|lang=ja|lect=1|cat=Tiếng Nhật Nhật Bản}}
5td3mgltqzazvqbfsjp2igszfbokvcz
Thể loại:Tiếng Nhật Kagoshima
14
397698
2514171
2354247
2026-08-15T09:05:07Z
Hiyuune
50834
2514171
wikitext
text/x-wiki
{{auto cat|1=Kagoshima|lang=ja|lect=1|cat=Tiếng Nhật Kyūshū}}
r23kly9hv8lvdp6tmrjvj20fidrqxpd
Thể loại:Tiếng Nhật Hakata
14
399603
2514169
2360881
2026-08-15T09:04:00Z
Hiyuune
50834
2514169
wikitext
text/x-wiki
{{auto cat|1=Hakata|lang=ja|lect=1|cat=Tiếng Nhật Kyūshū}}
1af3b8ix869en4n919ui4djwzpwdsi6
Thể loại:Tiếng Nhật Fukui
14
399996
2514165
2362470
2026-08-15T05:38:53Z
Hiyuune
50834
/* */
2514165
wikitext
text/x-wiki
{{auto cat|1=Fukui|lang=ja|lect=1|cat=Tiếng Nhật Hokuriku}}
0qrqtpn2sljusrypgt1tf7nqyyevike
Thể loại:Tiếng Nhật Okinawa
14
400309
2514172
2363111
2026-08-15T09:06:49Z
Hiyuune
50834
2514172
wikitext
text/x-wiki
{{auto cat|1=Okinawa|lang=ja|lect=1|cat=Tiếng Nhật Nhật Bản}}
q81uqj89fmjqazv1qlcqtgyun5scp6f
ℳ
0
400505
2514063
2513090
2026-08-14T14:59:04Z
TheHighFighter2
42988
2514063
wikitext
text/x-wiki
{{character info}}
=={{langname|mul}}==
==={{section|symbol}}===
{{head|mul|Ký hiệu}}
# {{lb|mul|historical}} Ký hiệu [[tiền tệ]] của [[Đức]] truớc năm 1924.
# {{lb|mul|physics}} [[M-matrix]].
==={{section|see}}===
{{list:ký hiệu tiền tệ}}
[[Thể loại:Ký hiệu tiền]]
6eumu2mxt1lp7z408naleg97pe8x2qq
đi B
0
409421
2514166
2473366
2026-08-15T05:44:11Z
TheHighFighter2
42988
/* Tham khảo */
2514166
wikitext
text/x-wiki
=={{langname|vi}}==
[[File:Svnmapfront.jpg|thumb|Các mặt trận (B) của {{w|Quân Giải phóng miền Nam Việt Nam}} (1970)]]
==={{ĐM|etym}}===
Từ {{com|vi|đi|alt2=B|t2=chiến trường miền Nam trong [[chiến tranh Việt Nam]], theo cách gọi của {{w|Đảng Lao động Việt Nam}}}}.<ref>{{cite-web|vi|author=PXN|date=2018-5-15|title="Đi B" ra mắt bạn đọc|work=Báo điện tử Đảng Cộng sản Việt Nam|url=https://dangcongsan.vn/tu-tuong-van-hoa/di-b-ra-mat-ban-doc-483579.html|passage=Hậu phương miền Bắc là A, chiến trường miền Nam ở bên kia vĩ tuyến 17 được gọi là B. "Đi B" là vào Nam, là ra chiến trường, là trực tiếp giáp mặt đạn bom chiến đấu với kẻ thù.}}</ref>
==={{ĐM|pron}}===
{{vi-IPA|đi Bê}}
==={{ĐM|verb}}===
{{vi-verb|head=[[đi]] B}}
# {{lb|vi|historical|slang|chỉ [[cán bộ]] [[Việt Nam Dân chủ Cộng hòa|miền Bắc Việt Nam]]}} Đi [[chiến đấu]], [[công tác]] ở [[miền Nam]] trong giai đoạn từ 1959 đến 1975.
#* {{quote-web|vi|date=26-04-2017|author=Nguyễn Bắc Sơn|title=Viết nhân ngày 30/4 - Kỳ cuối: Chuẩn tướng Nguyễn Hữu Hạnh bây giờ…|work=Tiền phong|url=https://tienphong.vn/viet-nhan-ngay-304-ky-cuoi-chuan-tuong-nguyen-huu-hanh-bay-gio-post948627.tpo|passage=Ngày '''đi B''', Long mang theo gần mười cân sách đại học (đã xé bỏ hết bìa, xén cả ba mép, chỉ để chữ, cho nhẹ cân) tức là phải bớt đi tư trang, chỉ còn lương thực, thực phẩm, thuốc…}}
==={{ĐM|see}}===
* {{l|vi|đi C}}
* {{l|vi|đi K}}
==={{ĐM|ref}}===
{{reflist}}
{{C|vi|Chiến tranh Việt Nam}}
8qyf1xiqi22ez9f4yaaqx20gl1mavet
ꞵ
0
411177
2514071
2509172
2026-08-15T03:01:43Z
Hiyuune
50834
2514071
wikitext
text/x-wiki
{{character info}}
=={{langname|mul}}==
==={{ĐM|etym}} 1===
Từ chữ Hy Lạp '''[[β#Đa ngữ|β]]'''
===={{ĐM|desction}}====
{{mul-letter}}
#[[chữ cái|Chữ cái]] '''''[[beta]]''''' viết thường.
==={{ĐM|etym}} 2===
===={{ĐM|alter form}}====
*[[β]]
===={{ĐM|symbol}}====
{{mul-symbol}}
# {{lb|mul|IPA}} Biến thể Latinh của chữ Hy Lạp [[β]], được một số tác giả sử dụng.
=={{langname|gha}}==
==={{ĐM|letter}}===
{{letter|gha}}
# Chữ cái thứ 5 viết thường trong bảng chữ cái Latinh tiếng Ghadames.
==={{ĐM|see}}===
*{{letters|lang=gha|sc=Latn|qual=Bảng chữ cái Latinh tiếng Ghadames|Aa|Ăă|Ǝǝ|Bb|Ꞵꞵ|Čč|Dd|Ḍḍ|Ee|Ɛɛ|Ff|Gg|Ǵǵ|Ɣɣ|Hh|Ḥḥ|Ii|Kk|Ll|Mm|Nn|Oo|Pp|Qq|Rr|Řř|Ṛṛ|Ss|Ṣṣ|Šš|Tt|Ṭṭ|Uu|Ww|Xx|Yy|Zz|Ẓẓ|Žž}}
=={{langname|lup}}==
==={{ĐM|alt}}===
*{{l|lup|v}}
==={{ĐM|pron}}===
*{{IPA4|lup|[v]}}
==={{ĐM|letter}}===
{{letter|lup}}
# Chữ cái Latinh viết thường biểu thị phụ âm '''{{IPAchar|/v/}}, /ꞵ/''' trong tiếng Lumbu.
=={{langname|puu}}==
==={{ĐM|alt}}===
*{{l|puu|v}}
==={{ĐM|pron}}===
*{{IPA4|puu|/β/}}
==={{ĐM|letter}}===
{{letter|puu}}
# Chữ cái thứ 26 trong bảng chữ cái AGS, tương ứng với ''{{l|puu|v}}'' trong bảng chữ cái Mabik-ma-Kombil.
==={{ĐM|see}}===
*{{letters|lang=puu|sc=Latn|qual=Bảng chữ cái AGS|a|b|d|e|f|ɣ|i|j|k|l|m|mb|mv|n|nd|ng|ny|nz|o|p|r|s|t|ts|u|ꞵ|w|y}}
*{{letters|lang=puu|sc=Latn|qual=Bảng chữ cái Mabik-ma-Kombil 2001a|b|d|e|f|g|i|j|k|l|m|mb|mf|n|nd|ng|ñ|nz|o|p|r|s|t|ts|u|v|w|y}}
qz4t46s307o5kx4c4cwuat0hvspicv3
Thành viên:Hiyuune/Gadget-popups.js
2
412105
2514175
2513984
2026-08-15T09:14:00Z
Hiyuune
50834
2514175
javascript
text/javascript
// {{documentation}}
// _________________________________________________________________________________________
// | |
// | === WARNING: GLOBAL GADGET FILE === |
// | Changes to this page affect many users. |
// | Please discuss changes on the [[Wiktionary:Grease Pit]] before editing. |
// |_________________________________________________________________________________________|
mw.loader.load('//en.wikipedia.org/w/index.php?action=raw&title=MediaWiki:Gadget-navpop.css&ctype=text/css', "text/css");
// Forked from [[:w:MediaWiki:Gadget-popups.js]]
$(function () {
//////////////////////////////////////////////////
// Globals
//
// Trying to shove as many of these as possible into the pg (popup globals) object
var pg = {
re: {}, // regexps
ns: {}, // namespaces
string: {}, // translatable strings
wiki: {}, // local site info
user: {}, // current user info
misc: {}, // YUCK PHOOEY
option: {}, // options, see newOption etc
optionDefault: {}, // default option values
flag: {}, // misc flags
cache: {}, // page and image cache
structures: {}, // navlink structures
timer: {}, // all sorts of timers (too damn many)
counter: {}, // .. and all sorts of counters
current: {}, // state info
fn: {}, // functions
endoflist: null
};
/* Bail if the gadget/script is being loaded twice */
if( window.pg ) {
return;
}
/* Export to global context */
window.pg = pg;
/// Local Variables: ///
/// mode:c ///
/// End: ///
// ENDFILE: main.js
// STARTFILE: actions.js
function setupTooltips(container, remove, force, popData) {
log('setupTooltips, container='+container+', remove='+remove);
if (!container) {
//<NOLITE>
// the main initial call
if (getValueOf('popupOnEditSelection') && document && document.editform && document.editform.wpTextbox1) {
document.editform.wpTextbox1.onmouseup=doSelectionPopup;
}
//</NOLITE>
// article/content is a structure-dependent thing
container = defaultPopupsContainer();
}
if (!remove && !force && container.ranSetupTooltipsAlready) { return; }
container.ranSetupTooltipsAlready = !remove;
var anchors;
anchors=container.getElementsByTagName('A');
setupTooltipsLoop(anchors, 0, 250, 100, remove, popData);
}
function defaultPopupsContainer() {
if (getValueOf('popupOnlyArticleLinks')) {
return document.getElementById('mw_content') ||
document.getElementById('content') ||
document.getElementById('article') || document;
}
return document;
}
function setupTooltipsLoop(anchors,begin,howmany,sleep, remove, popData) {
log(simplePrintf('setupTooltipsLoop(%s,%s,%s,%s,%s)', arguments));
var finish=begin+howmany;
var loopend = Math.min(finish, anchors.length);
var j=loopend - begin;
log ('setupTooltips: anchors.length=' + anchors.length + ', begin=' + begin +
', howmany=' + howmany + ', loopend=' + loopend + ', remove=' + remove);
var doTooltip= remove ? removeTooltip : addTooltip;
// try a faster (?) loop construct
if (j > 0) {
do {
var a=anchors[loopend - j];
if (typeof a==='undefined' || !a || !a.href) {
log('got null anchor at index ' + loopend - j);
continue;
}
doTooltip(a, popData);
} while (--j);
}
if (finish < anchors.length) {
setTimeout(function() {
setupTooltipsLoop(anchors,finish,howmany,sleep,remove,popData);},
sleep);
} else {
if ( !remove && ! getValueOf('popupTocLinks')) { rmTocTooltips(); }
pg.flag.finishedLoading=true;
}
}
// eliminate popups from the TOC
// This also kills any onclick stuff that used to be going on in the toc
function rmTocTooltips() {
var toc=document.getElementById('toc');
if (toc) {
var tocLinks=toc.getElementsByTagName('A');
var tocLen = tocLinks.length;
for (var j=0; j<tocLen; ++j) {
removeTooltip(tocLinks[j], true);
}
}
}
function addTooltip(a, popData) {
if ( !isPopupLink(a) ) { return; }
a.onmouseover=mouseOverWikiLink;
a.onmouseout= mouseOutWikiLink;
a.onmousedown = killPopup;
a.hasPopup = true;
a.popData = popData;
}
function removeTooltip(a) {
if ( !a.hasPopup ) { return; }
a.onmouseover = null;
a.onmouseout = null;
if (a.originalTitle) { a.title = a.originalTitle; }
a.hasPopup=false;
}
function removeTitle(a) {
if (!a.originalTitle) {
a.originalTitle=a.title;
}
a.title='';
}
function restoreTitle(a) {
if ( a.title || !a.originalTitle ) { return; }
a.title = a.originalTitle;
}
function registerHooks(np) {
var popupMaxWidth=getValueOf('popupMaxWidth');
if (typeof popupMaxWidth === 'number') {
var setMaxWidth = function () {
np.mainDiv.style.maxWidth = popupMaxWidth + 'px';
np.maxWidth = popupMaxWidth;
};
np.addHook(setMaxWidth, 'unhide', 'before');
}
//<NOLITE>
np.addHook(addPopupShortcuts, 'unhide', 'after');
np.addHook(rmPopupShortcuts, 'hide', 'before');
//</NOLITE>
}
function removeModifierKeyHandler(a) {
//remove listeners for modifier key if any that were added in mouseOverWikiLink
document.removeEventListener('keydown', a.modifierKeyHandler, false);
document.removeEventListener('keyup', a.modifierKeyHandler, false);
}
function mouseOverWikiLink(evt) {
if (!evt && window.event) {evt=window.event;}
// if the modifier is needed, listen for it,
// we will remove the listener when we mouseout of this link or kill popup.
if (getValueOf('popupModifier')) {
// if popupModifierAction = enable, we should popup when the modifier is pressed
// if popupModifierAction = disable, we should popup unless the modifier is pressed
var action = getValueOf('popupModifierAction');
var key = action=='disable' ? 'keyup' : 'keydown';
var a = this;
a.modifierKeyHandler = function(evt) {
mouseOverWikiLink2(a, evt);
};
document.addEventListener(key, a.modifierKeyHandler, false);
}
return mouseOverWikiLink2(this, evt);
}
/**
* Gets the references list item that the provided footnote link targets. This
* is typically a li element within the ol.references element inside the reflist.
* @param {Element} a - A footnote link.
* @returns {Element|boolean} The targeted element, or false if one can't be found.
*/
function footnoteTarget(a) {
var aTitle=Title.fromAnchor(a);
// We want ".3A" rather than "%3A" or "?" here, so use the anchor property directly
var anch = aTitle.anchor;
if ( ! /^(cite_note-|_note-|endnote)/.test(anch) ) { return false; }
var lTitle=Title.fromURL(location.href);
if ( lTitle.toString(true) !== aTitle.toString(true) ) { return false; }
var el=document.getElementById(anch);
while ( el && typeof el.nodeName === 'string') {
var nt = el.nodeName.toLowerCase();
if ( nt === 'li' ) { return el; }
else if ( nt === 'body' ) { return false; }
else if ( el.parentNode ) { el=el.parentNode; }
else { return false; }
}
return false;
}
function footnotePreview(x, navpop) {
setPopupHTML('<hr />' + x.innerHTML, 'popupPreview', navpop.idNumber);
}
function modifierPressed(evt) {
var mod=getValueOf('popupModifier');
if (!mod) { return false; }
if (!evt && window.event) {evt=window.event;}
return ( evt && mod && evt[mod.toLowerCase() + 'Key'] );
}
// Checks if the correct modifier pressed/unpressed if needed
function isCorrectModifier(a,evt) {
if (!getValueOf('popupModifier')) { return true; }
// if popupModifierAction = enable, we should popup when the modifier is pressed
// if popupModifierAction = disable, we should popup unless the modifier is pressed
var action = getValueOf('popupModifierAction');
return ( action == 'enable' && modifierPressed(evt) ||
action == 'disable' && !modifierPressed(evt) );
}
function mouseOverWikiLink2(a, evt) {
if (!isCorrectModifier(a,evt)) { return; }
if ( getValueOf('removeTitles') ) { removeTitle(a); }
if ( a==pg.current.link && a.navpopup && a.navpopup.isVisible() ) { return; }
pg.current.link=a;
if (getValueOf('simplePopups') && !pg.option.popupStructure) {
// reset *default value* of popupStructure
setDefault('popupStructure', 'original');
}
var article=(new Title()).fromAnchor(a);
// set global variable (ugh) to hold article (wikipage)
pg.current.article = article;
if (!a.navpopup) {
a.navpopup=newNavpopup(a, article);
pg.current.linksHash[a.href] = a.navpopup;
pg.current.links.push(a);
}
if (a.navpopup.pending === null || a.navpopup.pending !== 0) {
// either fresh popups or those with unfinshed business are redone from scratch
simplePopupContent(a, article);
}
a.navpopup.showSoonIfStable(a.navpopup.delay);
clearInterval(pg.timer.checkPopupPosition);
pg.timer.checkPopupPosition=setInterval(checkPopupPosition, 600);
if(getValueOf('simplePopups')) {
if (getValueOf('popupPreviewButton') && !a.simpleNoMore) {
var d=document.createElement('div');
d.className='popupPreviewButtonDiv';
var s=document.createElement('span');
d.appendChild(s);
s.className='popupPreviewButton';
s['on' + getValueOf('popupPreviewButtonEvent')] = function() {
a.simpleNoMore=true;
d.style.display = "none";
nonsimplePopupContent(a,article);
};
s.innerHTML=popupString('show preview');
setPopupHTML(d, 'popupPreview', a.navpopup.idNumber);
}
}
if (a.navpopup.pending !== 0 ) {
nonsimplePopupContent(a, article);
}
}
// simplePopupContent: the content that do not require additional download
// (it is shown even when simplePopups is true)
function simplePopupContent(a, article) {
/* FIXME hack */ a.navpopup.hasPopupMenu=false;
a.navpopup.setInnerHTML(popupHTML(a));
fillEmptySpans({navpopup:a.navpopup});
if (getValueOf('popupDraggable'))
{
var dragHandle = getValueOf('popupDragHandle') || null;
if (dragHandle && dragHandle != 'all') {
dragHandle += a.navpopup.idNumber;
}
setTimeout(function(){a.navpopup.makeDraggable(dragHandle);}, 150);
}
//<NOLITE>
if (getValueOf('popupRedlinkRemoval') && a.className=='new') {
setPopupHTML('<br>'+popupRedlinkHTML(article), 'popupRedlink', a.navpopup.idNumber);
}
//</NOLITE>
}
function debugData(navpopup) {
if(getValueOf('popupDebugging') && navpopup.idNumber) {
setPopupHTML('idNumber='+navpopup.idNumber + ', pending=' + navpopup.pending,
'popupError', navpopup.idNumber);
}
}
function newNavpopup(a, article) {
var navpopup = new Navpopup();
navpopup.fuzz=5;
navpopup.delay=getValueOf('popupDelay')*1000;
// increment global counter now
navpopup.idNumber = ++pg.idNumber;
navpopup.parentAnchor = a;
navpopup.parentPopup = (a.popData && a.popData.owner);
navpopup.article = article;
registerHooks(navpopup);
return navpopup;
}
// Should we show nonsimple context?
// If simplePopups is set to true, then we do not show nonsimple context,
// but if a bottom "show preview" was clicked we do show nonsimple context
function shouldShowNonSimple(a) {
return !getValueOf('simplePopups') || a.simpleNoMore;
}
// Should we show nonsimple context govern by the option (e.g. popupUserInfo)?
// If the user explicitly asked for nonsimple context by setting the option to true,
// then we show it even in nonsimple mode.
function shouldShow(a,option) {
if (shouldShowNonSimple(a)) {
return getValueOf(option);
} else {
return (typeof window[option] != 'undefined' ) && window[option];
}
}
function nonsimplePopupContent(a, article) {
var diff=null, history=null;
var params=parseParams(a.href);
var oldid=(typeof params.oldid=='undefined' ? null : params.oldid);
//<NOLITE>
if(shouldShow(a,'popupPreviewDiffs')) {
diff=params.diff;
}
if(shouldShow(a,'popupPreviewHistory')) {
history=(params.action=='history');
}
//</NOLITE>
a.navpopup.pending=0;
var referenceElement = footnoteTarget(a);
if (referenceElement) {
footnotePreview(referenceElement, a.navpopup);
//<NOLITE>
} else if ( diff || diff === 0 ) {
loadDiff(article, oldid, diff, a.navpopup);
} else if ( history ) {
loadAPIPreview('history', article, a.navpopup);
} else if ( shouldShowNonSimple(a) && pg.re.contribs.test(a.href) ) {
loadAPIPreview('contribs', article, a.navpopup);
} else if ( shouldShowNonSimple(a) && pg.re.backlinks.test(a.href) ) {
loadAPIPreview('backlinks', article, a.navpopup);
} else if ( // FIXME should be able to get all preview combinations with options
article.namespaceId()==pg.nsImageId &&
( shouldShow(a,'imagePopupsForImages') || ! anchorContainsImage(a) )
) {
loadAPIPreview('imagepagepreview', article, a.navpopup);
loadImage(article, a.navpopup);
//</NOLITE>
} else {
if (article.namespaceId() == pg.nsCategoryId &&
shouldShow(a,'popupCategoryMembers')) {
loadAPIPreview('category', article, a.navpopup);
} else if ((article.namespaceId() == pg.nsUserId || article.namespaceId() == pg.nsUsertalkId) &&
shouldShow(a,'popupUserInfo')) {
loadAPIPreview('userinfo', article, a.navpopup);
}
if (shouldShowNonSimple(a)) startArticlePreview(article, oldid, a.navpopup);
}
}
function pendingNavpopTask(navpop) {
if (navpop && navpop.pending === null) { navpop.pending=0; }
++navpop.pending;
debugData(navpop);
}
function completedNavpopTask(navpop) {
if (navpop && navpop.pending) { --navpop.pending; }
debugData(navpop);
}
function startArticlePreview(article, oldid, navpop) {
navpop.redir=0;
loadPreview(article, oldid, navpop);
}
function loadPreview(article, oldid, navpop) {
if (!navpop.redir) { navpop.originalArticle=article; }
article.oldid = oldid;
loadAPIPreview('revision', article, navpop);
}
function loadPreviewFromRedir(redirMatch, navpop) {
// redirMatch is a regex match
var target = new Title().fromWikiText(redirMatch[2]);
// overwrite (or add) anchor from original target
// mediawiki does overwrite; eg User:Lupin/foo3#Done
if ( navpop.article.anchor ) { target.anchor = navpop.article.anchor; }
navpop.redir++;
navpop.redirTarget=target;
//<NOLITE>
var warnRedir = redirLink(target, navpop.article);
setPopupHTML(warnRedir, 'popupWarnRedir', navpop.idNumber);
//</NOLITE>
navpop.article=target;
fillEmptySpans({redir: true, redirTarget: target, navpopup:navpop});
return loadPreview(target, null, navpop);
}
function insertPreview(download) {
if (!download.owner) { return; }
var redirMatch = pg.re.redirect.exec(download.data);
if (download.owner.redir === 0 && redirMatch) {
loadPreviewFromRedir(redirMatch, download.owner);
return;
}
if (download.owner.visible || !getValueOf('popupLazyPreviews')) {
insertPreviewNow(download);
} else {
var id=(download.owner.redir) ? 'PREVIEW_REDIR_HOOK' : 'PREVIEW_HOOK';
download.owner.addHook( function(){insertPreviewNow(download); return true;},
'unhide', 'after', id );
}
}
function insertPreviewNow(download) {
if (!download.owner) { return; }
var wikiText=download.data;
var navpop=download.owner;
var art=navpop.redirTarget || navpop.originalArticle;
//<NOLITE>
makeFixDabs(wikiText, navpop);
if (getValueOf('popupSummaryData')) {
getPageInfo(wikiText, download);
setPopupTrailer(getPageInfo(wikiText, download), navpop.idNumber);
}
var imagePage='';
if (art.namespaceId()==pg.nsImageId) { imagePage=art.toString(); }
else { imagePage=getValidImageFromWikiText(wikiText); }
if(imagePage) { loadImage(Title.fromWikiText(imagePage), navpop); }
//</NOLITE>
if (getValueOf('popupPreviews')) { insertArticlePreview(download, art, navpop); }
}
function insertArticlePreview(download, art, navpop) {
if (download && typeof download.data == typeof ''){
if (art.namespaceId()==pg.nsTemplateId && getValueOf('popupPreviewRawTemplates')) {
// FIXME compare/consolidate with diff escaping code for wikitext
var h='<hr /><span style="font-family: monospace;">' + download.data.entify().split('\\n').join('<br />\\n') + '</span>';
setPopupHTML(h, 'popupPreview', navpop.idNumber);
}
else {
var p=prepPreviewmaker(download.data, art, navpop);
p.showPreview();
}
}
}
function prepPreviewmaker(data, article, navpop) {
// deal with tricksy anchors
var d=anchorize(data, article.anchorString());
var urlBase=joinPath([pg.wiki.articlebase, article.urlString()]);
var p=new Previewmaker(d, urlBase, navpop);
return p;
}
// Try to imitate the way mediawiki generates HTML anchors from section titles
function anchorize(d, anch) {
if (!anch) { return d; }
var anchRe=RegExp('(?:=+\\s*' + literalizeRegex(anch).replace(/[_ ]/g, '[_ ]') + '\\s*=+|\\{\\{\\s*'+getValueOf('popupAnchorRegexp')+'\\s*(?:\\|[^|}]*)*?\\s*'+literalizeRegex(anch)+'\\s*(?:\\|[^}]*)?}})');
var match=d.match(anchRe);
if(match && match.length > 0 && match[0]) { return d.substring(d.indexOf(match[0])); }
// now try to deal with == foo [[bar|baz]] boom == -> #foo_baz_boom
var lines=d.split('\n');
for (var i=0; i<lines.length; ++i) {
lines[i]=lines[i].replace(RegExp('[[]{2}([^|\\]]*?[|])?(.*?)[\\]]{2}', 'g'), '$2')
.replace(/'''([^'])/g, '$1').replace(RegExp("''([^'])", 'g'), '$1');
if (lines[i].match(anchRe)) {
return d.split('\n').slice(i).join('\n').replace(RegExp('^[^=]*'), '');
}
}
return d;
}
function killPopup() {
removeModifierKeyHandler(this);
if (getValueOf('popupShortcutKeys')) { rmPopupShortcuts(); }
if (!pg) { return; }
if (pg.current.link && pg.current.link.navpopup) { pg.current.link.navpopup.banish(); }
pg.current.link=null;
abortAllDownloads();
if (pg.timer.checkPopupPosition) {
clearInterval(pg.timer.checkPopupPosition);
pg.timer.checkPopupPosition=null;
}
return true; // preserve default action
}
// ENDFILE: actions.js
// STARTFILE: domdrag.js
/**
@fileoverview
The {@link Drag} object, which enables objects to be dragged around.
<pre>
*************************************************
dom-drag.js
09.25.2001
www.youngpup.net
**************************************************
10.28.2001 - fixed minor bug where events
sometimes fired off the handle, not the root.
*************************************************
Pared down, some hooks added by User:Lupin
Copyright Aaron Boodman.
Saying stupid things daily since March 2001.
</pre>
*/
/**
Creates a new Drag object. This is used to make various DOM elements draggable.
@constructor
*/
function Drag () {
/**
Condition to determine whether or not to drag. This function should take one parameter, an Event.
To disable this, set it to <code>null</code>.
@type Function
*/
this.startCondition = null;
/**
Hook to be run when the drag finishes. This is passed the final coordinates of
the dragged object (two integers, x and y). To disables this, set it to <code>null</code>.
@type Function
*/
this.endHook = null;
}
/**
Gets an event in a cross-browser manner.
@param {Event} e
@private
*/
Drag.prototype.fixE = function(e) {
if (typeof e == 'undefined') { e = window.event; }
if (typeof e.layerX == 'undefined') { e.layerX = e.offsetX; }
if (typeof e.layerY == 'undefined') { e.layerY = e.offsetY; }
return e;
};
/**
Initialises the Drag instance by telling it which object you want to be draggable, and what you want to drag it by.
@param {DOMElement} o The "handle" by which <code>oRoot</code> is dragged.
@param {DOMElement} oRoot The object which moves when <code>o</code> is dragged, or <code>o</code> if omitted.
*/
Drag.prototype.init = function(o, oRoot) {
var dragObj = this;
this.obj = o;
o.onmousedown = function(e) { dragObj.start.apply( dragObj, [e]); };
o.dragging = false;
o.popups_draggable = true;
o.hmode = true;
o.vmode = true;
o.root = oRoot ? oRoot : o ;
if (isNaN(parseInt(o.root.style.left, 10))) { o.root.style.left = "0px"; }
if (isNaN(parseInt(o.root.style.top, 10))) { o.root.style.top = "0px"; }
o.root.onthisStart = function(){};
o.root.onthisEnd = function(){};
o.root.onthis = function(){};
};
/**
Starts the drag.
@private
@param {Event} e
*/
Drag.prototype.start = function(e) {
var o = this.obj; // = this;
e = this.fixE(e);
if (this.startCondition && !this.startCondition(e)) { return; }
var y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10);
o.root.onthisStart(x, y);
o.lastMouseX = e.clientX;
o.lastMouseY = e.clientY;
var dragObj = this;
o.onmousemoveDefault = document.onmousemove;
o.dragging = true;
document.onmousemove = function(e) { dragObj.drag.apply( dragObj, [e] ); };
document.onmouseup = function(e) { dragObj.end.apply( dragObj, [e] ); };
return false;
};
/**
Does the drag.
@param {Event} e
@private
*/
Drag.prototype.drag = function(e) {
e = this.fixE(e);
var o = this.obj;
var ey = e.clientY;
var ex = e.clientX;
var y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10 );
var nx, ny;
nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));
this.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
this.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
this.obj.lastMouseX = ex;
this.obj.lastMouseY = ey;
this.obj.root.onthis(nx, ny);
return false;
};
/**
Ends the drag.
@private
*/
Drag.prototype.end = function() {
document.onmousemove=this.obj.onmousemoveDefault;
document.onmouseup = null;
this.obj.dragging = false;
if (this.endHook) {
this.endHook( parseInt(this.obj.root.style[this.obj.hmode ? "left" : "right"], 10),
parseInt(this.obj.root.style[this.obj.vmode ? "top" : "bottom"], 10));
}
};
// ENDFILE: domdrag.js
// STARTFILE: structures.js
//<NOLITE>
pg.structures.original={};
pg.structures.original.popupLayout=function () {
return ['popupError', 'popupImage', 'popupTopLinks', 'popupTitle',
'popupUserData', 'popupData', 'popupOtherLinks',
'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks',
'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'],
'popupMiscTools', ['popupRedlink'],
'popupPrePreviewSep', 'popupPreview', 'popupSecondPreview', 'popupPreviewMore', 'popupPostPreview', 'popupFixDab'];
};
pg.structures.original.popupRedirSpans=function () {
return ['popupRedir', 'popupWarnRedir', 'popupRedirTopLinks',
'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'];
};
pg.structures.original.popupTitle=function (x) {
log ('defaultstructure.popupTitle');
if (!getValueOf('popupNavLinks')) {
return navlinkStringToHTML('<b><<mainlink>></b>',x.article,x.params);
}
return '';
};
pg.structures.original.popupTopLinks=function (x) {
log ('defaultstructure.popupTopLinks');
if (getValueOf('popupNavLinks')) { return navLinksHTML(x.article, x.hint, x.params); }
return '';
};
pg.structures.original.popupImage=function(x) {
log ('original.popupImage, x.article='+x.article+', x.navpop.idNumber='+x.navpop.idNumber);
return imageHTML(x.article, x.navpop.idNumber);
};
pg.structures.original.popupRedirTitle=pg.structures.original.popupTitle;
pg.structures.original.popupRedirTopLinks=pg.structures.original.popupTopLinks;
function copyStructure(oldStructure, newStructure) {
pg.structures[newStructure]={};
for (var prop in pg.structures[oldStructure]) {
pg.structures[newStructure][prop]=pg.structures[oldStructure][prop];
}
}
copyStructure('original', 'nostalgia');
pg.structures.nostalgia.popupTopLinks=function(x) {
var str='';
str += '<b><<mainlink|shortcut= >></b>';
// user links
// contribs - log - count - email - block
// count only if applicable; block only if popupAdminLinks
str += 'if(user){<br><<contribs|shortcut=c>>';
str+='if(wikimedia){*<<count|shortcut=#>>}';
str+='if(ipuser){}else{*<<email|shortcut=E>>}if(admin){*<<block|shortcut=b>>}}';
// editing links
// talkpage -> edit|new - history - un|watch - article|edit
// other page -> edit - history - un|watch - talk|edit|new
var editstr='<<edit|shortcut=e>>';
var editOldidStr='if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr + '}';
var historystr='<<history|shortcut=h>>';
var watchstr='<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
str += '<br>if(talk){' +
editOldidStr+'|<<new|shortcut=+>>' + '*' + historystr+'*'+watchstr + '*' +
'<b><<article|shortcut=a>></b>|<<editArticle|edit>>' +
'}else{' + // not a talk page
editOldidStr + '*' + historystr + '*' + watchstr + '*' +
'<b><<talk|shortcut=t>></b>|<<editTalk|edit>>|<<newTalk|shortcut=+|new>>}';
// misc links
str += '<br><<whatLinksHere|shortcut=l>>*<<relatedChanges|shortcut=r>>';
str += 'if(admin){<br>}else{*}<<move|shortcut=m>>';
// admin links
str += 'if(admin){*<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*' +
'<<undelete|undeleteShort>>|<<delete|shortcut=d>>}';
return navlinkStringToHTML(str, x.article, x.params);
};
pg.structures.nostalgia.popupRedirTopLinks=pg.structures.nostalgia.popupTopLinks;
/** -- fancy -- **/
copyStructure('original', 'fancy');
pg.structures.fancy.popupTitle=function (x) {
return navlinkStringToHTML('<font size=+0><<mainlink>></font>',x.article,x.params);
};
pg.structures.fancy.popupTopLinks=function(x) {
var hist='<<history|shortcut=h|hist>>|<<lastEdit|shortcut=/|last>>|<<editors|shortcut=E|eds>>';
var watch='<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
var move='<<move|shortcut=m|move>>';
return navlinkStringToHTML('if(talk){' +
'<<edit|shortcut=e>>|<<new|shortcut=+|+>>*' + hist + '*' +
'<<article|shortcut=a>>|<<editArticle|edit>>' + '*' + watch + '*' + move +
'}else{<<edit|shortcut=e>>*' + hist +
'*<<talk|shortcut=t|>>|<<editTalk|edit>>|<<newTalk|shortcut=+|new>>' +
'*' + watch + '*' + move+'}<br>', x.article, x.params);
};
pg.structures.fancy.popupOtherLinks=function(x) {
var admin='<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*<<undelete|undeleteShort>>|<<delete|shortcut=d|del>>';
var user='<<contribs|shortcut=c>>if(wikimedia){|<<count|shortcut=#|#>>}';
user+='if(ipuser){|<<arin>>}else{*<<email|shortcut=E|'+
popupString('email')+'>>}if(admin){*<<block|shortcut=b>>}';
var normal='<<whatLinksHere|shortcut=l|links here>>*<<relatedChanges|shortcut=r|related>>';
return navlinkStringToHTML('<br>if(user){' + user + '*}if(admin){'+admin+'if(user){<br>}else{*}}' + normal,
x.article, x.params);
};
pg.structures.fancy.popupRedirTitle=pg.structures.fancy.popupTitle;
pg.structures.fancy.popupRedirTopLinks=pg.structures.fancy.popupTopLinks;
pg.structures.fancy.popupRedirOtherLinks=pg.structures.fancy.popupOtherLinks;
/** -- fancy2 -- **/
// hack for User:MacGyverMagic
copyStructure('fancy', 'fancy2');
pg.structures.fancy2.popupTopLinks=function(x) { // hack out the <br> at the end and put one at the beginning
return '<br>'+pg.structures.fancy.popupTopLinks(x).replace(RegExp('<br>$','i'),'');
};
pg.structures.fancy2.popupLayout=function () { // move toplinks to after the title
return ['popupError', 'popupImage', 'popupTitle', 'popupUserData', 'popupData', 'popupTopLinks', 'popupOtherLinks',
'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'],
'popupMiscTools', ['popupRedlink'],
'popupPrePreviewSep', 'popupPreview', 'popupSecondPreview', 'popupPreviewMore', 'popupPostPreview', 'popupFixDab'];
};
/** -- menus -- **/
copyStructure('original', 'menus');
pg.structures.menus.popupLayout=function () {
return ['popupError', 'popupImage', 'popupTopLinks', 'popupTitle', 'popupOtherLinks',
'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'],
'popupUserData', 'popupData', 'popupMiscTools', ['popupRedlink'],
'popupPrePreviewSep', 'popupPreview', 'popupSecondPreview', 'popupPreviewMore', 'popupPostPreview', 'popupFixDab'];
};
pg.structures.menus.popupTopLinks = function (x, shorter) {
// FIXME maybe this stuff should be cached
var s=[];
var dropdiv='<div class="popup_drop">';
var enddiv='</div>';
var hist='<<history|shortcut=h>>';
if (!shorter) { hist = '<menurow>' + hist +
'|<<historyfeed|rss>>|<<editors|shortcut=E>></menurow>'; }
var lastedit='<<lastEdit|shortcut=/|show last edit>>';
var thank='if(diff){<<thank|send thanks>>}';
var jsHistory='<<lastContrib|last set of edits>><<sinceMe|changes since mine>>';
var linkshere='<<whatLinksHere|shortcut=l|what links here>>';
var related='<<relatedChanges|shortcut=r|related changes>>';
var search='<menurow><<search|shortcut=s>>if(wikimedia){|<<globalsearch|shortcut=g|global>>}' +
'|<<google|shortcut=G|web>></menurow>';
var watch='<menurow><<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>></menurow>';
var protect='<menurow><<unprotect|unprotectShort>>|' +
'<<protect|shortcut=p>>|<<protectlog|log>></menurow>';
var del='<menurow><<undelete|undeleteShort>>|<<delete|shortcut=d>>|' +
'<<deletelog|log>></menurow>';
var move='<<move|shortcut=m|move page>>';
var nullPurge='<menurow><<nullEdit|shortcut=n|null edit>>|<<purge|shortcut=P>></menurow>';
var viewOptions='<menurow><<view|shortcut=v>>|<<render|shortcut=S>>|<<raw>></menurow>';
var editRow='if(oldid){' +
'<menurow><<edit|shortcut=e>>|<<editOld|shortcut=e|this revision>></menurow>' +
'<menurow><<revert|shortcut=v>>|<<undo>></menurow>' + '}else{<<edit|shortcut=e>>}';
var markPatrolled='if(rcid){<<markpatrolled|mark patrolled>>}';
var newTopic='if(talk){<<new|shortcut=+|new topic>>}';
var protectDelete='if(admin){' + protect + del + '}';
if (getValueOf('popupActionsMenu')) {
s.push( '<<mainlink>>*' + dropdiv + menuTitle('tác vụ'));
} else {
s.push( dropdiv + '<<mainlink>>');
}
s.push( '<menu>');
s.push( editRow + markPatrolled + newTopic + hist + lastedit + thank );
if (!shorter) { s.push(jsHistory); }
s.push( move + linkshere + related);
if (!shorter) { s.push(nullPurge + search); }
if (!shorter) { s.push(viewOptions); }
s.push('<hr />' + watch + protectDelete);
s.push('<hr />' +
'if(talk){<<article|shortcut=a|view article>><<editArticle|edit article>>}' +
'else{<<talk|shortcut=t|talk page>><<editTalk|edit talk>>' +
'<<newTalk|shortcut=+|new topic>>}</menu>' + enddiv);
// user menu starts here
var email='<<email|shortcut=E|email user>>';
var contribs= 'if(wikimedia){<menurow>}<<contribs|shortcut=c|contributions>>if(wikimedia){</menurow>}' +
'if(admin){<menurow><<deletedContribs>></menurow>}';
s.push('if(user){*' + dropdiv + menuTitle('user'));
s.push('<menu>');
s.push('<menurow><<userPage|shortcut=u|user page>>|<<userSpace|space>></menurow>');
s.push('<<userTalk|shortcut=t|user talk>><<editUserTalk|edit user talk>>' +
'<<newUserTalk|shortcut=+|leave comment>>');
if(!shorter) { s.push( 'if(ipuser){<<arin>>}else{' + email + '}' ); }
else { s.push( 'if(ipuser){}else{' + email + '}' ); }
s.push('<hr />' + contribs + '<<userlog|shortcut=L|user log>>');
s.push('if(wikimedia){<<count|shortcut=#|edit counter>>}');
s.push('if(admin){<menurow><<unblock|unblockShort>>|<<block|shortcut=b|block user>></menurow>}');
s.push('<<blocklog|shortcut=B|block log>>');
s.push('</menu>' + enddiv + '}');
// popups menu starts here
if (getValueOf('popupSetupMenu') && !x.navpop.hasPopupMenu /* FIXME: hack */) {
x.navpop.hasPopupMenu=true;
s.push('*' + dropdiv + menuTitle('popupsMenu') + '<menu>');
s.push('<<togglePreviews|toggle previews>>');
s.push('<<purgePopups|reset>>');
s.push('<<disablePopups|disable>>');
s.push('</menu>'+enddiv);
}
return navlinkStringToHTML(s.join(''), x.article, x.params);
};
function menuTitle(s) {
return '<a href="#" noPopup=1>' + popupString(s) + '</a>';
}
pg.structures.menus.popupRedirTitle=pg.structures.menus.popupTitle;
pg.structures.menus.popupRedirTopLinks=pg.structures.menus.popupTopLinks;
copyStructure('menus', 'shortmenus');
pg.structures.shortmenus.popupTopLinks=function(x) {
return pg.structures.menus.popupTopLinks(x,true);
};
pg.structures.shortmenus.popupRedirTopLinks=pg.structures.shortmenus.popupTopLinks;
//</NOLITE>
pg.structures.lite={};
pg.structures.lite.popupLayout=function () {
return ['popupTitle', 'popupPreview' ];
};
pg.structures.lite.popupTitle=function (x) {
log (x.article + ': structures.lite.popupTitle');
//return navlinkStringToHTML('<b><<mainlink>></b>',x.article,x.params);
return '<div><span class="popup_mainlink"><b>' + x.article.toString() + '</b></span></div>';
};
// ENDFILE: structures.js
// STARTFILE: autoedit.js
//<NOLITE>
function substitute(data,cmdBody) {
// alert('sub\nfrom: '+cmdBody.from+'\nto: '+cmdBody.to+'\nflags: '+cmdBody.flags);
var fromRe=RegExp(cmdBody.from, cmdBody.flags);
return data.replace(fromRe, cmdBody.to);
}
function execCmds(data, cmdList) {
for (var i=0; i<cmdList.length; ++i) {
data=cmdList[i].action(data, cmdList[i]);
}
return data;
}
function parseCmd(str) {
// returns a list of commands
if (!str.length) { return []; }
var p=false;
switch (str.charAt(0)) {
case 's':
p=parseSubstitute(str);
break;
default:
return false;
}
if (p) { return [p].concat(parseCmd(p.remainder)); }
return false;
}
function unEscape(str, sep) {
return str.split('\\\\').join('\\').split('\\'+sep).join(sep).split('\\n').join('\n');
}
function parseSubstitute(str) {
// takes a string like s/a/b/flags;othercmds and parses it
var from,to,flags,tmp;
if (str.length<4) { return false; }
var sep=str.charAt(1);
str=str.substring(2);
tmp=skipOver(str,sep);
if (tmp) { from=tmp.segment; str=tmp.remainder; }
else { return false; }
tmp=skipOver(str,sep);
if (tmp) { to=tmp.segment; str=tmp.remainder; }
else { return false; }
flags='';
if (str.length) {
tmp=skipOver(str,';') || skipToEnd(str, ';');
if (tmp) {flags=tmp.segment; str=tmp.remainder; }
}
return {action: substitute, from: from, to: to, flags: flags, remainder: str};
}
function skipOver(str,sep) {
var endSegment=findNext(str,sep);
if (endSegment<0) { return false; }
var segment=unEscape(str.substring(0,endSegment), sep);
return {segment: segment, remainder: str.substring(endSegment+1)};
}
/*eslint-disable*/
function skipToEnd(str,sep) {
return {segment: str, remainder: ''};
}
/*eslint-enable */
function findNext(str, ch) {
for (var i=0; i<str.length; ++i) {
if (str.charAt(i)=='\\') { i+=2; }
if (str.charAt(i)==ch) { return i; }
}
return -1;
}
function setCheckbox(param, box) {
var val=mw.util.getParamValue(param);
if (val) {
switch (val) {
case '1': case 'yes': case 'true':
box.checked=true;
break;
case '0': case 'no': case 'false':
box.checked=false;
}
}
}
function autoEdit() {
setupPopups( function () {
if (mw.util.getParamValue('autoimpl') !== popupString('autoedit_version') ) { return false; }
if (mw.util.getParamValue('autowatchlist') && mw.util.getParamValue('actoken')===autoClickToken()) {
pg.fn.modifyWatchlist(mw.util.getParamValue('title'), mw.util.getParamValue('action'));
}
if (!document.editform) { return false; }
if (autoEdit.alreadyRan) { return false; }
autoEdit.alreadyRan=true;
var cmdString=mw.util.getParamValue('autoedit');
if (cmdString) {
try {
var editbox=document.editform.wpTextbox1;
var cmdList=parseCmd(cmdString);
var input=editbox.value;
var output=execCmds(input, cmdList);
editbox.value=output;
} catch (dang) { return; }
// wikEd user script compatibility
if (typeof(wikEdUseWikEd) != 'undefined') {
if (wikEdUseWikEd === true) {
WikEdUpdateFrame();
}
}
}
setCheckbox('autominor', document.editform.wpMinoredit);
setCheckbox('autowatch', document.editform.wpWatchthis);
var rvid = mw.util.getParamValue('autorv');
if (rvid) {
var url=pg.wiki.apiwikibase + '?action=query&format=json&formatversion=2&prop=revisions&revids='+rvid;
startDownload(url, null, autoEdit2);
} else { autoEdit2(); }
} );
}
function autoEdit2(d) {
var summary=mw.util.getParamValue('autosummary');
var summaryprompt=mw.util.getParamValue('autosummaryprompt');
var summarynotice='';
if (d && d.data && mw.util.getParamValue('autorv')) {
var s = getRvSummary(summary, d.data);
if (s === false) {
summaryprompt=true;
summarynotice=popupString('Failed to get revision information, please edit manually.\n\n');
summary = simplePrintf(summary, [mw.util.getParamValue('autorv'), '(unknown)', '(unknown)']);
} else { summary = s; }
}
if (summaryprompt) {
var txt= summarynotice +
popupString('Enter a non-empty edit summary or press cancel to abort');
var response=prompt(txt, summary);
if (response) { summary=response; }
else { return; }
}
if (summary) { document.editform.wpSummary.value=summary; }
// Attempt to avoid possible premature clicking of the save button
// (maybe delays in updates to the DOM are to blame?? or a red herring)
setTimeout(autoEdit3, 100);
}
function autoClickToken() {
return mw.user.sessionId();
}
function autoEdit3() {
if( mw.util.getParamValue('actoken') != autoClickToken()) { return; }
var btn=mw.util.getParamValue('autoclick');
if (btn) {
if (document.editform && document.editform[btn]) {
var button=document.editform[btn];
var msg=tprintf('The %s button has been automatically clicked. Please wait for the next page to load.',
[ button.value ]);
bannerMessage(msg);
document.title='('+document.title+')';
button.click();
} else {
alert(tprintf('Could not find button %s. Please check the settings in your javascript file.',
[ btn ]));
}
}
}
function bannerMessage(s) {
var headings=document.getElementsByTagName('h1');
if (headings) {
var div=document.createElement('div');
div.innerHTML='<font size=+1><b>' + s + '</b></font>';
headings[0].parentNode.insertBefore(div, headings[0]);
}
}
function getRvSummary(template, json) {
try {
var o=getJsObj(json);
var edit = anyChild(o.query.pages).revisions[0];
var timestamp = edit.timestamp.split(/[A-Z]/g).join(' ').replace(/^ *| *$/g, '');
return simplePrintf(template, [edit.revid, timestamp, edit.userhidden ? '(hidden)' : edit.user ]);
} catch (badness) {
return false;
}
}
//</NOLITE>
// ENDFILE: autoedit.js
// STARTFILE: downloader.js
/**
@fileoverview
{@link Downloader}, a xmlhttprequest wrapper, and helper functions.
*/
/**
Creates a new Downloader
@constructor
@class The Downloader class. Create a new instance of this class to download stuff.
@param {String} url The url to download. This can be omitted and supplied later.
*/
function Downloader(url) {
if (typeof XMLHttpRequest!='undefined') { this.http = new XMLHttpRequest(); }
/**
The url to download
@type String
*/
this.url = url;
/**
A universally unique ID number
@type integer
*/
this.id=null;
/**
Modification date, to be culled from the incoming headers
@type Date
@private
*/
this.lastModified = null;
/**
What to do when the download completes successfully
@type Function
@private
*/
this.callbackFunction = null;
/**
What to do on failure
@type Function
@private
*/
this.onFailure = null;
/**
Flag set on <code>abort</code>
@type boolean
*/
this.aborted = false;
/**
HTTP method. See https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html for possibilities.
@type String
*/
this.method='GET';
/**
Async flag.
@type boolean
*/
this.async=true;
}
new Downloader();
/** Submits the http request. */
Downloader.prototype.send = function (x) {
if (!this.http) { return null; }
return this.http.send(x);
};
/** Aborts the download, setting the <code>aborted</code> field to true. */
Downloader.prototype.abort = function () {
if (!this.http) { return null; }
this.aborted=true;
return this.http.abort();
};
/** Returns the downloaded data. */
Downloader.prototype.getData = function () {if (!this.http) { return null; } return this.http.responseText;};
/** Prepares the download. */
Downloader.prototype.setTarget = function () {
if (!this.http) { return null; }
this.http.open(this.method, this.url, this.async);
this.http.setRequestHeader( 'Api-User-Agent', pg.misc.userAgent );
};
/** Gets the state of the download. */
Downloader.prototype.getReadyState=function () {if (!this.http) { return null; } return this.http.readyState;};
pg.misc.downloadsInProgress = { };
/** Starts the download.
Note that setTarget {@link Downloader#setTarget} must be run first
*/
Downloader.prototype.start=function () {
if (!this.http) { return; }
pg.misc.downloadsInProgress[this.id] = this;
this.http.send(null);
};
/** Gets the 'Last-Modified' date from the download headers.
Should be run after the download completes.
Returns <code>null</code> on failure.
@return {Date}
*/
Downloader.prototype.getLastModifiedDate=function () {
if(!this.http) { return null; }
var lastmod=null;
try {
lastmod=this.http.getResponseHeader('Last-Modified');
} catch (err) {}
if (lastmod) { return new Date(lastmod); }
return null;
};
/** Sets the callback function.
@param {Function} f callback function, called as <code>f(this)</code> on success
*/
Downloader.prototype.setCallback = function (f) {
if(!this.http) { return; }
this.http.onreadystatechange = f;
};
Downloader.prototype.getStatus = function() { if (!this.http) { return null; } return this.http.status; };
//////////////////////////////////////////////////
// helper functions
/** Creates a new {@link Downloader} and prepares it for action.
@param {String} url The url to download
@param {integer} id The ID of the {@link Downloader} object
@param {Function} callback The callback function invoked on success
@return {String/Downloader} the {@link Downloader} object created, or 'ohdear' if an unsupported browser
*/
function newDownload(url, id, callback, onfailure) {
var d=new Downloader(url);
if (!d.http) { return 'ohdear'; }
d.id=id;
d.setTarget();
if (!onfailure) {
onfailure=2;
}
var f = function () {
if (d.getReadyState() == 4) {
delete pg.misc.downloadsInProgress[this.id];
try {
if ( d.getStatus() == 200 ) {
d.data=d.getData();
d.lastModified=d.getLastModifiedDate();
callback(d);
} else if (typeof onfailure == typeof 1) {
if (onfailure > 0) {
// retry
newDownload(url, id, callback, onfailure - 1);
}
} else if (typeof onfailure === 'function') {
onfailure(d,url,id,callback);
}
} catch (somerr) { /* ignore it */ }
}
};
d.setCallback(f);
return d;
}
/** Simulates a download from cached data.
The supplied data is put into a {@link Downloader} as if it had downloaded it.
@param {String} url The url.
@param {integer} id The ID.
@param {Function} callback The callback, which is invoked immediately as <code>callback(d)</code>,
where <code>d</code> is the new {@link Downloader}.
@param {String} data The (cached) data.
@param {Date} lastModified The (cached) last modified date.
*/
function fakeDownload(url, id, callback, data, lastModified, owner) {
var d=newDownload(url,callback);
d.owner=owner;
d.id=id; d.data=data;
d.lastModified=lastModified;
return callback(d);
}
/**
Starts a download.
@param {String} url The url to download
@param {integer} id The ID of the {@link Downloader} object
@param {Function} callback The callback function invoked on success
@return {String/Downloader} the {@link Downloader} object created, or 'ohdear' if an unsupported browser
*/
function startDownload(url, id, callback) {
var d=newDownload(url, id, callback);
if (typeof d == typeof '' ) { return d; }
d.start();
return d;
}
/**
Aborts all downloads which have been started.
*/
function abortAllDownloads() {
for ( var x in pg.misc.downloadsInProgress ) {
try {
pg.misc.downloadsInProgress[x].aborted=true;
pg.misc.downloadsInProgress[x].abort();
delete pg.misc.downloadsInProgress[x];
} catch (e) {}
}
}
// ENDFILE: downloader.js
// STARTFILE: livepreview.js
// TODO: location is often not correct (eg relative links in previews)
// NOTE: removed md5 and image and math parsing. was broken, lots of bytes.
/**
* InstaView - a Mediawiki to HTML converter in JavaScript
* Version 0.6.1
* Copyright (C) Pedro Fayolle 2005-2006
* https://en.wikipedia.org/wiki/User:Pilaf
* Distributed under the BSD license
*
* Changelog:
*
* 0.6.1
* - Fixed problem caused by \r characters
* - Improved inline formatting parser
*
* 0.6
* - Changed name to InstaView
* - Some major code reorganizations and factored out some common functions
* - Handled conversion of relative links (i.e. [[/foo]])
* - Fixed misrendering of adjacent definition list items
* - Fixed bug in table headings handling
* - Changed date format in signatures to reflect Mediawiki's
* - Fixed handling of [[:Image:...]]
* - Updated MD5 function (hopefully it will work with UTF-8)
* - Fixed bug in handling of links inside images
*
* To do:
* - Better support for math tags
* - Full support for <nowiki>
* - Parser-based (as opposed to RegExp-based) inline wikicode handling (make it one-pass and bullet-proof)
* - Support for templates (through AJAX)
* - Support for coloured links (AJAX)
*/
var Insta = {};
function setupLivePreview() {
// options
Insta.conf =
{
baseUrl: '',
user: {},
wiki: {
lang: pg.wiki.lang,
interwiki: pg.wiki.interwiki,
default_thumb_width: 180
},
paths: {
articles: pg.wiki.articlePath + '/',
// Only used for Insta previews with images. (not in popups)
math: '/math/',
images: '//upload.wikimedia.org/wikipedia/en/', // FIXME getImageUrlStart(pg.wiki.hostname),
images_fallback: '//upload.wikimedia.org/wikipedia/commons/',
},
locale: {
user: mw.config.get('wgFormattedNamespaces')[pg.nsUserId],
image: mw.config.get('wgFormattedNamespaces')[pg.nsImageId],
category: mw.config.get('wgFormattedNamespaces')[pg.nsCategoryId],
// shouldn't be used in popup previews, i think
months: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
}
};
// options with default values or backreferences
Insta.conf.user.name = Insta.conf.user.name || 'Wikipedian';
Insta.conf.user.signature = '[['+Insta.conf.locale.user+':'+Insta.conf.user.name+'|'+Insta.conf.user.name+']]';
//Insta.conf.paths.images = '//upload.wikimedia.org/wikipedia/' + Insta.conf.wiki.lang + '/';
// define constants
Insta.BLOCK_IMAGE = new RegExp('^\\[\\[(?:File|Image|'+Insta.conf.locale.image+
'):.*?\\|.*?(?:frame|thumbnail|thumb|none|right|left|center)', 'i');
}
Insta.dump = function(from, to)
{
if (typeof from == 'string') { from = document.getElementById(from); }
if (typeof to == 'string') { to = document.getElementById(to); }
to.innerHTML = this.convert(from.value);
};
Insta.convert = function(wiki)
{
var ll = (typeof wiki == 'string')? wiki.replace(/\r/g,'').split(/\n/): wiki, // lines of wikicode
o = '', // output
p = 0, // para flag
$r; // result of passing a regexp to $()
// some shorthands
function remain() { return ll.length; }
function sh() { return ll.shift(); } // shift
function ps(s) { o += s; } // push
// similar to C's printf, uses ? as placeholders, ?? to escape question marks
function f()
{
var i=1, a=arguments, f=a[0], o='', c, p;
for (; i<a.length; i++) {
if ((p=f.indexOf('?'))+1) {
// allow character escaping
i -= c = f.charAt(p+1)=='?' ? 1 : 0;
o += f.substring(0,p) + (c ? '?' : a[i]);
f = f.substr(p+1+c);
} else { break; }
}
return o+f;
}
function html_entities(s) {
return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
}
// Wiki text parsing to html is a nightmare.
// The below functions deliberately don't escape the ampersand since this would make it more difficult,
// and we don't absolutely need to for how we need it.
// This means that any unescaped ampersands in wikitext will remain unescaped and can cause invalid HTML.
// Browsers should all be able to handle it though.
// We also escape significant wikimarkup characters to prevent further matching on the processed text
function htmlescape_text(s) {
return s.replace(/</g,"<").replace(/>/g,">").replace(/:/g,":").replace(/\[/g,"[").replace(/]/g,"]");
}
function htmlescape_attr(s) {
return htmlescape_text(s).replace(/'/g,"'").replace(/"/g,""");
}
// return the first non matching character position between two strings
function str_imatch(a, b)
{
for (var i=0, l=Math.min(a.length, b.length); i<l; i++) {
if (a.charAt(i)!=b.charAt(i)) { break; }
}
return i;
}
// compare current line against a string or regexp
// if passed a string it will compare only the first string.length characters
// if passed a regexp the result is stored in $r
function $(c) { return (typeof c == 'string') ? (ll[0].substr(0,c.length)==c) : ($r = ll[0].match(c)); }
function $$(c) { return ll[0]==c; } // compare current line against a string
function _(p) { return ll[0].charAt(p); } // return char at pos p
function endl(s) { ps(s); sh(); }
function parse_list()
{
var prev='';
while (remain() && $(/^([*#:;]+)(.*)$/)) {
var l_match = $r;
sh();
var ipos = str_imatch(prev, l_match[1]);
// close uncontinued lists
for (var prevPos=prev.length-1; prevPos >= ipos; prevPos--) {
var pi = prev.charAt(prevPos);
if (pi=='*') { ps('</ul>'); }
else if (pi=='#') { ps('</ol>'); }
// close a dl only if the new item is not a dl item (:, ; or empty)
else if($.inArray(l_match[1].charAt(prevPos), ['','*','#'])) { ps('</dl>'); }
}
// open new lists
for (var matchPos=ipos; matchPos<l_match[1].length; matchPos++) {
var li = l_match[1].charAt(matchPos);
if (li=='*') { ps('<ul>'); }
else if (li=='#') { ps('<ol>'); }
// open a new dl only if the prev item is not a dl item (:, ; or empty)
else if ($.inArray(prev.charAt(matchPos), ['','*','#'])) { ps('<dl>'); }
}
switch (l_match[1].charAt(l_match[1].length-1)) {
case '*': case '#':
ps('<li>' + parse_inline_nowiki(l_match[2]));
break;
case ';':
ps('<dt>');
var dt_match = l_match[2].match(/(.*?)(:.*?)$/);
// handle ;dt :dd format
if (dt_match) {
ps(parse_inline_nowiki(dt_match[1]));
ll.unshift(dt_match[2]);
} else ps(parse_inline_nowiki(l_match[2]));
break;
case ':':
ps('<dd>' + parse_inline_nowiki(l_match[2]));
}
prev=l_match[1];
}
// close remaining lists
for (var i=prev.length-1; i>=0; i--) {
ps(f('</?>', (prev.charAt(i)=='*')? 'ul': ((prev.charAt(i)=='#')? 'ol': 'dl')));
}
}
function parse_table()
{
endl(f('<table>', $(/^\{\|( .*)$/)? $r[1]: ''));
for (;remain();) if ($('|')) switch (_(1)) {
case '}':
endl('</table>');
return;
case '-':
endl(f('<tr>', $(/\|-*(.*)/)[1]));
break;
default:
parse_table_data();
}
else if ($('!')) { parse_table_data(); }
else { sh(); }
}
function parse_table_data()
{
var td_line, match_i;
// 1: "|+", '|' or '+'
// 2: ??
// 3: attributes ??
// TODO: finish commenting this regexp
var td_match = sh().match(/^(\|\+|\||!)((?:([^[|]*?)\|(?!\|))?(.*))$/);
if (td_match[1] == '|+') ps('<caption');
else ps('<t' + ((td_match[1]=='|')?'d':'h'));
if (typeof td_match[3] != 'undefined') {
//ps(' ' + td_match[3])
match_i = 4;
} else match_i = 2;
ps('>');
if (td_match[1] != '|+') {
// use || or !! as a cell separator depending on context
// NOTE: when split() is passed a regexp make sure to use non-capturing brackets
td_line = td_match[match_i].split((td_match[1] == '|')? '||': /(?:\|\||!!)/);
ps(parse_inline_nowiki(td_line.shift()));
while (td_line.length) ll.unshift(td_match[1] + td_line.pop());
} else ps(td_match[match_i]);
var tc = 0, td = [];
while (remain()) {
td.push(sh());
if ($('|')) {
if (!tc) break; // we're at the outer-most level (no nested tables), skip to td parse
else if (_(1)=='}') tc--;
}
else if (!tc && $('!')) break;
else if ($('{|')) tc++;
}
if (td.length) ps(Insta.convert(td));
}
function parse_pre()
{
ps('<pre>');
do {
endl(parse_inline_nowiki(ll[0].substring(1)) + "\n");
} while (remain() && $(' '));
ps('</pre>');
}
function parse_block_image()
{
ps(parse_image(sh()));
}
function parse_image(str)
{
//<NOLITE>
// get what's in between "[[Image:" and "]]"
var tag = str.substring(str.indexOf(':') + 1, str.length - 2);
/* eslint-disable no-unused-vars */
var width;
var attr = [], filename, caption = '';
var thumb=0, frame=0, center=0;
var align='';
/* eslint-enable no-unused-vars */
if (tag.match(/\|/)) {
// manage nested links
var nesting = 0;
var last_attr;
for (var i = tag.length-1; i > 0; i--) {
if (tag.charAt(i) == '|' && !nesting) {
last_attr = tag.substr(i+1);
tag = tag.substring(0, i);
break;
} else switch (tag.substr(i-1, 2)) {
case ']]':
nesting++;
i--;
break;
case '[[':
nesting--;
i--;
}
}
attr = tag.split(/\s*\|\s*/);
attr.push(last_attr);
filename = attr.shift();
var w_match;
for (;attr.length; attr.shift()) {
w_match = attr[0].match(/^(\d*)(?:[px]*\d*)?px$/);
if (w_match) width = w_match[1];
else switch(attr[0]) {
case 'thumb':
case 'thumbnail':
thumb=true;
frame=true;
break;
case 'frame':
frame=true;
break;
case 'none':
case 'right':
case 'left':
center=false;
align=attr[0];
break;
case 'center':
center=true;
align='none';
break;
default:
if (attr.length == 1) caption = attr[0];
}
}
} else filename = tag;
return '';
//</NOLITE>
}
function parse_inline_nowiki(str)
{
var start, lastend=0;
var substart=0, nestlev=0, open, close, subloop;
var html='';
while (-1 != (start = str.indexOf('<nowiki>', substart))) {
html += parse_inline_wiki(str.substring(lastend, start));
start += 8;
substart = start;
subloop = true;
do {
open = str.indexOf('<nowiki>', substart);
close = str.indexOf('</nowiki>', substart);
if (close<=open || open==-1) {
if (close==-1) {
return html + html_entities(str.substr(start));
}
substart = close+9;
if (nestlev) {
nestlev--;
} else {
lastend = substart;
html += html_entities(str.substring(start, lastend-9));
subloop = false;
}
} else {
substart = open+8;
nestlev++;
}
} while (subloop);
}
return html + parse_inline_wiki(str.substr(lastend));
}
function parse_inline_images(str)
{
//<NOLITE>
var start, substart=0, nestlev=0;
var loop, close, open, wiki, html;
while (-1 != (start=str.indexOf('[[', substart))) {
if(str.substr(start+2).match(RegExp('^(Image|File|' + Insta.conf.locale.image + '):','i'))) {
loop=true;
substart=start;
do {
substart+=2;
close=str.indexOf(']]',substart);
open=str.indexOf('[[',substart);
if (close<=open||open==-1) {
if (close==-1) return str;
substart=close;
if (nestlev) {
nestlev--;
} else {
wiki=str.substring(start,close+2);
html=parse_image(wiki);
str=str.replace(wiki,html);
substart=start+html.length;
loop=false;
}
} else {
substart=open;
nestlev++;
}
} while (loop);
} else break;
}
//</NOLITE>
return str;
}
// the output of this function doesn't respect the FILO structure of HTML
// but since most browsers can handle it I'll save myself the hassle
function parse_inline_formatting(str)
{
var em,st,i,li,o='';
while ((i=str.indexOf("''",li))+1) {
o += str.substring(li,i);
li=i+2;
if (str.charAt(i+2)=="'") {
li++;
st=!st;
o+=st?'<strong>':'</strong>';
} else {
em=!em;
o+=em?'<em>':'</em>';
}
}
return o+str.substr(li);
}
function parse_inline_wiki(str)
{
str = parse_inline_images(str);
str = parse_inline_formatting(str);
// math
str = str.replace(/<(?:)math>(.*?)<\/math>/ig, '');
// Build a Mediawiki-formatted date string
var date = new Date();
var minutes = date.getUTCMinutes();
if (minutes < 10) minutes = '0' + minutes;
date = f("?:?, ? ? ? (UTC)", date.getUTCHours(), minutes, date.getUTCDate(), Insta.conf.locale.months[date.getUTCMonth()], date.getUTCFullYear());
// text formatting
return str.
// signatures
replace(/~{5}(?!~)/g, date).
replace(/~{4}(?!~)/g, Insta.conf.user.name+' '+date).
replace(/~{3}(?!~)/g, Insta.conf.user.name).
// [[:Category:...]], [[:Image:...]], etc...
replace(RegExp('\\[\\[:((?:'+Insta.conf.locale.category+'|Image|File|'+Insta.conf.locale.image+'|'+Insta.conf.wiki.interwiki+'):[^|]*?)\\]\\](\\w*)','gi'), function($0,$1,$2){return f("<a href='?'>?</a>", Insta.conf.paths.articles + htmlescape_attr($1), htmlescape_text($1) + htmlescape_text($2));}).
// remove straight category and interwiki tags
replace(RegExp('\\[\\[(?:'+Insta.conf.locale.category+'|'+Insta.conf.wiki.interwiki+'):.*?\\]\\]','gi'),'').
// [[:Category:...|Links]], [[:Image:...|Links]], etc...
replace(RegExp('\\[\\[:((?:'+Insta.conf.locale.category+'|Image|File|'+Insta.conf.locale.image+'|'+Insta.conf.wiki.interwiki+'):.*?)\\|([^\\]]+?)\\]\\](\\w*)','gi'), function($0,$1,$2,$3){return f("<a href='?'>?</a>", Insta.conf.paths.articles + htmlescape_attr($1), htmlescape_text($2) + htmlescape_text($3));}).
// [[/Relative links]]
replace(/\[\[(\/[^|]*?)\]\]/g, function($0,$1){return f("<a href='?'>?</a>", Insta.conf.baseUrl + htmlescape_attr($1), htmlescape_text($1)); }).
// [[/Replaced|Relative links]]
replace(/\[\[(\/.*?)\|(.+?)\]\]/g, function($0,$1,$2){return f("<a href='?'>?</a>", Insta.conf.baseUrl + htmlescape_attr($1), htmlescape_text($2)); }).
// [[Common links]]
replace(/\[\[([^[|]*?)\]\](\w*)/g, function($0,$1,$2){return f("<a href='?'>?</a>", Insta.conf.paths.articles + htmlescape_attr($1), htmlescape_text($1) + htmlescape_text($2)); }).
// [[Replaced|Links]]
replace(/\[\[([^[]*?)\|([^\]]+?)\]\](\w*)/g, function($0,$1,$2,$3){return f("<a href='?'>?</a>", Insta.conf.paths.articles + htmlescape_attr($1), htmlescape_text($2) + htmlescape_text($3)); }).
// [[Stripped:Namespace|Namespace]]
replace(/\[\[([^\]]*?:)?(.*?)( *\(.*?\))?\|\]\]/g, function($0,$1,$2,$3){return f("<a href='?'>?</a>", Insta.conf.paths.articles + htmlescape_attr($1) + htmlescape_attr($2) + htmlescape_attr($3), htmlescape_text($2)); }).
// External links
replace(/\[(https?|news|ftp|mailto|gopher|irc):(\/*)([^\]]*?) (.*?)\]/g, function($0,$1,$2,$3,$4){return f("<a class='external' href='?:?'>?</a>", htmlescape_attr($1), htmlescape_attr($2) + htmlescape_attr($3), htmlescape_text($4)); }).
replace(/\[http:\/\/(.*?)\]/g, function($0,$1){return f("<a class='external' href='http://?'>[#]</a>", htmlescape_attr($1)); }).
replace(/\[(news|ftp|mailto|gopher|irc):(\/*)(.*?)\]/g, function($0,$1,$2,$3){return f("<a class='external' href='?:?'>?:?</a>", htmlescape_attr($1), htmlescape_attr($2) + htmlescape_attr($3), htmlescape_text($1), htmlescape_text($2) + htmlescape_text($3)); }).
replace(/(^| )(https?|news|ftp|mailto|gopher|irc):(\/*)([^ $]*[^.,!?;: $])/g, function($0,$1,$2,$3,$4){return f("?<a class='external' href='?:?'>?:?</a>", htmlescape_text($1), htmlescape_attr($2), htmlescape_attr($3) + htmlescape_attr($4), htmlescape_text($2), htmlescape_text($3) + htmlescape_text($4)); }).
replace('__NOTOC__','').
replace('__NOEDITSECTION__','');
}
// begin parsing
for (;remain();) if ($(/^(={1,6})(.*)\1(.*)$/)) {
p=0;
endl(f('<h?>?</h?>?', $r[1].length, parse_inline_nowiki($r[2]), $r[1].length, $r[3]));
} else if ($(/^[*#:;]/)) {
p=0;
parse_list();
} else if ($(' ')) {
p=0;
parse_pre();
} else if ($('{|')) {
p=0;
parse_table();
} else if ($(/^----+$/)) {
p=0;
endl('<hr />');
} else if ($(Insta.BLOCK_IMAGE)) {
p=0;
parse_block_image();
} else {
// handle paragraphs
if ($$('')) {
p = (remain()>1 && ll[1]===(''));
if (p) endl('<p><br>');
} else {
if(!p) {
ps('<p>');
p=1;
}
ps(parse_inline_nowiki(ll[0]) + ' ');
}
sh();
}
return o;
};
function wiki2html(txt,baseurl) {
Insta.conf.baseUrl=baseurl;
return Insta.convert(txt);
}
// ENDFILE: livepreview.js
// STARTFILE: pageinfo.js
//<NOLITE>
function popupFilterPageSize(data) {
return formatBytes(data.length);
}
function popupFilterCountLinks(data) {
var num=countLinks(data);
return String(num) + ' ' + ((num!=1)?popupString('wikiLinks'):popupString('wikiLink'));
}
function popupFilterCountImages(data) {
var num=countImages(data);
return String(num) + ' ' + ((num!=1)?popupString('images'):popupString('image'));
}
function popupFilterCountCategories(data) {
var num=countCategories(data);
return String(num) + ' ' + ((num!=1)?popupString('categories'):popupString('category'));
}
function popupFilterLastModified(data,download) {
var lastmod=download.lastModified;
var now=new Date();
var age=now-lastmod;
if (lastmod && getValueOf('popupLastModified')) {
return (tprintf('%s old', [formatAge(age)])).replace(RegExp(' ','g'), ' ');
}
return '';
}
function formatAge(age) {
// coerce into a number
var a=0+age, aa=a;
var seclen = 1000;
var minlen = 60*seclen;
var hourlen = 60*minlen;
var daylen = 24*hourlen;
var weeklen = 7*daylen;
var numweeks = (a-a%weeklen)/weeklen; a = a-numweeks*weeklen; var sweeks = addunit(numweeks, 'week');
var numdays = (a-a%daylen)/daylen; a = a-numdays*daylen; var sdays = addunit(numdays, 'day');
var numhours = (a-a%hourlen)/hourlen; a = a-numhours*hourlen; var shours = addunit(numhours,'hour');
var nummins = (a-a%minlen)/minlen; a = a-nummins*minlen; var smins = addunit(nummins, 'minute');
var numsecs = (a-a%seclen)/seclen; a = a-numsecs*seclen; var ssecs = addunit(numsecs, 'second');
if (aa > 4*weeklen) { return sweeks; }
if (aa > weeklen) { return sweeks + ' ' + sdays; }
if (aa > daylen) { return sdays + ' ' + shours; }
if (aa > 6*hourlen) { return shours; }
if (aa > hourlen) { return shours + ' ' + smins; }
if (aa > 10*minlen) { return smins; }
if (aa > minlen) { return smins + ' ' + ssecs; }
return ssecs;
}
function addunit(num,str) { return '' + num + ' ' + ((num!=1) ? popupString(str+'s') : popupString(str)) ;}
function runPopupFilters(list, data, download) {
var ret=[];
for (var i=0; i<list.length; ++i) {
if (list[i] && typeof list[i] == 'function') {
var s=list[i](data, download, download.owner.article);
if (s) { ret.push(s); }
}
}
return ret;
}
function getPageInfo(data, download) {
if (!data || data.length === 0) { return popupString('Empty page'); }
var popupFilters=getValueOf('popupFilters') || [];
var extraPopupFilters = getValueOf('extraPopupFilters') || [];
var pageInfoArray = runPopupFilters(popupFilters.concat(extraPopupFilters), data, download);
var pageInfo=pageInfoArray.join(', ');
if (pageInfo !== '' ) { pageInfo = upcaseFirst(pageInfo); }
return pageInfo;
}
// this could be improved!
function countLinks(wikiText) { return wikiText.split('[[').length - 1; }
// if N = # matches, n = # brackets, then
// String.parenSplit(regex) intersperses the N+1 split elements
// with Nn other elements. So total length is
// L= N+1 + Nn = N(n+1)+1. So N=(L-1)/(n+1).
function countImages(wikiText) {
return (wikiText.parenSplit(pg.re.image).length - 1) / (pg.re.imageBracketCount + 1);
}
function countCategories(wikiText) {
return (wikiText.parenSplit(pg.re.category).length - 1) / (pg.re.categoryBracketCount + 1);
}
function popupFilterStubDetect(data, download, article) {
var counts=stubCount(data, article);
if (counts.real) { return popupString('stub'); }
if (counts.sect) { return popupString('section stub'); }
return '';
}
function popupFilterDisambigDetect(data, download, article) {
if (!getValueOf('popupAllDabsStubs') && article.namespace()) { return ''; }
return (isDisambig(data, article)) ? popupString('disambig') : '';
}
function formatBytes(num) {
return (num > 949) ? (Math.round(num/100)/10+popupString('kB')) : (num +' ' + popupString('bytes')) ;
}
//</NOLITE>
// ENDFILE: pageinfo.js
// STARTFILE: titles.js
/**
@fileoverview Defines the {@link Title} class, and associated crufty functions.
<code>Title</code> deals with article titles and their various
forms. {@link Stringwrapper} is the parent class of
<code>Title</code>, which exists simply to make things a little
neater.
*/
/**
Creates a new Stringwrapper.
@constructor
@class the Stringwrapper class. This base class is not really
useful on its own; it just wraps various common string operations.
*/
function Stringwrapper() {
/**
Wrapper for this.toString().indexOf()
@param {String} x
@type integer
*/
this.indexOf=function(x){return this.toString().indexOf(x);};
/**
Returns this.value.
@type String
*/
this.toString=function(){return this.value;};
/**
Wrapper for {@link String#parenSplit} applied to this.toString()
@param {RegExp} x
@type Array
*/
this.parenSplit=function(x){return this.toString().parenSplit(x);};
/**
Wrapper for this.toString().substring()
@param {String} x
@param {String} y (optional)
@type String
*/
this.substring=function(x,y){
if (typeof y=='undefined') { return this.toString().substring(x); }
return this.toString().substring(x,y);
};
/**
Wrapper for this.toString().split()
@param {String} x
@type Array
*/
this.split=function(x){return this.toString().split(x);};
/**
Wrapper for this.toString().replace()
@param {String} x
@param {String} y
@type String
*/
this.replace=function(x,y){ return this.toString().replace(x,y); };
}
/**
Creates a new <code>Title</code>.
@constructor
@class The Title class. Holds article titles and converts them into
various forms. Also deals with anchors, by which we mean the bits
of the article URL after a # character, representing locations
within an article.
@param {String} value The initial value to assign to the
article. This must be the canonical title (see {@link
Title#value}. Omit this in the constructor and use another function
to set the title if this is unavailable.
*/
function Title(val) {
/**
The canonical article title. This must be in UTF-8 with no
entities, escaping or nasties. Also, underscores should be
replaced with spaces.
@type String
@private
*/
this.value=null;
/**
The canonical form of the anchor. This should be exactly as
it appears in the URL, i.e. with the .C3.0A bits in.
@type String
*/
this.anchor='';
this.setUtf(val);
}
Title.prototype=new Stringwrapper();
/**
Returns the canonical representation of the article title, optionally without anchor.
@param {boolean} omitAnchor
@fixme Decide specs for anchor
@return String The article title and the anchor.
*/
Title.prototype.toString=function(omitAnchor) {
return this.value + ( (!omitAnchor && this.anchor) ? '#' + this.anchorString() : '' );
};
Title.prototype.anchorString=function() {
if (!this.anchor) { return ''; }
var split=this.anchor.parenSplit(/((?:[.][0-9A-F]{2})+)/);
var len=split.length;
for (var j=1; j<len; j+=2) {
// FIXME s/decodeURI/decodeURIComponent/g ?
split[j]=decodeURIComponent(split[j].split('.').join('%')).split('_').join(' ');
}
return split.join('');
};
Title.prototype.urlAnchor=function() {
var split=this.anchor.parenSplit('/((?:[%][0-9A-F]{2})+)/');
var len=split.length;
for (var j=1; j<len; j+=2) {
split[j]=split[j].split('%').join('.');
}
return split.join('');
};
Title.prototype.anchorFromUtf=function(str) {
this.anchor=encodeURIComponent(str.split(' ').join('_'))
.split('%3A').join(':').split("'").join('%27').split('%').join('.');
};
Title.fromURL=function(h) {
return new Title().fromURL(h);
};
Title.prototype.fromURL=function(h) {
if (typeof h != 'string') {
this.value=null;
return this;
}
// NOTE : playing with decodeURI, encodeURI, escape, unescape,
// we seem to be able to replicate the IE borked encoding
// IE doesn't do this new-fangled utf-8 thing.
// and it's worse than that.
// IE seems to treat the query string differently to the rest of the url
// the query is treated as bona-fide utf8, but the first bit of the url is pissed around with
// we fix up & for all browsers, just in case.
var splitted=h.split('?');
splitted[0]=splitted[0].split('&').join('%26');
h=splitted.join('?');
var contribs=pg.re.contribs.exec(h);
if (contribs) {
if (contribs[1]=='title=') { contribs[3]=contribs[3].split('+').join(' '); }
var u=new Title(contribs[3]);
this.setUtf(this.decodeNasties(mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' + u.stripNamespace()));
return this;
}
var email=pg.re.email.exec(h);
if (email) {
this.setUtf(this.decodeNasties(mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' + new Title(email[3]).stripNamespace()));
return this;
}
var backlinks=pg.re.backlinks.exec(h);
if (backlinks) {
this.setUtf(this.decodeNasties(new Title(backlinks[3])));
return this;
}
//A dummy title object for a Special:Diff link.
var specialdiff=pg.re.specialdiff.exec(h);
if (specialdiff) {
this.setUtf(this.decodeNasties(new Title(mw.config.get('wgFormattedNamespaces')[pg.nsSpecialId] + ':Diff')));
return this;
}
// no more special cases to check --
// hopefully it's not a disguised user-related or specially treated special page
var m=pg.re.main.exec(h);
if(m === null) { this.value=null; }
else {
var fromBotInterface = /[?](.+[&])?title=/.test(h);
if (fromBotInterface) {
m[2]=m[2].split('+').join('_');
}
var extracted = m[2] + (m[3] ? '#' + m[3] : '');
if (pg.flag.isSafari && /%25[0-9A-Fa-f]{2}/.test(extracted)) {
// Fix Safari issue
// Safari sometimes encodes % as %25 in UTF-8 encoded strings like %E5%A3 -> %25E5%25A3.
this.setUtf(decodeURIComponent(unescape(extracted)));
} else {
this.setUtf(this.decodeNasties(extracted));
}
}
return this;
};
Title.prototype.decodeNasties=function(txt) {
var ret= this.decodeEscapes(decodeURI(txt));
ret = ret.replace(/[_ ]*$/, '');
return ret;
};
Title.prototype.decodeEscapes=function(txt) {
var split=txt.parenSplit(/((?:[%][0-9A-Fa-f]{2})+)/);
var len=split.length;
for (var i=1; i<len; i=i+2) {
// FIXME is decodeURIComponent better?
split[i]=unescape(split[i]);
}
return split.join('');
};
Title.fromAnchor=function(a) {
return new Title().fromAnchor(a);
};
Title.prototype.fromAnchor=function(a) {
if (!a) { this.value=null; return this; }
return this.fromURL(a.href);
};
Title.fromWikiText=function(txt) {
return new Title().fromWikiText(txt);
};
Title.prototype.fromWikiText=function(txt) {
// FIXME - testing needed
txt=myDecodeURI(txt);
this.setUtf(txt);
return this;
};
Title.prototype.hintValue=function(){
if(!this.value) { return ''; }
return safeDecodeURI(this.value);
};
//<NOLITE>
Title.prototype.toUserName=function(withNs) {
if (this.namespaceId() != pg.nsUserId && this.namespaceId() != pg.nsUsertalkId) {
this.value=null;
return;
}
this.value = (withNs ? mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' : '') + this.stripNamespace().split('/')[0];
};
Title.prototype.userName=function(withNs) {
var t=(new Title(this.value));
t.toUserName(withNs);
if (t.value) { return t; }
return null;
};
Title.prototype.toTalkPage=function() {
// convert article to a talk page, or if we can't, return null
// In other words: return null if this ALREADY IS a talk page
// and return the corresponding talk page otherwise
//
// Per https://www.mediawiki.org/wiki/Manual:Namespace#Subject_and_talk_namespaces
// * All discussion namespaces have odd-integer indices
// * The discussion namespace index for a specific namespace with index n is n + 1
if (this.value === null) { return null; }
var namespaceId = this.namespaceId();
if (namespaceId>=0 && namespaceId % 2 === 0) //non-special and subject namespace
{
var localizedNamespace = mw.config.get('wgFormattedNamespaces')[namespaceId+1];
if (typeof localizedNamespace!=='undefined')
{
if (localizedNamespace === '') {
this.value = this.stripNamespace();
} else {
this.value = localizedNamespace.split(' ').join('_') + ':' + this.stripNamespace();
}
return this.value;
}
}
this.value=null;
return null;
};
//</NOLITE>
// Return canonical, localized namespace
Title.prototype.namespace=function() {
return mw.config.get('wgFormattedNamespaces')[this.namespaceId()];
};
Title.prototype.namespaceId=function() {
var n=this.value.indexOf(':');
if (n<0) { return 0; } //mainspace
var namespaceId = mw.config.get('wgNamespaceIds')[this.value.substring(0,n).split(' ').join('_').toLowerCase()];
if (typeof namespaceId=='undefined') return 0; //mainspace
return namespaceId;
};
//<NOLITE>
Title.prototype.talkPage=function() {
var t=new Title(this.value);
t.toTalkPage();
if (t.value) { return t; }
return null;
};
Title.prototype.isTalkPage=function() {
if (this.talkPage()===null) { return true; }
return false;
};
Title.prototype.toArticleFromTalkPage=function() {
//largely copy/paste from toTalkPage above.
if (this.value === null) { return null; }
var namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 == 1) //non-special and talk namespace
{
var localizedNamespace = mw.config.get('wgFormattedNamespaces')[namespaceId-1];
if (typeof localizedNamespace!=='undefined')
{
if (localizedNamespace === '') {
this.value = this.stripNamespace();
} else {
this.value = localizedNamespace.split(' ').join('_') + ':' + this.stripNamespace();
}
return this.value;
}
}
this.value=null;
return null;
};
Title.prototype.articleFromTalkPage=function() {
var t=new Title(this.value);
t.toArticleFromTalkPage();
if (t.value) { return t; }
return null;
};
Title.prototype.articleFromTalkOrArticle=function() {
var t=new Title(this.value);
if ( t.toArticleFromTalkPage() ) { return t; }
return this;
};
Title.prototype.isIpUser=function() {
return pg.re.ipUser.test(this.userName());
};
//</NOLITE>
Title.prototype.stripNamespace=function(){ // returns a string, not a Title
var n=this.value.indexOf(':');
if (n<0) { return this.value; }
var namespaceId = this.namespaceId();
if (namespaceId === pg.nsMainspaceId) return this.value;
return this.value.substring(n+1);
};
Title.prototype.setUtf=function(value){
if (!value) { this.value=''; return; }
var anch=value.indexOf('#');
if(anch < 0) { this.value=value.split('_').join(' '); this.anchor=''; return; }
this.value=value.substring(0,anch).split('_').join(' ');
this.anchor=value.substring(anch+1);
this.ns=null; // wait until namespace() is called
};
Title.prototype.setUrl=function(urlfrag) {
var anch=urlfrag.indexOf('#');
this.value=safeDecodeURI(urlfrag.substring(0,anch));
this.anchor=this.value.substring(anch+1);
};
Title.prototype.append=function(x){
this.setUtf(this.value + x);
};
Title.prototype.urlString=function(x) {
if(!x) { x={}; }
var v=this.toString(true);
if (!x.omitAnchor && this.anchor) { v+= '#' + this.urlAnchor(); }
if (!x.keepSpaces) { v=v.split(' ').join('_'); }
return encodeURI(v).split('&').join('%26').split('?').join('%3F').split('+').join('%2B');
};
Title.prototype.removeAnchor=function() {
return new Title(this.toString(true));
};
Title.prototype.toUrl=function() {
return pg.wiki.titlebase + this.urlString();
};
function parseParams(url) {
var specialDiff = pg.re.specialdiff.exec(url);
if (specialDiff)
{
var split= specialDiff[1].split('/');
if (split.length==1) return {oldid:split[0], diff: 'prev'};
else if (split.length==2) return {oldid: split[0], diff: split[1]};
}
var ret={};
if (url.indexOf('?')==-1) { return ret; }
url = url.split('#')[0];
var s=url.split('?').slice(1).join();
var t=s.split('&');
for (var i=0; i<t.length; ++i) {
var z=t[i].split('=');
z.push(null);
ret[z[0]]=z[1];
}
//Diff revision with no oldid is interpreted as a diff to the previous revision by MediaWiki
if (ret.diff && typeof(ret.oldid)==='undefined')
{
ret.oldid = "prev";
}
//Documentation seems to say something different, but oldid can also accept prev/next, and Echo is emitting such URLs. Simple fixup during parameter decoding:
if (ret.oldid && (ret.oldid==='prev' || ret.oldid==='next' || ret.oldid==='cur'))
{
var helper = ret.diff;
ret.diff = ret.oldid;
ret.oldid = helper;
}
return ret;
}
// (a) myDecodeURI (first standard decodeURI, then pg.re.urlNoPopup)
// (b) change spaces to underscores
// (c) encodeURI (just the straight one, no pg.re.urlNoPopup)
function myDecodeURI (str) {
var ret;
// FIXME decodeURIComponent??
try { ret=decodeURI(str.toString()); }
catch (summat) { return str; }
for (var i=0; i<pg.misc.decodeExtras.length; ++i) {
var from=pg.misc.decodeExtras[i].from;
var to=pg.misc.decodeExtras[i].to;
ret=ret.split(from).join(to);
}
return ret;
}
function safeDecodeURI(str) { var ret=myDecodeURI(str); return ret || str; }
///////////
// TESTS //
///////////
//<NOLITE>
function isDisambig(data, article) {
if (!getValueOf('popupAllDabsStubs') && article.namespace()) { return false; }
return ! article.isTalkPage() && pg.re.disambig.test(data);
}
function stubCount(data, article) {
if (!getValueOf('popupAllDabsStubs') && article.namespace()) { return false; }
var sectStub=0;
var realStub=0;
if (pg.re.stub.test(data)) {
var s=data.parenSplit(pg.re.stub);
for (var i=1; i<s.length; i=i+2) {
if (s[i]) { ++sectStub; }
else { ++realStub; }
}
}
return { real: realStub, sect: sectStub };
}
function isValidImageName(str){ // extend as needed...
return ( str.indexOf('{') == -1 );
}
function isInStrippableNamespace(article) {
// Does the namespace allow subpages
// Note, would be better if we had access to wgNamespacesWithSubpages
return ( article.namespaceId() !== 0 );
}
function isInMainNamespace(article) { return article.namespaceId() === 0; }
function anchorContainsImage(a) {
// iterate over children of anchor a
// see if any are images
if (a === null) { return false; }
var kids=a.childNodes;
for (var i=0; i<kids.length; ++i) { if (kids[i].nodeName=='IMG') { return true; } }
return false;
}
//</NOLITE>
function isPopupLink(a) {
// NB for performance reasons, TOC links generally return true
// they should be stripped out later
if (!markNopopupSpanLinks.done) { markNopopupSpanLinks(); }
if (a.inNopopupSpan) { return false; }
// FIXME is this faster inline?
if (a.onmousedown || a.getAttribute('nopopup')) { return false; }
var h=a.href;
if (h === document.location.href+'#') { return false; }
if (!pg.re.basenames.test(h)) { return false; }
if (!pg.re.urlNoPopup.test(h)) { return true; }
return (
(pg.re.email.test(h) || pg.re.contribs.test(h) || pg.re.backlinks.test(h) || pg.re.specialdiff.test(h)) &&
h.indexOf('&limit=') == -1 );
}
function markNopopupSpanLinks() {
if( !getValueOf('popupOnlyArticleLinks'))
fixVectorMenuPopups();
var s = $('.nopopups').toArray();
for (var i=0; i<s.length; ++i) {
var as=s[i].getElementsByTagName('a');
for (var j=0; j<as.length; ++j) {
as[j].inNopopupSpan=true;
}
}
markNopopupSpanLinks.done=true;
}
function fixVectorMenuPopups() {
$('div.vectorMenu h3:first a:first').prop('inNopopupSpan', true);
}
// ENDFILE: titles.js
// STARTFILE: getpage.js
//////////////////////////////////////////////////
// Wiki-specific downloading
//
// Schematic for a getWiki call
//
// getPageWithCaching
// |
// false | true
// getPage<-[findPictureInCache]->-onComplete(a fake download)
// \.
// (async)->addPageToCache(download)->-onComplete(download)
// check cache to see if page exists
function getPageWithCaching(url, onComplete, owner) {
log('getPageWithCaching, url='+url);
var i=findInPageCache(url);
var d;
if (i > -1) {
d=fakeDownload(url, owner.idNumber, onComplete,
pg.cache.pages[i].data, pg.cache.pages[i].lastModified,
owner);
} else {
d=getPage(url, onComplete, owner);
if (d && owner && owner.addDownload) {
owner.addDownload(d);
d.owner=owner;
}
}
}
function getPage(url, onComplete, owner) {
log('getPage');
var callback= function (d) { if (!d.aborted) {addPageToCache(d); onComplete(d);} };
return startDownload(url, owner.idNumber, callback);
}
function findInPageCache(url) {
for (var i=0; i<pg.cache.pages.length; ++i) {
if (url==pg.cache.pages[i].url) { return i; }
}
return -1;
}
function addPageToCache(download) {
log('addPageToCache '+download.url);
var page = {url: download.url, data: download.data, lastModified: download.lastModified};
return pg.cache.pages.push(page);
}
// ENDFILE: getpage.js
// STARTFILE: parensplit.js
//////////////////////////////////////////////////
// parenSplit
// String.prototype.parenSplit should do what ECMAscript says String.prototype.split does,
// interspersing paren matches (regex capturing groups) between the split elements.
// i.e. 'abc'.split(/(b)/)) should return ['a','b','c'], not ['a','c']
if (String('abc'.split(/(b)/))!='a,b,c') {
// broken String.split, e.g. konq, IE < 10
String.prototype.parenSplit=function (re) {
re=nonGlobalRegex(re);
var s=this;
var m=re.exec(s);
var ret=[];
while (m && s) {
// without the following loop, we have
// 'ab'.parenSplit(/a|(b)/) != 'ab'.split(/a|(b)/)
for(var i=0; i<m.length; ++i) {
if (typeof m[i]=='undefined') m[i]='';
}
ret.push(s.substring(0,m.index));
ret = ret.concat(m.slice(1));
s=s.substring(m.index + m[0].length);
m=re.exec(s);
}
ret.push(s);
return ret;
};
} else {
String.prototype.parenSplit=function (re) { return this.split(re); };
String.prototype.parenSplit.isNative=true;
}
function nonGlobalRegex(re) {
var s=re.toString();
var flags='';
for (var j=s.length; s.charAt(j) != '/'; --j) {
if (s.charAt(j) != 'g') { flags += s.charAt(j); }
}
var t=s.substring(1,j);
return RegExp(t,flags);
}
// ENDFILE: parensplit.js
// STARTFILE: tools.js
// IE madness with encoding
// ========================
//
// suppose throughout that the page is in utf8, like wikipedia
//
// if a is an anchor DOM element and a.href should consist of
//
// http://host.name.here/wiki/foo?bar=baz
//
// then IE gives foo as "latin1-encoded" utf8; we have foo = decode_utf8(decodeURI(foo_ie))
// but IE gives bar=baz correctly as plain utf8
//
// ---------------------------------
//
// IE's xmlhttp doesn't understand utf8 urls. Have to use encodeURI here.
//
// ---------------------------------
//
// summat else
// Source: http://aktuell.de.selfhtml.org/artikel/javascript/utf8b64/utf8.htm
//<NOLITE>
function getJsObj(json) {
try {
var json_ret = JSON.parse(json);
if( json_ret.warnings ) {
for( var w=0; w < json_ret.warnings.length; w++ ) {
if( json_ret.warnings[w]['*'] ) {
log( json_ret.warnings[w]['*'] );
} else {
log( json_ret.warnings[w]['warnings'] );
}
}
} else if ( json_ret.error ) {
errlog( json_ret.error.code + ': ' + json_ret.error.info );
}
return json_ret;
} catch (someError) {
errlog('Something went wrong with getJsObj, json='+json);
return 1;
}
}
function anyChild(obj) {
for (var p in obj) {
return obj[p];
}
return null;
}
//</NOLITE>
function upcaseFirst(str) {
if (typeof str != typeof '' || str === '') return '';
return str.charAt(0).toUpperCase() + str.substring(1);
}
function findInArray(arr, foo) {
if (!arr || !arr.length) { return -1; }
var len=arr.length;
for (var i=0; i<len; ++i) { if (arr[i]==foo) { return i; } }
return -1;
}
/* eslint-disable no-unused-vars */
function nextOne (array, value) {
// NB if the array has two consecutive entries equal
// then this will loop on successive calls
var i=findInArray(array, value);
if (i<0) { return null; }
return array[i+1];
}
/* eslint-enable no-unused-vars */
function literalizeRegex(str){
return mw.util.escapeRegExp(str);
}
String.prototype.entify=function() {
//var shy='­';
return this.split('&').join('&').split('<').join('<').split('>').join('>'/*+shy*/).split('"').join('"');
};
// Array filter function
function removeNulls(val) { return val !== null; }
function joinPath(list) {
return list.filter(removeNulls).join('/');
}
function simplePrintf(str, subs) {
if (!str || !subs) { return str; }
var ret=[];
var s=str.parenSplit(/(%s|\$[0-9]+)/);
var i=0;
do {
ret.push(s.shift());
if ( !s.length ) { break; }
var cmd=s.shift();
if (cmd == '%s') {
if ( i < subs.length ) { ret.push(subs[i]); } else { ret.push(cmd); }
++i;
} else {
var j=parseInt( cmd.replace('$', ''), 10 ) - 1;
if ( j > -1 && j < subs.length ) { ret.push(subs[j]); } else { ret.push(cmd); }
}
} while (s.length > 0);
return ret.join('');
}
/* eslint-disable no-unused-vars */
function isString(x) { return (typeof x === 'string' || x instanceof String); }
function isNumber(x) { return (typeof x === 'number' || x instanceof Number); }
function isRegExp(x) { return x instanceof RegExp; }
function isArray (x) { return x instanceof Array; }
function isObject(x) { return x instanceof Object; }
function isFunction(x) {
return !isRegExp(x) && (typeof x === 'function' || x instanceof Function);
}
/* eslint-enable no-unused-vars */
function repeatString(s,mult) {
var ret='';
for (var i=0; i<mult; ++i) { ret += s; }
return ret;
}
function zeroFill(s, min) {
min = min || 2;
var t=s.toString();
return repeatString('0', min - t.length) + t;
}
function map(f, o) {
if (isArray(o)) { return map_array(f,o); }
return map_object(f,o);
}
function map_array(f,o) {
var ret=[];
for (var i=0; i<o.length; ++i) {
ret.push(f(o[i]));
}
return ret;
}
function map_object(f,o) {
var ret={};
for (var i in o) { ret[o]=f(o[i]); }
return ret;
}
pg.escapeQuotesHTML = function ( text ) {
return text
.replace(/&/g, "&")
.replace(/"/g, """)
.replace(/</g, "<")
.replace(/>/g, ">");
};
// ENDFILE: tools.js
// STARTFILE: dab.js
//<NOLITE>
//////////////////////////////////////////////////
// Dab-fixing code
//
function retargetDab(newTarget, oldTarget, friendlyCurrentArticleName, titleToEdit) {
log('retargetDab: newTarget='+newTarget + ' oldTarget=' + oldTarget);
return changeLinkTargetLink(
{newTarget: newTarget,
text: newTarget.split(' ').join(' '),
hint: tprintf('disambigHint', [newTarget]),
summary: simplePrintf(
getValueOf('popupFixDabsSummary'), [friendlyCurrentArticleName, newTarget ]),
clickButton: getValueOf('popupDabsAutoClick'), minor: true, oldTarget: oldTarget,
watch: getValueOf('popupWatchDisambiggedPages'),
title: titleToEdit});
}
function listLinks(wikitext, oldTarget, titleToEdit) {
// mediawiki strips trailing spaces, so we do the same
// testcase: https://en.wikipedia.org/w/index.php?title=Radial&oldid=97365633
var reg=RegExp('\\[\\[([^|]*?) *(\\||\\]\\])', 'gi');
var ret=[];
var splitted=wikitext.parenSplit(reg);
// ^[a-z]+ should match interwiki links, hopefully (case-insensitive)
// and ^[a-z]* should match those and [[:Category...]] style links too
var omitRegex=RegExp('^[a-z]*:|^[Ss]pecial:|^[Ii]mage|^[Cc]ategory');
var friendlyCurrentArticleName= oldTarget.toString();
var wikPos = getValueOf('popupDabWiktionary');
for (var i=1; i<splitted.length; i=i+3) {
if (typeof splitted[i] == typeof 'string' && splitted[i].length>0 && !omitRegex.test(splitted[i])) {
ret.push( retargetDab(splitted[i], oldTarget, friendlyCurrentArticleName, titleToEdit) );
} /* if */
} /* for loop */
ret = rmDupesFromSortedList(ret.sort());
if (wikPos) {
var wikTarget='wiktionary:' +
friendlyCurrentArticleName.replace( RegExp('^(.+)\\s+[(][^)]+[)]\\s*$'), '$1' );
var meth;
if (wikPos.toLowerCase() == 'first') { meth = 'unshift'; }
else { meth = 'push'; }
ret[meth]( retargetDab(wikTarget, oldTarget, friendlyCurrentArticleName, titleToEdit) );
}
ret.push(changeLinkTargetLink(
{ newTarget: null,
text: popupString('remove this link').split(' ').join(' '),
hint: popupString("remove all links to this disambig page from this article"),
clickButton: getValueOf('popupDabsAutoClick'), oldTarget: oldTarget,
summary: simplePrintf(getValueOf('popupRmDabLinkSummary'), [friendlyCurrentArticleName]),
watch: getValueOf('popupWatchDisambiggedPages'),
title: titleToEdit
}));
return ret;
}
function rmDupesFromSortedList(list) {
var ret=[];
for (var i=0; i<list.length; ++i) {
if (ret.length === 0 || list[i]!=ret[ret.length-1]) { ret.push(list[i]); }
}
return ret;
}
function makeFixDab(data, navpop) {
// grab title from parent popup if there is one; default exists in changeLinkTargetLink
var titleToEdit=(navpop.parentPopup && navpop.parentPopup.article.toString());
var list=listLinks(data, navpop.originalArticle, titleToEdit);
if (list.length === 0) { log('listLinks returned empty list'); return null; }
var html='<hr />' + popupString('Click to disambiguate this link to:') + '<br>';
html+=list.join(', ');
return html;
}
function makeFixDabs(wikiText, navpop) {
if (getValueOf('popupFixDabs') && isDisambig(wikiText, navpop.article) &&
Title.fromURL(location.href).namespaceId() != pg.nsSpecialId &&
navpop.article.talkPage() ) {
setPopupHTML(makeFixDab(wikiText, navpop), 'popupFixDab', navpop.idNumber);
}
}
function popupRedlinkHTML(article) {
return changeLinkTargetLink(
{ newTarget: null, text: popupString('remove this link').split(' ').join(' '),
hint: popupString("remove all links to this page from this article"),
clickButton: getValueOf('popupRedlinkAutoClick'),
oldTarget: article.toString(),
summary: simplePrintf(getValueOf('popupRedlinkSummary'), [article.toString()])});
}
//</NOLITE>
// ENDFILE: dab.js
// STARTFILE: htmloutput.js
// this has to use a timer loop as we don't know if the DOM element exists when we want to set the text
function setPopupHTML (str, elementId, popupId, onSuccess, append) {
if (typeof popupId === 'undefined') {
//console.error('popupId is not defined in setPopupHTML, html='+str.substring(0,100));
popupId = pg.idNumber;
}
var popupElement=document.getElementById(elementId+popupId);
if (popupElement) {
if (!append) { popupElement.innerHTML=''; }
if (isString(str)) {
popupElement.innerHTML+=str;
} else {
popupElement.appendChild(str);
}
if (onSuccess) { onSuccess(); }
setTimeout(checkPopupPosition, 100);
return true;
} else {
// call this function again in a little while...
setTimeout(function(){
setPopupHTML(str,elementId,popupId,onSuccess);
}, 600);
}
return null;
}
//<NOLITE>
function setPopupTrailer(str,id) {return setPopupHTML(str, 'popupData', id);}
//</NOLITE>
// args.navpopup is mandatory
// optional: args.redir, args.redirTarget
// FIXME: ye gods, this is ugly stuff
function fillEmptySpans(args) {
// if redir is present and true then redirTarget is mandatory
var redir=true;
var rcid;
if (typeof args != 'object' || typeof args.redir == 'undefined' || !args.redir) { redir=false; }
var a=args.navpopup.parentAnchor;
var article, hint=null, oldid=null, params={};
if (redir && typeof args.redirTarget == typeof {}) {
article=args.redirTarget;
//hint=article.hintValue();
} else {
article=(new Title()).fromAnchor(a);
hint=a.originalTitle || article.hintValue();
params=parseParams(a.href);
oldid=(getValueOf('popupHistoricalLinks')) ? params.oldid : null;
rcid=params.rcid;
}
var x={ article:article, hint: hint, oldid: oldid, rcid: rcid, navpop:args.navpopup, params:params };
var structure=pg.structures[getValueOf('popupStructure')];
if (typeof structure != 'object') {
setPopupHTML('popupError', 'Unknown structure (this should never happen): '+
pg.option.popupStructure, args.navpopup.idNumber);
return;
}
var spans=flatten(pg.misc.layout);
var numspans = spans.length;
var redirs=pg.misc.redirSpans;
for (var i=0; i<numspans; ++i) {
var found = redirs && (redirs.indexOf( spans[i] ) !== -1);
//log('redir='+redir+', found='+found+', spans[i]='+spans[i]);
if ( (found && !redir) || (!found && redir) ) {
//log('skipping this set of the loop');
continue;
}
var structurefn=structure[spans[i]];
var setfn = setPopupHTML;
if (getValueOf('popupActiveNavlinks') &&
(spans[i].indexOf('popupTopLinks')===0 || spans[i].indexOf('popupRedirTopLinks')===0)
) {
setfn = setPopupTipsAndHTML;
}
switch (typeof structurefn) {
case 'function':
log('running '+spans[i]+'({article:'+x.article+', hint:'+x.hint+', oldid: '+x.oldid+'})');
setfn(structurefn(x), spans[i], args.navpopup.idNumber);
break;
case 'string':
setfn(structurefn, spans[i], args.navpopup.idNumber);
break;
default:
errlog('unknown thing with label '+spans[i] + ' (span index was ' + i + ')');
break;
}
}
}
// flatten an array
function flatten(list, start) {
var ret=[];
if (typeof start == 'undefined') { start=0; }
for (var i=start; i<list.length; ++i) {
if (typeof list[i] == typeof []) {
return ret.concat(flatten(list[i])).concat(flatten(list, i+1));
}
else { ret.push(list[i]); }
}
return ret;
}
// Generate html for whole popup
function popupHTML (a) {
getValueOf('popupStructure');
var structure=pg.structures[pg.option.popupStructure];
if (typeof structure != 'object') {
//return 'Unknown structure: '+pg.option.popupStructure;
// override user choice
pg.option.popupStructure=pg.optionDefault.popupStructure;
return popupHTML(a);
}
if (typeof structure.popupLayout != 'function') { return 'Bad layout'; }
pg.misc.layout=structure.popupLayout();
if (typeof structure.popupRedirSpans === 'function') { pg.misc.redirSpans=structure.popupRedirSpans(); }
else { pg.misc.redirSpans=[]; }
return makeEmptySpans(pg.misc.layout, a.navpopup);
}
function makeEmptySpans (list, navpop) {
var ret='';
for (var i=0; i<list.length; ++i) {
if (typeof list[i] == typeof '') {
ret += emptySpanHTML(list[i], navpop.idNumber, 'div');
} else if (typeof list[i] == typeof [] && list[i].length > 0 ) {
ret = ret.parenSplit(RegExp('(</[^>]*?>$)')).join(makeEmptySpans(list[i], navpop));
} else if (typeof list[i] == typeof {} && list[i].nodeType ) {
ret += emptySpanHTML(list[i].name, navpop.idNumber, list[i].nodeType);
}
}
return ret;
}
function emptySpanHTML(name, id, tag, classname) {
tag = tag || 'span';
if (!classname) { classname = emptySpanHTML.classAliases[name]; }
classname = classname || name;
if (name == getValueOf('popupDragHandle')) { classname += ' popupDragHandle'; }
return simplePrintf('<%s id="%s" class="%s"></%s>', [tag, name + id, classname, tag]);
}
emptySpanHTML.classAliases={ 'popupSecondPreview': 'popupPreview' };
// generate html for popup image
// <a id="popupImageLinkn"><img id="popupImagen">
// where n=idNumber
function imageHTML(article, idNumber) {
return simplePrintf('<a id="popupImageLink$1">' +
'<img align="right" valign="top" id="popupImg$1" style="display: none;"></img>' +
'</a>', [ idNumber ]);
}
function popTipsSoonFn(id, when, popData) {
if (!when) { when=250; }
var popTips=function(){ setupTooltips(document.getElementById(id), false, true, popData); };
return function() { setTimeout( popTips, when, popData ); };
}
function setPopupTipsAndHTML(html, divname, idnumber, popData) {
setPopupHTML(html, divname, idnumber,
getValueOf('popupSubpopups') ?
popTipsSoonFn(divname + idnumber, null, popData) :
null);
}
// ENDFILE: htmloutput.js
// STARTFILE: mouseout.js
//////////////////////////////////////////////////
// fuzzy checks
function fuzzyCursorOffMenus(x,y, fuzz, parent) {
if (!parent) { return null; }
var uls=parent.getElementsByTagName('ul');
for (var i=0; i<uls.length; ++i) {
if (uls[i].className=='popup_menu') {
if (uls[i].offsetWidth > 0) return false;
} // else {document.title+='.';}
}
return true;
}
function checkPopupPosition () { // stop the popup running off the right of the screen
// FIXME avoid pg.current.link
if (pg.current.link && pg.current.link.navpopup)
pg.current.link.navpopup.limitHorizontalPosition();
}
function mouseOutWikiLink () {
//console ('mouseOutWikiLink');
var a=this;
removeModifierKeyHandler(a);
if (a.navpopup === null || typeof a.navpopup === 'undefined') return;
if ( ! a.navpopup.isVisible() ) {
a.navpopup.banish();
return;
}
restoreTitle(a);
Navpopup.tracker.addHook(posCheckerHook(a.navpopup));
}
function posCheckerHook(navpop) {
return function() {
if (!navpop.isVisible()) { return true; /* remove this hook */ }
if (Navpopup.tracker.dirty) {
return false;
}
var x=Navpopup.tracker.x, y=Navpopup.tracker.y;
var mouseOverNavpop = navpop.isWithin(x,y,navpop.fuzz, navpop.mainDiv) ||
!fuzzyCursorOffMenus(x,y,navpop.fuzz, navpop.mainDiv);
// FIXME it'd be prettier to do this internal to the Navpopup objects
var t=getValueOf('popupHideDelay');
if (t) { t = t * 1000; }
if (!t) {
if(!mouseOverNavpop) {
if(navpop.parentAnchor) {
restoreTitle( navpop.parentAnchor );
}
navpop.banish();
return true; /* remove this hook */
}
return false;
}
// we have a hide delay set
var d=+(new Date());
if ( !navpop.mouseLeavingTime ) {
navpop.mouseLeavingTime = d;
return false;
}
if ( mouseOverNavpop ) {
navpop.mouseLeavingTime=null;
return false;
}
if (d - navpop.mouseLeavingTime > t) {
navpop.mouseLeavingTime=null;
navpop.banish(); return true; /* remove this hook */
}
return false;
};
}
function runStopPopupTimer(navpop) {
// at this point, we should have left the link but remain within the popup
// so we call this function again until we leave the popup.
if (!navpop.stopPopupTimer) {
navpop.stopPopupTimer=setInterval(posCheckerHook(navpop), 500);
navpop.addHook(function(){clearInterval(navpop.stopPopupTimer);},
'hide', 'before');
}
}
// ENDFILE: mouseout.js
// STARTFILE: previewmaker.js
/**
@fileoverview
Defines the {@link Previewmaker} object, which generates short previews from wiki markup.
*/
/**
Creates a new Previewmaker
@constructor
@class The Previewmaker class. Use an instance of this to generate short previews from Wikitext.
@param {String} wikiText The Wikitext source of the page we wish to preview.
@param {String} baseUrl The url we should prepend when creating relative urls.
@param {Navpopup} owner The navpop associated to this preview generator
*/
function Previewmaker(wikiText, baseUrl, owner) {
/** The wikitext which is manipulated to generate the preview. */
this.originalData=wikiText;
this.baseUrl=baseUrl;
this.owner=owner;
this.maxCharacters=getValueOf('popupMaxPreviewCharacters');
this.maxSentences=getValueOf('popupMaxPreviewSentences');
this.setData();
}
Previewmaker.prototype.setData=function() {
var maxSize=Math.max(10000, 2*this.maxCharacters);
this.data=this.originalData.substring(0,maxSize);
};
/** Remove HTML comments
@private
*/
Previewmaker.prototype.killComments = function () {
// this also kills one trailing newline, eg [[diamyo]]
this.data=this.data.replace(RegExp('^<!--[^$]*?-->\\n|\\n<!--[^$]*?-->(?=\\n)|<!--[^$]*?-->', 'g'), '');
};
/**
@private
*/
Previewmaker.prototype.killDivs = function () {
// say goodbye, divs (can be nested, so use * not *?)
this.data=this.data.replace(RegExp('< *div[^>]* *>[\\s\\S]*?< */ *div *>',
'gi'), '');
};
/**
@private
*/
Previewmaker.prototype.killGalleries = function () {
this.data=this.data.replace(RegExp('< *gallery[^>]* *>[\\s\\S]*?< */ *gallery *>',
'gi'), '');
};
/**
@private
*/
Previewmaker.prototype.kill = function(opening, closing, subopening, subclosing, repl) {
var oldk=this.data;
var k=this.killStuff(this.data, opening, closing, subopening, subclosing, repl);
while (k.length < oldk.length) {
oldk=k;
k=this.killStuff(k, opening, closing, subopening, subclosing, repl);
}
this.data=k;
};
/**
@private
*/
Previewmaker.prototype.killStuff = function (txt, opening, closing, subopening, subclosing, repl) {
var op=this.makeRegexp(opening);
var cl=this.makeRegexp(closing, '^');
var sb=subopening ? this.makeRegexp(subopening, '^') : null;
var sc=subclosing ? this.makeRegexp(subclosing, '^') : cl;
if (!op || !cl) {
alert('Navigation Popups error: op or cl is null! something is wrong.');
return;
}
if (!op.test(txt)) { return txt; }
var ret='';
var opResult = op.exec(txt);
ret = txt.substring(0,opResult.index);
txt=txt.substring(opResult.index+opResult[0].length);
var depth = 1;
while (txt.length > 0) {
var removal=0;
if (depth==1 && cl.test(txt)) {
depth--;
removal=cl.exec(txt)[0].length;
} else if (depth > 1 && sc.test(txt)) {
depth--;
removal=sc.exec(txt)[0].length;
}else if (sb && sb.test(txt)) {
depth++;
removal=sb.exec(txt)[0].length;
}
if ( !removal ) { removal = 1; }
txt=txt.substring(removal);
if (depth === 0) { break; }
}
return ret + (repl || '') + txt;
};
/**
@private
*/
Previewmaker.prototype.makeRegexp = function (x, prefix, suffix) {
prefix = prefix || '';
suffix = suffix || '';
var reStr='';
var flags='';
if (isString(x)) {
reStr=prefix + literalizeRegex(x) + suffix;
} else if (isRegExp(x)) {
var s=x.toString().substring(1);
var sp=s.split('/');
flags=sp[sp.length-1];
sp[sp.length-1]='';
s=sp.join('/');
s=s.substring(0,s.length-1);
reStr= prefix + s + suffix;
} else {
log ('makeRegexp failed');
}
log ('makeRegexp: got reStr=' + reStr + ', flags=' + flags);
return RegExp(reStr, flags);
};
/**
@private
*/
Previewmaker.prototype.killBoxTemplates = function () {
// taxobox removal... in fact, there's a saudiprincebox_begin, so let's be more general
// also, have float_begin, ... float_end
this.kill(RegExp('[{][{][^{}\\s|]*?(float|box)[_ ](begin|start)', 'i'), /[}][}]\s*/, '{{');
// infoboxes etc
// from User:Zyxw/popups.js: kill frames too
this.kill(RegExp('[{][{][^{}\\s|]*?(infobox|elementbox|frame)[_ ]', 'i'), /[}][}]\s*/, '{{');
};
/**
@private
*/
Previewmaker.prototype.killTemplates = function () {
// the plus sign is to avoid transcluding [[Template:', ']]
this.kill('{'+'{', '}'+'}', '{', '}', ' ');
};
/**
@private
*/
Previewmaker.prototype.killTables = function () {
// tables are bad, too
// this can be slow, but it's an inprovement over a browser hang
// torture test: [[Comparison_of_Intel_Central_Processing_Units]]
this.kill('{|', /[|]}\s*/, '{|');
this.kill(/<table.*?>/i, /<\/table.*?>/i, /<table.*?>/i);
// remove lines starting with a pipe for the hell of it (?)
this.data=this.data.replace(RegExp('^[|].*$', 'mg'), '');
};
/**
@private
*/
Previewmaker.prototype.killImages = function () {
var forbiddenNamespaceAliases = [];
jQuery.each(mw.config.get('wgNamespaceIds'), function(_localizedNamespaceLc, _namespaceId) {
if (_namespaceId!=pg.nsImageId && _namespaceId!=pg.nsCategoryId) return;
forbiddenNamespaceAliases.push(_localizedNamespaceLc.split(' ').join('[ _]')); //todo: escape regexp fragments!
});
// images and categories are a nono
this.kill(RegExp('[[][[]\\s*(' + forbiddenNamespaceAliases.join('|') + ')\\s*:', 'i'),
/\]\]\s*/, '[', ']');
};
/**
@private
*/
Previewmaker.prototype.killHTML = function () {
// kill <ref ...>...</ref>
this.kill(/<ref\b[^/>]*?>/i, /<\/ref>/i);
// let's also delete entire lines starting with <. it's worth a try.
this.data=this.data.replace(RegExp('(^|\\n) *<.*', 'g'), '\n');
// and those pesky html tags, but not <nowiki> or <blockquote>
var splitted=this.data.parenSplit(/(<[\w\W]*?(?:>|$|(?=<)))/);
var len=splitted.length;
for (var i=1; i<len; i=i+2) {
switch (splitted[i]) {
case '<nowiki>':
case '</nowiki>':
case '<blockquote>':
case '</blockquote>':
break;
default:
splitted[i]='';
}
}
this.data=splitted.join('');
};
/**
@private
*/
Previewmaker.prototype.killChunks = function() { // heuristics alert
// chunks of italic text? you crazy, man?
var italicChunkRegex=new RegExp
("((^|\\n)\\s*:*\\s*''[^']([^']|'''|'[^']){20}(.|\\n[^\\n])*''[.!?\\s]*\\n)+", 'g');
// keep stuff separated, though, so stick in \n (fixes [[Union Jack]]?
this.data=this.data.replace(italicChunkRegex, '\n');
};
/**
@private
*/
Previewmaker.prototype.mopup = function () {
// we simply *can't* be doing with horizontal rules right now
this.data=this.data.replace(RegExp('^-{4,}','mg'),'');
// no indented lines
this.data=this.data.replace(RegExp('(^|\\n) *:[^\\n]*','g'), '');
// replace __TOC__, __NOTOC__ and whatever else there is
// this'll probably do
this.data=this.data.replace(RegExp('^__[A-Z_]*__ *$', 'gmi'),'');
};
/**
@private
*/
Previewmaker.prototype.firstBit = function () {
// dont't be givin' me no subsequent paragraphs, you hear me?
/// first we "normalize" section headings, removing whitespace after, adding before
var d=this.data;
if (getValueOf('popupPreviewCutHeadings')) {
this.data=this.data.replace(RegExp('\\s*(==+[^=]*==+)\\s*', 'g'), '\n\n$1 ');
/// then we want to get rid of paragraph breaks whose text ends badly
this.data=this.data.replace(RegExp('([:;]) *\\n{2,}', 'g'), '$1\n');
this.data=this.data.replace(RegExp('^[\\s\\n]*'), '');
var stuff=(RegExp('^([^\\n]|\\n[^\\n\\s])*')).exec(this.data);
if (stuff) { d = stuff[0]; }
if (!getValueOf('popupPreviewFirstParOnly')) { d = this.data; }
/// now put \n\n after sections so that bullets and numbered lists work
d=d.replace(RegExp('(==+[^=]*==+)\\s*', 'g'), '$1\n\n');
}
// Split sentences. Superfluous sentences are RIGHT OUT.
// note: exactly 1 set of parens here needed to make the slice work
d = d.parenSplit(RegExp('([!?.]+["'+"'"+']*\\s)','g'));
// leading space is bad, mmkay?
d[0]=d[0].replace(RegExp('^\\s*'), '');
var notSentenceEnds=RegExp('([^.][a-z][.] *[a-z]|etc|sic|Dr|Mr|Mrs|Ms|St|no|op|cit|\\[[^\\]]*|\\s[A-Zvclm])$', 'i');
d = this.fixSentenceEnds(d, notSentenceEnds);
this.fullLength=d.join('').length;
var n=this.maxSentences;
var dd=this.firstSentences(d,n);
do {
dd=this.firstSentences(d,n); --n;
} while ( dd.length > this.maxCharacters && n !== 0 );
this.data = dd;
};
/**
@private
*/
Previewmaker.prototype.fixSentenceEnds = function(strs, reg) {
// take an array of strings, strs
// join strs[i] to strs[i+1] & strs[i+2] if strs[i] matches regex reg
for (var i=0; i<strs.length-2; ++i) {
if (reg.test(strs[i])) {
var a=[];
for (var j=0; j<strs.length; ++j) {
if (j<i) a[j]=strs[j];
if (j==i) a[i]=strs[i]+strs[i+1]+strs[i+2];
if (j>i+2) a[j-2]=strs[j];
}
return this.fixSentenceEnds(a,reg);
}
}
return strs;
};
/**
@private
*/
Previewmaker.prototype.firstSentences = function(strs, howmany) {
var t=strs.slice(0, 2*howmany);
return t.join('');
};
/**
@private
*/
Previewmaker.prototype.killBadWhitespace = function() {
// also cleans up isolated '''', eg [[Suntory Sungoliath]]
this.data=this.data.replace(RegExp('^ *\'+ *$', 'gm'), '');
};
/**
Runs the various methods to generate the preview.
The preview is stored in the <code>html</html> field.
@private
*/
Previewmaker.prototype.makePreview = function() {
if (this.owner.article.namespaceId()!=pg.nsTemplateId &&
this.owner.article.namespaceId()!=pg.nsImageId ) {
this.killComments();
this.killDivs();
this.killGalleries();
this.killBoxTemplates();
if (getValueOf('popupPreviewKillTemplates')) {
this.killTemplates();
} else {
this.killMultilineTemplates();
}
this.killTables();
this.killImages();
this.killHTML();
this.killChunks();
this.mopup();
this.firstBit();
this.killBadWhitespace();
}
else
{
this.killHTML();
}
this.html=wiki2html(this.data, this.baseUrl); // needs livepreview
this.fixHTML();
this.stripLongTemplates();
};
/**
@private
*/
Previewmaker.prototype.esWiki2HtmlPart = function(data) {
var reLinks = /(?:\[\[([^|\]]*)(?:\|([^|\]]*))*]]([a-z]*))/gi; //match a wikilink
reLinks.lastIndex = 0; //reset regex
var match;
var result = "";
var postfixIndex = 0;
while ((match = reLinks.exec(data))) //match all wikilinks
{
//FIXME: the way that link is built here isn't perfect. It is clickable, but popups preview won't recognize it in some cases.
result += pg.escapeQuotesHTML(data.substring(postfixIndex, match.index)) +
'<a href="'+Insta.conf.paths.articles+pg.escapeQuotesHTML(match[1])+'">'+pg.escapeQuotesHTML((match[2]?match[2]:match[1])+match[3])+"</a>";
postfixIndex = reLinks.lastIndex;
}
//append the rest
result += pg.escapeQuotesHTML(data.substring(postfixIndex));
return result;
};
Previewmaker.prototype.editSummaryPreview=function() {
var reAes = /\/\* *(.*?) *\*\//g; //match the first section marker
reAes.lastIndex = 0; //reset regex
var match;
match = reAes.exec(this.data);
if (match)
{
//we have a section link. Split it, process it, combine it.
var prefix = this.data.substring(0,match.index-1);
var section = match[1];
var postfix = this.data.substring(reAes.lastIndex);
var start = "<span class='autocomment'>";
var end = "</span>";
if (prefix.length>0) start = this.esWiki2HtmlPart(prefix) + " " + start + "- ";
if (postfix.length>0) end = ": " + end + this.esWiki2HtmlPart(postfix);
var t=new Title().fromURL(this.baseUrl);
t.anchorFromUtf(section);
var sectionLink = Insta.conf.paths.articles + pg.escapeQuotesHTML(t.toString(true)) + '#' + pg.escapeQuotesHTML(t.anchor);
return start + '<a href="'+sectionLink+'">→</a> '+pg.escapeQuotesHTML(section) + end;
}
//else there's no section link, htmlify the whole thing.
return this.esWiki2HtmlPart(this.data);
};
//<NOLITE>
/** Test function for debugging preview problems one step at a time.
*/
/*eslint-disable */
function previewSteps(txt) {
try {
txt=txt || document.editform.wpTextbox1.value;
} catch (err) {
if (pg.cache.pages.length > 0) {
txt=pg.cache.pages[pg.cache.pages.length-1].data;
} else {
alert('provide text or use an edit page');
}
}
txt=txt.substring(0,10000);
var base=pg.wiki.articlebase + Title.fromURL(document.location.href).urlString();
var p=new Previewmaker(txt, base, pg.current.link.navpopup);
if (this.owner.article.namespaceId() != pg.nsTemplateId) {
p.killComments(); if (!confirm('done killComments(). Continue?\n---\n' + p.data)) { return; }
p.killDivs(); if (!confirm('done killDivs(). Continue?\n---\n' + p.data)) { return; }
p.killGalleries(); if (!confirm('done killGalleries(). Continue?\n---\n' + p.data)) { return; }
p.killBoxTemplates(); if (!confirm('done killBoxTemplates(). Continue?\n---\n' + p.data)) { return; }
if (getValueOf('popupPreviewKillTemplates')) {
p.killTemplates(); if (!confirm('done killTemplates(). Continue?\n---\n' + p.data)) { return; }
} else {
p.killMultilineTemplates(); if (!confirm('done killMultilineTemplates(). Continue?\n---\n' + p.data)) { return; }
}
p.killTables(); if (!confirm('done killTables(). Continue?\n---\n' + p.data)) { return; }
p.killImages(); if (!confirm('done killImages(). Continue?\n---\n' + p.data)) { return; }
p.killHTML(); if (!confirm('done killHTML(). Continue?\n---\n' + p.data)) { return; }
p.killChunks(); if (!confirm('done killChunks(). Continue?\n---\n' + p.data)) { return; }
p.mopup(); if (!confirm('done mopup(). Continue?\n---\n' + p.data)) { return; }
p.firstBit(); if (!confirm('done firstBit(). Continue?\n---\n' + p.data)) { return; }
p.killBadWhitespace(); if (!confirm('done killBadWhitespace(). Continue?\n---\n' + p.data)) { return; }
}
p.html=wiki2html(p.data, base); // needs livepreview
p.fixHTML(); if (!confirm('done fixHTML(). Continue?\n---\n' + p.html)) { return; }
p.stripLongTemplates(); if (!confirm('done stripLongTemplates(). Continue?\n---\n' + p.html)) { return; }
alert('finished preview - end result follows.\n---\n' + p.html);
}
/*eslint-enable */
//</NOLITE>
/**
Works around livepreview bugs.
@private
*/
Previewmaker.prototype.fixHTML = function() {
if(!this.html) return;
var ret = this.html;
// fix question marks in wiki links
// maybe this'll break some stuff :-(
ret=ret.replace(RegExp('(<a href="' + pg.wiki.articlePath + '/[^"]*)[?](.*?")', 'g'), '$1%3F$2');
ret=ret.replace(RegExp('(<a href=\'' + pg.wiki.articlePath + '/[^\']*)[?](.*?\')', 'g'), '$1%3F$2');
// FIXME fix up % too
this.html=ret;
};
/**
Generates the preview and displays it in the current popup.
Does nothing if the generated preview is invalid or consists of whitespace only.
Also activates wikilinks in the preview for subpopups if the popupSubpopups option is true.
*/
Previewmaker.prototype.showPreview = function () {
this.makePreview();
if (typeof this.html != typeof '') return;
if (RegExp('^\\s*$').test(this.html)) return;
setPopupHTML('<hr />', 'popupPrePreviewSep', this.owner.idNumber);
setPopupTipsAndHTML(this.html, 'popupPreview', this.owner.idNumber, { owner: this.owner });
var more = (this.fullLength > this.data.length) ? this.moreLink() : '';
setPopupHTML(more, 'popupPreviewMore', this.owner.idNumber);
};
/**
@private
*/
Previewmaker.prototype.moreLink=function() {
var a=document.createElement('a');
a.className='popupMoreLink';
a.innerHTML=popupString('more...');
var savedThis=this;
a.onclick=function() {
savedThis.maxCharacters+=2000;
savedThis.maxSentences+=20;
savedThis.setData();
savedThis.showPreview();
};
return a;
};
/**
@private
*/
Previewmaker.prototype.stripLongTemplates = function() {
// operates on the HTML!
this.html=this.html.replace(RegExp('^.{0,1000}[{][{][^}]*?(<(p|br)( /)?>\\s*){2,}([^{}]*?[}][}])?', 'gi'), '');
this.html=this.html.split('\n').join(' '); // workaround for <pre> templates
this.html=this.html.replace(RegExp('[{][{][^}]*<pre>[^}]*[}][}]','gi'), '');
};
/**
@private
*/
Previewmaker.prototype.killMultilineTemplates = function() {
this.kill('{{{', '}}}');
this.kill(RegExp('\\s*[{][{][^{}]*\\n'), '}}', '{{');
};
// ENDFILE: previewmaker.js
// STARTFILE: querypreview.js
function loadAPIPreview(queryType, article, navpop) {
var art=new Title(article).urlString();
var url=pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
var htmlGenerator=function(/*a, d*/){alert('invalid html generator');};
var usernameart = '';
switch (queryType) {
case 'history':
url += 'titles=' + art + '&prop=revisions&rvlimit=' +
getValueOf('popupHistoryPreviewLimit');
htmlGenerator=APIhistoryPreviewHTML;
break;
case 'category':
url += 'list=categorymembers&cmtitle=' + art;
htmlGenerator=APIcategoryPreviewHTML;
break;
case 'userinfo':
var username = new Title( article ).userName();
usernameart = encodeURIComponent( username );
if (pg.re.ipUser.test(username)) {
url += 'list=blocks&bkprop=range|restrictions&bkip=' + usernameart;
} else {
url += 'list=users|usercontribs&usprop=blockinfo|groups|editcount|registration|gender&ususers=' + usernameart + "&meta=globaluserinfo&guiprop=groups|unattached&guiuser="+ usernameart + "&uclimit=1&ucprop=timestamp&ucuser=" + usernameart;
}
htmlGenerator=APIuserInfoPreviewHTML;
break;
case 'contribs':
usernameart = encodeURIComponent( new Title( article ).userName() );
url += 'list=usercontribs&ucuser=' + usernameart +
'&uclimit=' + getValueOf('popupContribsPreviewLimit');
htmlGenerator=APIcontribsPreviewHTML;
break;
case 'imagepagepreview':
var trail='';
if (getValueOf('popupImageLinks')) { trail = '&list=imageusage&iutitle=' + art; }
url += 'titles=' + art + '&prop=revisions|imageinfo&rvprop=content' + trail;
htmlGenerator=APIimagepagePreviewHTML;
break;
case 'backlinks':
url += 'list=backlinks&bltitle=' + art;
htmlGenerator=APIbacklinksPreviewHTML;
break;
case 'revision':
if (article.oldid) {
url += 'revids=' + article.oldid;
} else {
url += 'titles=' + article.removeAnchor().urlString();
}
url += '&prop=revisions|pageprops|info|images|categories&rvprop=ids|timestamp|flags|comment|user|content&cllimit=max&imlimit=max';
htmlGenerator=APIrevisionPreviewHTML;
break;
}
pendingNavpopTask(navpop);
var callback=function(d){
log( "callback of API functions was hit" );
showAPIPreview(queryType, htmlGenerator(article,d,navpop), navpop.idNumber, navpop, d);
};
var go = function(){
getPageWithCaching(url, callback, navpop);
return true;
};
if (navpop.visible || !getValueOf('popupLazyDownloads')) { go(); }
else { navpop.addHook(go, 'unhide', 'before', 'DOWNLOAD_'+queryType+'_QUERY_DATA'); }
}
function linkList(list) {
list.sort(function(x,y) { return (x==y ? 0 : (x<y ? -1 : 1)); });
var buf=[];
for (var i=0; i<list.length; ++i) {
buf.push(wikiLink({article: new Title(list[i]),
text: list[i].split(' ').join(' '),
action: 'view'}));
}
return buf.join(', ');
}
function getTimeOffset() {
var tz = mw.user.options.get('timecorrection');
if(tz) {
if( tz.indexOf('|') > -1 ) {
// New format
return parseInt(tz.split('|')[1],10);
} else if ( tz.indexOf(':') > -1 ) {
// Old format
return( parseInt(tz,10)*60 + parseInt(tz.split(':')[1],10) );
}
}
return 0;
}
/*
* Creates a HTML table that's shown in the history and user-contribs popups.
* @param {Object[]} h - a list of revisions, returned from the API
* @param {boolean} reallyContribs - true only if we're displaying user contributions
*/
function editPreviewTable(article, h, reallyContribs, timeOffset) {
var html=['<table>'];
var day=null;
var curart=article;
var page=null;
var makeFirstColumnLinks;
if(reallyContribs) {
// We're showing user contributions, so make (diff | hist) links
makeFirstColumnLinks = function(currentRevision) {
var result = '(';
result += '<a href="' + pg.wiki.titlebase +
new Title(currentRevision.title).urlString() + '&diff=prev' +
'&oldid=' + currentRevision.revid + '">' + popupString('diff') + '</a>';
result += ' | ';
result += '<a href="' + pg.wiki.titlebase +
new Title(currentRevision.title).urlString() + '&action=history">' +
popupString('hist') + '</a>';
result += ')';
return result;
};
} else {
// It's a regular history page, so make (cur | last) links
var firstRevid = h[0].revid;
makeFirstColumnLinks = function(currentRevision) {
var result = '(';
result += '<a href="' + pg.wiki.titlebase + new Title(curart).urlString() +
'&diff=' + firstRevid + '&oldid=' + currentRevision.revid + '">' + popupString('cur') + '</a>';
result += ' | ';
result += '<a href="' + pg.wiki.titlebase + new Title(curart).urlString() +
'&diff=prev&oldid=' + currentRevision.revid + '">' + popupString('last') + '</a>';
result += ')';
return result;
};
}
for (var i=0; i<h.length; ++i) {
if (reallyContribs) {
page = h[i].title;
curart = new Title(page);
}
var minor = h[i].minor ? '<b>m </b>' : '';
var editDate = adjustDate(getDateFromTimestamp(h[i].timestamp), timeOffset);
var thisDay = dayFormat(editDate);
var thisTime = timeFormat(editDate);
if (thisDay == day) {
thisDay = '';
} else {
day = thisDay;
}
if (thisDay) {
html.push( '<tr><td colspan=3><span class="popup_history_date">' +
thisDay+'</span></td></tr>' );
}
html.push('<tr class="popup_history_row_' + ( (i%2) ? 'odd' : 'even') + '">');
html.push('<td>' + makeFirstColumnLinks(h[i]) + '</td>');
html.push('<td>' +
'<a href="' + pg.wiki.titlebase + new Title(curart).urlString() +
'&oldid=' + h[i].revid + '">' + thisTime + '</a></td>');
var col3url='', col3txt='';
if (!reallyContribs) {
var user=h[i].user;
if( !h[i].userhidden ) {
if( pg.re.ipUser.test(user) ) {
col3url=pg.wiki.titlebase + mw.config.get('wgFormattedNamespaces')[pg.nsSpecialId] + ':Contributions&target=' + new Title(user).urlString();
} else {
col3url=pg.wiki.titlebase + mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' + new Title(user).urlString();
}
col3txt=pg.escapeQuotesHTML(user);
} else {
col3url=getValueOf('popupRevDelUrl');
col3txt=pg.escapeQuotesHTML( popupString('revdel'));
}
} else {
col3url=pg.wiki.titlebase + curart.urlString();
col3txt=pg.escapeQuotesHTML(page);
}
html.push('<td>' + (reallyContribs ? minor : '') +
'<a href="' + col3url + '">' + col3txt + '</a></td>');
var comment='';
var c=h[i].comment || h[i].content;
if (c) {
comment=new Previewmaker(c, new Title(curart).toUrl()).editSummaryPreview();
} else if ( h[i].commenthidden ) {
comment=popupString('revdel');
}
html.push('<td>' + (!reallyContribs ? minor : '') + comment + '</td>');
html.push('</tr>');
html=[html.join('')];
}
html.push('</table>');
return html.join('');
}
function getDateFromTimestamp(t) {
var s=t.split(/[^0-9]/);
switch(s.length) {
case 0: return null;
case 1: return new Date(s[0]);
case 2: return new Date(s[0], s[1]-1);
case 3: return new Date(s[0], s[1]-1, s[2]);
case 4: return new Date(s[0], s[1]-1, s[2], s[3]);
case 5: return new Date(s[0], s[1]-1, s[2], s[3], s[4]);
case 6: return new Date(s[0], s[1]-1, s[2], s[3], s[4], s[5]);
default: return new Date(s[0], s[1]-1, s[2], s[3], s[4], s[5], s[6]);
}
}
function adjustDate(d, offset) {
// offset is in minutes
var o=offset * 60 * 1000;
return new Date( +d + o);
}
function dayFormat(editDate, utc) {
if (utc) { return map(zeroFill, [editDate.getUTCFullYear(), editDate.getUTCMonth()+1, editDate.getUTCDate()]).join('-'); }
return map(zeroFill, [editDate.getFullYear(), editDate.getMonth()+1, editDate.getDate()]).join('-');
}
function timeFormat(editDate, utc) {
if (utc) { return map(zeroFill, [editDate.getUTCHours(), editDate.getUTCMinutes(), editDate.getUTCSeconds()]).join(':'); }
return map(zeroFill, [editDate.getHours(), editDate.getMinutes(), editDate.getSeconds()]).join(':');
}
function showAPIPreview(queryType, html, id, navpop, download) {
// DJ: done
var target='popupPreview';
completedNavpopTask(navpop);
switch (queryType) {
case 'imagelinks':
case 'category':
target='popupPostPreview'; break;
case 'userinfo':
target='popupUserData'; break;
case 'revision':
insertPreview(download);
return;
}
setPopupTipsAndHTML(html, target, id);
}
function APIrevisionPreviewHTML(article, download) {
try{
var jsObj=getJsObj(download.data);
var page=anyChild(jsObj.query.pages);
if( page.missing ) {
// TODO we need to fix this proper later on
download.owner = null;
return;
}
var content = (
page &&
page.revisions &&
page.revisions[0].contentmodel === 'wikitext'
) ? page.revisions[0].content : null;
if( typeof content === 'string' )
{
download.data = content;
download.lastModified = new Date(page.revisions[0].timestamp);
}
} catch(someError) {
return 'Revision preview failed :(';
}
}
function APIbacklinksPreviewHTML(article, download/*, navpop*/ ) {
try {
var jsObj=getJsObj(download.data);
var list=jsObj.query.backlinks;
var html=[];
if (!list) { return popupString('No backlinks found'); }
for ( var i=0; i < list.length; i++ ) {
var t=new Title(list[i].title);
html.push('<a href="' + pg.wiki.titlebase + t.urlString() + '">' + t + '</a>');
}
html=html.join(', ');
if (jsObj['continue'] && jsObj['continue'].blcontinue) {
html += popupString(' and more');
}
return html;
} catch (someError) {
return 'backlinksPreviewHTML went wonky';
}
}
pg.fn.APIsharedImagePagePreviewHTML = function APIsharedImagePagePreviewHTML(obj) {
log( "APIsharedImagePagePreviewHTML" );
var popupid = obj.requestid;
if( obj.query && obj.query.pages )
{
var page=anyChild(obj.query.pages );
var content = (
page &&
page.revisions &&
page.revisions[0].contentmodel === 'wikitext'
) ? page.revisions[0].content : null;
if( typeof content === 'string' )
{
/* Not entirely safe, but the best we can do */
var p=new Previewmaker(content, pg.current.link.navpopup.article, pg.current.link.navpopup);
p.makePreview();
setPopupHTML( p.html, "popupSecondPreview", popupid );
}
}
};
function APIimagepagePreviewHTML(article, download, navpop) {
try {
var jsObj=getJsObj(download.data);
var page=anyChild(jsObj.query.pages);
var content= (
page &&
page.revisions &&
page.revisions[0].contentmodel === 'wikitext'
) ? page.revisions[0].content : null;
var ret='';
var alt='';
try{alt=navpop.parentAnchor.childNodes[0].alt;} catch(e){}
if (alt) {
ret = ret + '<hr /><b>' + popupString('Alt text:') + '</b> ' + pg.escapeQuotesHTML(alt);
}
if (typeof content === 'string') {
var p=prepPreviewmaker(content, article, navpop);
p.makePreview();
if (p.html) { ret += '<hr />' + p.html; }
if (getValueOf('popupSummaryData')) {
var info=getPageInfo(content, download);
log(info);
setPopupTrailer(info, navpop.idNumber);
}
}
if (page && page.imagerepository == "shared" ) {
var art=new Title(article);
var encart = encodeURIComponent( "File:" + art.stripNamespace() );
var shared_url = pg.wiki.apicommonsbase + '?format=json&formatversion=2' +
'&callback=pg.fn.APIsharedImagePagePreviewHTML' +
'&requestid=' + navpop.idNumber +
'&action=query&prop=revisions&rvprop=content&titles=' + encart;
ret = ret +'<hr />' + popupString( 'Image from Commons') +
': <a href="' + pg.wiki.commonsbase + '?title=' + encart + '">' +
popupString( 'Description page') + '</a>';
mw.loader.load( shared_url );
}
showAPIPreview('imagelinks', APIimagelinksPreviewHTML(article,download), navpop.idNumber, download);
return ret;
} catch (someError) {
return 'API imagepage preview failed :(';
}
}
function APIimagelinksPreviewHTML(article, download) {
try {
var jsobj=getJsObj(download.data);
var list=jsobj.query.imageusage;
if (list) {
var ret=[];
for (var i=0; i < list.length; i++) {
ret.push(list[i].title);
}
if (ret.length === 0) { return popupString('No image links found'); }
return '<h2>' + popupString('File links') + '</h2>' + linkList(ret);
} else {
return popupString('No image links found');
}
} catch(someError) {
return 'Image links preview generation failed :(';
}
}
function APIcategoryPreviewHTML(article, download) {
try{
var jsobj=getJsObj(download.data);
var list=jsobj.query.categorymembers;
var ret=[];
for (var p=0; p < list.length; p++) {
ret.push(list[p].title);
}
if (ret.length === 0) { return popupString('Empty category'); }
ret = '<h2>' + tprintf('Category members (%s shown)', [ret.length]) + '</h2>' +linkList(ret);
if (jsobj['continue'] && jsobj['continue'].cmcontinue) {
ret += popupString(' and more');
}
return ret;
} catch(someError) {
return 'Category preview failed :(';
}
}
function APIuserInfoPreviewHTML(article, download) {
var ret=[];
var queryobj = {};
try{
queryobj=getJsObj(download.data).query;
} catch(someError) { return 'Userinfo preview failed :('; }
var user=anyChild(queryobj.users);
if (user) {
var globaluserinfo=queryobj.globaluserinfo;
if (user.invalid === '') {
ret.push( popupString( 'Invalid user') );
} else if (user.missing === '') {
ret.push( popupString( 'Not a registered username') );
}
if( user.blockedby ) {
if( user.blockpartial ) {
ret.push('<b>' + popupString('Has blocks') + '</b>');
} else {
ret.push('<b>' + popupString('CẤM') + '</b>');
}
}
if( globaluserinfo && ( 'locked' in globaluserinfo || 'hidden' in globaluserinfo ) ) {
var lockedSulAccountIsAttachedToThis = true;
for( var i=0; globaluserinfo.unattached && i < globaluserinfo.unattached.length; i++) {
if ( globaluserinfo.unattached[i].wiki === mw.config.get('wgDBname') ) {
lockedSulAccountIsAttachedToThis=false;
break;
}
}
if (lockedSulAccountIsAttachedToThis) {
if ( 'locked' in globaluserinfo ) ret.push('<b><i>' + popupString('LOCKED') + '</i></b>');
if ( 'hidden' in globaluserinfo ) ret.push('<b><i>' + popupString('HIDDEN') + '</i></b>');
}
}
if( getValueOf('popupShowGender') && user.gender ) {
switch( user.gender ) {
case "male": ret.push( popupString( "\u2642" ) ); break;
case "female": ret.push( popupString( "\u2640" ) ); break;
}
}
if( user.groups ) {
for( var j=0; j < user.groups.length; j++) {
var currentGroup = user.groups[j];
if( ["*", "user", "autoconfirmed", "extendedconfirmed"].indexOf( currentGroup ) === -1 ) {
ret.push( pg.escapeQuotesHTML(user.groups[j]) );
}
}
}
if( globaluserinfo && globaluserinfo.groups ) {
for( var k=0; k < globaluserinfo.groups.length; k++) {
ret.push( '<i>'+pg.escapeQuotesHTML(globaluserinfo.groups[k])+'</i>' );
}
}
if( user.registration )
ret.push( pg.escapeQuotesHTML((user.editcount?user.editcount:'0') + popupString(' sửa đổi từ: ') + (user.registration?dayFormat(getDateFromTimestamp(user.registration)):'')) );
}
if (queryobj.usercontribs && queryobj.usercontribs.length) {
ret.push( popupString('sửa đổi lần cuối vào ') + dayFormat(getDateFromTimestamp(queryobj.usercontribs[0].timestamp)) );
}
if (queryobj.blocks) {
ret.push( popupString( 'IP user') ); //we only request list=blocks for IPs
for (var l=0; l<queryobj.blocks.length; l++) {
console.log(queryobj);
var rbstr = queryobj.blocks[l].rangestart === queryobj.blocks[l].rangeend ? 'BLOCK' : 'RANGEBLOCK';
rbstr = (!Array.isArray(queryobj.blocks[l].restrictions) ? 'Has ' + rbstr.toLowerCase() + 's' : rbstr + 'ED');
ret.push('<b>' + popupString(rbstr) + '</b>' );
}
}
ret = '<hr />' + ret.join( ', ' );
return ret;
}
function APIcontribsPreviewHTML(article, download, navpop) {
return APIhistoryPreviewHTML(article, download, navpop, true);
}
function APIhistoryPreviewHTML(article, download, navpop, reallyContribs) {
try {
var jsobj=getJsObj(download.data);
var edits = [];
if( reallyContribs ) {
edits=jsobj.query.usercontribs;
} else {
edits=anyChild(jsobj.query.pages).revisions;
}
var ret=editPreviewTable(article, edits, reallyContribs, getTimeOffset());
return ret;
} catch (someError) {
return 'History preview failed :-(';
}
}
//</NOLITE>
// ENDFILE: querypreview.js
// STARTFILE: debug.js
////////////////////////////////////////////////////////////////////
// Debugging functions
////////////////////////////////////////////////////////////////////
function setupDebugging() {
//<NOLITE>
if (window.popupDebug) { // popupDebug is set from .version
window.log=function(x) { //if(gMsg!='')gMsg += '\n'; gMsg+=time() + ' ' + x; };
window.console.log(x);
};
window.errlog=function(x) {
window.console.error(x);
};
log('Initializing logger');
} else {
//</NOLITE>
window.log = function() {};
window.errlog = function() {};
//<NOLITE>
}
//</NOLITE>
}
// ENDFILE: debug.js
// STARTFILE: images.js
// load image of type Title.
function loadImage(image, navpop) {
if (typeof image.stripNamespace != 'function') { alert('loadImages bad'); }
// API call to retrieve image info.
if ( !getValueOf('popupImages') ) return;
if ( !isValidImageName(image) ) return false;
var art=image.urlString();
var url=pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query';
url += '&prop=imageinfo&iiprop=url|mime&iiurlwidth=' + getValueOf('popupImageSizeLarge');
url += '&titles=' + art;
pendingNavpopTask(navpop);
var callback=function(d){
popupsInsertImage(navpop.idNumber, navpop, d);
};
var go = function(){
getPageWithCaching(url, callback, navpop);
return true;
};
if (navpop.visible || !getValueOf('popupLazyDownloads')) { go(); }
else { navpop.addHook(go, 'unhide', 'after', 'DOWNLOAD_IMAGE_QUERY_DATA'); }
}
function popupsInsertImage(id, navpop, download) {
log( "popupsInsertImage");
var imageinfo;
try {
var jsObj=getJsObj(download.data);
var imagepage=anyChild(jsObj.query.pages);
if (typeof imagepage.imageinfo === 'undefined') return;
imageinfo = imagepage.imageinfo[0];
} catch (someError) {
log( "popupsInsertImage failed :(" );
return;
}
var popupImage = document.getElementById("popupImg"+id);
if (!popupImage) {
log( "could not find insertion point for image");
return;
}
popupImage.width=getValueOf('popupImageSize');
popupImage.style.display='inline';
// Set the source for the image.
if( imageinfo.thumburl )
popupImage.src=imageinfo.thumburl;
else if( imageinfo.mime.indexOf("image") === 0 ){
popupImage.src=imageinfo.url;
log( "a thumb could not be found, using original image" );
} else log( "fullsize imagethumb, but not sure if it's an image");
var a=document.getElementById("popupImageLink"+id);
if (a === null) { return null; }
// Determine the action of the surrouding imagelink.
switch (getValueOf('popupThumbAction')) {
case 'imagepage':
if (pg.current.article.namespaceId()!=pg.nsImageId) {
a.href=imageinfo.descriptionurl;
// FIXME: unreliable pg.idNumber
popTipsSoonFn('popupImage' + id)();
break;
}
/* falls through */
case 'sizetoggle':
a.onclick=toggleSize;
a.title=popupString('Toggle image size');
return;
case 'linkfull':
a.href = imageinfo.url;
a.title=popupString('Open full-size image');
return;
}
}
// Toggles the image between inline small and navpop fullwidth.
// It's the same image, no actual sizechange occurs, only display width.
function toggleSize() {
var imgContainer=this;
if (!imgContainer) {
alert('imgContainer is null :/');
return;
}
var img=imgContainer.firstChild;
if (!img) {
alert('img is null :/');
return;
}
if (!img.style.width || img.style.width==='') {
img.style.width='100%';
} else {
img.style.width='';
}
}
// Returns one title of an image from wikiText.
function getValidImageFromWikiText(wikiText) {
// nb in pg.re.image we're interested in the second bracketed expression
// this may change if the regex changes :-(
//var match=pg.re.image.exec(wikiText);
var matched=null;
var match;
// strip html comments, used by evil bots :-(
var t = removeMatchesUnless(wikiText, RegExp('(<!--[\\s\\S]*?-->)'), 1,
RegExp('^<!--[^[]*popup', 'i'));
while ( ( match = pg.re.image.exec(t) ) ) {
// now find a sane image name - exclude templates by seeking {
var m = match[2] || match[6];
if ( isValidImageName(m) ) {
matched=m;
break;
}
}
pg.re.image.lastIndex=0;
if (!matched) { return null; }
return mw.config.get('wgFormattedNamespaces')[pg.nsImageId]+':'+upcaseFirst(matched);
}
function removeMatchesUnless(str, re1, parencount, re2) {
var split=str.parenSplit(re1);
var c=parencount + 1;
for (var i=0; i<split.length; ++i) {
if ( i%c === 0 || re2.test(split[i]) ) { continue; }
split[i]='';
}
return split.join('');
}
//</NOLITE>
// ENDFILE: images.js
// STARTFILE: namespaces.js
// Set up namespaces and other non-strings.js localization
// (currently that means redirs too)
function setNamespaces() {
pg.nsSpecialId = -1;
pg.nsMainspaceId = 0;
pg.nsImageId = 6;
pg.nsUserId = 2;
pg.nsUsertalkId = 3;
pg.nsCategoryId = 14;
pg.nsTemplateId = 10;
}
function setRedirs() {
var r='redirect';
var R='REDIRECT';
var redirLists={
//<NOLITE>
'ar': [ R, 'تحويل' ],
'be': [ r, 'перанакіраваньне' ],
'bg': [ r, 'пренасочване', 'виж' ],
'bs': [ r, 'Preusmjeri', 'preusmjeri', 'PREUSMJERI' ],
'cs': [ R, 'PŘESMĚRUJ' ],
'cy': [ r, 'ail-cyfeirio' ],
'de': [ R, 'WEITERLEITUNG' ],
'el': [ R, 'ΑΝΑΚΑΤΕΥΘΥΝΣΗ'],
'eo': [ R, 'ALIDIREKTU', 'ALIDIREKTI' ],
'es': [ R, 'REDIRECCIÓN' ],
'et': [ r, 'suuna' ],
'ga': [ r, 'athsheoladh' ],
'gl': [ r, 'REDIRECCIÓN', 'REDIRECIONAMENTO'],
'he': [ R, 'הפניה' ],
'hu': [ R, 'ÁTIRÁNYÍTÁS' ],
'is': [ r, 'tilvísun', 'TILVÍSUN' ],
'it': [ R, 'RINVIA', 'Rinvia'],
'ja': [ R, '転送' ],
'mk': [ r, 'пренасочување', 'види' ],
'nds': [ r, 'wiederleiden' ],
'nl': [ R, 'DOORVERWIJZING' ],
'nn': [ r, 'omdiriger' ],
'pl': [ R, 'PATRZ', 'PRZEKIERUJ', 'TAM' ],
'pt': [ R, 'redir' ],
'ru': [ R, 'ПЕРЕНАПРАВЛЕНИЕ', 'ПЕРЕНАПР' ],
'sk': [ r, 'presmeruj' ],
'sr': [ r, 'Преусмери', 'преусмери', 'ПРЕУСМЕРИ', 'Preusmeri', 'preusmeri', 'PREUSMERI' ],
'tt': [ R, 'yünältü', 'перенаправление', 'перенапр' ],
'uk': [ R, 'ПЕРЕНАПРАВЛЕННЯ', 'ПЕРЕНАПР' ],
'vi': [ r, 'đổi' ],
'zh': [ R, '重定向'] // no comma
//</NOLITE>
};
var redirList=redirLists[ pg.wiki.lang ] || [r, R];
// Mediawiki is very tolerant about what comes after the #redirect at the start
pg.re.redirect=RegExp('^\\s*[#](' + redirList.join('|') + ').*?\\[{2}([^\\|\\]]*)(|[^\\]]*)?\\]{2}\\s*(.*)', 'i');
}
function setInterwiki() {
if (pg.wiki.wikimedia) {
// From https://meta.wikimedia.org/wiki/List_of_Wikipedias
pg.wiki.interwiki='aa|ab|ace|af|ak|als|am|an|ang|ar|arc|arz|as|ast|av|ay|az|ba|bar|bat-smg|bcl|be|be-x-old|bg|bh|bi|bjn|bm|bn|bo|bpy|br|bs|bug|bxr|ca|cbk-zam|cdo|ce|ceb|ch|cho|chr|chy|ckb|co|cr|crh|cs|csb|cu|cv|cy|da|de|diq|dsb|dv|dz|ee|el|eml|en|eo|es|et|eu|ext|fa|ff|fi|fiu-vro|fj|fo|fr|frp|frr|fur|fy|ga|gag|gan|gd|gl|glk|gn|got|gu|gv|ha|hak|haw|he|hi|hif|ho|hr|hsb|ht|hu|hy|hz|ia|id|ie|ig|ii|ik|ilo|io|is|it|iu|ja|jbo|jv|ka|kaa|kab|kbd|kg|ki|kj|kk|kl|km|kn|ko|koi|kr|krc|ks|ksh|ku|kv|kw|ky|la|lad|lb|lbe|lg|li|lij|lmo|ln|lo|lt|ltg|lv|map-bms|mdf|mg|mh|mhr|mi|mk|ml|mn|mo|mr|mrj|ms|mt|mus|mwl|my|myv|mzn|na|nah|nap|nds|nds-nl|ne|new|ng|nl|nn|no|nov|nrm|nv|ny|oc|om|or|os|pa|pag|pam|pap|pcd|pdc|pfl|pi|pih|pl|pms|pnb|pnt|ps|pt|qu|rm|rmy|rn|ro|roa-rup|roa-tara|ru|rue|rw|sa|sah|sc|scn|sco|sd|se|sg|sh|si|simple|sk|sl|sm|sn|so|sq|sr|srn|ss|st|stq|su|sv|sw|szl|ta|te|tet|tg|th|ti|tk|tl|tn|to|tpi|tr|ts|tt|tum|tw|ty|udm|ug|uk|ur|uz|ve|vec|vi|vls|vo|wa|war|wo|wuu|xal|xh|yi|yo|za|zea|zh|zh-classical|zh-min-nan|zh-yue|zu';
pg.re.interwiki=RegExp('^'+pg.wiki.interwiki+':');
} else {
pg.wiki.interwiki=null;
pg.re.interwiki=RegExp('^$');
}
}
// return a regexp pattern matching all variants to write the given namespace
function nsRe(namespaceId) {
var imageNamespaceVariants = [];
jQuery.each(mw.config.get('wgNamespaceIds'), function(_localizedNamespaceLc, _namespaceId) {
if (_namespaceId!=namespaceId) return;
_localizedNamespaceLc = upcaseFirst(_localizedNamespaceLc);
imageNamespaceVariants.push(mw.util.escapeRegExp(_localizedNamespaceLc).split(' ').join('[ _]'));
imageNamespaceVariants.push(mw.util.escapeRegExp(encodeURI(_localizedNamespaceLc)));
});
return '(?:' + imageNamespaceVariants.join('|') + ')';
}
function nsReImage() {
return nsRe(pg.nsImageId);
}
// ENDFILE: namespaces.js
// STARTFILE: selpop.js
//<NOLITE>
function getEditboxSelection() {
// see http://www.webgurusforum.com/8/12/0
var editbox;
try {
editbox=document.editform.wpTextbox1;
} catch (dang) { return; }
// IE, Opera
if (document.selection) { return document.selection.createRange().text; }
// Mozilla
var selStart = editbox.selectionStart;
var selEnd = editbox.selectionEnd;
return (editbox.value).substring(selStart, selEnd);
}
function doSelectionPopup() {
// popup if the selection looks like [[foo|anything afterwards at all
// or [[foo|bar]]text without ']]'
// or [[foo|bar]]
var sel=getEditboxSelection();
var open=sel.indexOf('[[');
var pipe=sel.indexOf('|');
var close=sel.indexOf(']]');
if (open == -1 || ( pipe == -1 && close == -1) ) { return; }
if (pipe != -1 && open > pipe || close != -1 && open > close) { return; }
if (getValueOf('popupOnEditSelection')=='boxpreview') {
return doSeparateSelectionPopup(sel);
}
var article=new Title(sel.substring(open+2, (pipe < 0) ? close : pipe)).urlString();
if (close > 0 && sel.substring(close+2).indexOf('[[') >= 0) {
return;
}
var a=document.createElement('a');
a.href=pg.wiki.titlebase + article;
mouseOverWikiLink2(a);
if (a.navpopup) {
a.navpopup.addHook(function(){runStopPopupTimer(a.navpopup);}, 'unhide', 'after');
}
}
function doSeparateSelectionPopup(str) {
var div=document.getElementById('selectionPreview');
if (!div) {
div = document.createElement('div');
div.id='selectionPreview';
try {
var box=document.editform.wpTextbox1;
box.parentNode.insertBefore(div, box);
} catch (error) {
return;
}
}
div.innerHTML=wiki2html(str);
div.ranSetupTooltipsAlready = false;
popTipsSoonFn('selectionPreview')();
}
//</NOLITE>
// ENDFILE: selpop.js
// STARTFILE: navpopup.js
/**
@fileoverview Defines two classes: {@link Navpopup} and {@link Mousetracker}.
<code>Navpopup</code> describes popups: when they appear, where, what
they look like and so on.
<code>Mousetracker</code> "captures" the mouse using
<code>document.onmousemove</code>.
*/
/**
Creates a new Mousetracker.
@constructor
@class The Mousetracker class. This monitors mouse movements and manages associated hooks.
*/
function Mousetracker() {
/**
Interval to regularly run the hooks anyway, in milliseconds.
@type Integer
*/
this.loopDelay=400;
/**
Timer for the loop.
@type Timer
*/
this.timer=null;
/**
Flag - are we switched on?
@type Boolean
*/
this.active=false;
/**
Flag - are we probably inaccurate, i.e. not reflecting the actual mouse position?
*/
this.dirty=true;
/**
Array of hook functions.
@private
@type Array
*/
this.hooks=[];
}
/**
Adds a hook, to be called when we get events.
@param {Function} f A function which is called as
<code>f(x,y)</code>. It should return <code>true</code> when it
wants to be removed, and <code>false</code> otherwise.
*/
Mousetracker.prototype.addHook = function (f) {
this.hooks.push(f);
};
/**
Runs hooks, passing them the x
and y coords of the mouse. Hook functions that return true are
passed to {@link Mousetracker#removeHooks} for removal.
@private
*/
Mousetracker.prototype.runHooks = function () {
if (!this.hooks || !this.hooks.length) { return; }
//log('Mousetracker.runHooks; we got some hooks to run');
var remove=false;
var removeObj={};
// this method gets called a LOT -
// pre-cache some variables
var x=this.x, y=this.y, len = this.hooks.length;
for (var i=0; i<len; ++i) {
//~ run the hook function, and remove it if it returns true
if (this.hooks[i](x, y)===true) {
remove=true;
removeObj[i]=true;
}
}
if (remove) { this.removeHooks(removeObj); }
};
/**
Removes hooks.
@private
@param {Object} removeObj An object whose keys are the index
numbers of functions for removal, with values that evaluate to true
*/
Mousetracker.prototype.removeHooks = function(removeObj) {
var newHooks=[];
var len = this.hooks.length;
for (var i=0; i<len; ++i) {
if (! removeObj[i]) { newHooks.push(this.hooks[i]); }
}
this.hooks=newHooks;
};
/**
Event handler for mouse wiggles.
We simply grab the event, set x and y and run the hooks.
This makes the cpu all hot and bothered :-(
@private
@param {Event} e Mousemove event
*/
Mousetracker.prototype.track=function (e) {
//~ Apparently this is needed in IE.
e = e || window.event;
var x, y;
if (e) {
if (e.pageX) { x=e.pageX; y=e.pageY; }
else if (typeof e.clientX!='undefined') {
var left, top, docElt = document.documentElement;
if (docElt) { left=docElt.scrollLeft; }
left = left || document.body.scrollLeft || document.scrollLeft || 0;
if (docElt) { top=docElt.scrollTop; }
top = top || document.body.scrollTop || document.scrollTop || 0;
x=e.clientX + left;
y=e.clientY + top;
} else { return; }
this.setPosition(x,y);
}
};
/**
Sets the x and y coordinates stored and takes appropriate action,
running hooks as appropriate.
@param {Integer} x, y Screen coordinates to set
*/
Mousetracker.prototype.setPosition=function(x,y) {
this.x = x;
this.y = y;
if (this.dirty || this.hooks.length === 0) { this.dirty=false; return; }
if (typeof this.lastHook_x != 'number') { this.lastHook_x = -100; this.lastHook_y=-100; }
var diff = (this.lastHook_x - x)*(this.lastHook_y - y);
diff = (diff >= 0) ? diff : -diff;
if ( diff > 1 ) {
this.lastHook_x=x;
this.lastHook_y=y;
if (this.dirty) { this.dirty = false; }
else { this.runHooks(); }
}
};
/**
Sets things in motion, unless they are already that is, registering an event handler on <code>document.onmousemove</code>.
A half-hearted attempt is made to preserve the old event handler if there is one.
*/
Mousetracker.prototype.enable = function () {
if (this.active) { return; }
this.active=true;
//~ Save the current handler for mousemove events. This isn't too
//~ robust, of course.
this.savedHandler=document.onmousemove;
//~ Gotta save @tt{this} again for the closure, and use apply for
//~ the member function.
var savedThis=this;
document.onmousemove=function (e) {savedThis.track.apply(savedThis, [e]);};
if (this.loopDelay) { this.timer = setInterval(function() { //log('loop delay in mousetracker is working');
savedThis.runHooks();}, this.loopDelay); }
};
/**
Disables the tracker, removing the event handler.
*/
Mousetracker.prototype.disable = function () {
if (!this.active) { return; }
if (typeof this.savedHandler === 'function') {
document.onmousemove=this.savedHandler;
} else { delete document.onmousemove; }
if (this.timer) { clearInterval(this.timer); }
this.active=false;
};
/**
Creates a new Navpopup.
Gets a UID for the popup and
@param init Contructor object. If <code>init.draggable</code> is true or absent, the popup becomes draggable.
@constructor
@class The Navpopup class. This generates popup hints, and does some management of them.
*/
function Navpopup(/*init*/) {
//alert('new Navpopup(init)');
/** UID for each Navpopup instance.
Read-only.
@type integer
*/
this.uid=Navpopup.uid++;
/**
Read-only flag for current visibility of the popup.
@type boolean
@private
*/
this.visible=false;
/** Flag to be set when we want to cancel a previous request to
show the popup in a little while.
@private
@type boolean
*/
this.noshow=false;
/** Categorised list of hooks.
@see #runHooks
@see #addHook
@private
@type Object
*/
this.hooks={
'create': [],
'unhide': [],
'hide': []
};
/** list of unique IDs of hook functions, to avoid duplicates
@private
*/
this.hookIds={};
/** List of downloads associated with the popup.
@private
@type Array
*/
this.downloads=[];
/** Number of uncompleted downloads.
@type integer
*/
this.pending=null;
/** Tolerance in pixels when detecting whether the mouse has left the popup.
@type integer
*/
this.fuzz=5;
/** Flag to toggle running {@link #limitHorizontalPosition} to regulate the popup's position.
@type boolean
*/
this.constrained=true;
/** The popup width in pixels.
@private
@type integer
*/
this.width=0;
/** The popup width in pixels.
@private
@type integer
*/
this.height=0;
/** The main content DIV element.
@type HTMLDivElement
*/
this.mainDiv=null;
this.createMainDiv();
// if (!init || typeof init.popups_draggable=='undefined' || init.popups_draggable) {
// this.makeDraggable(true);
// }
}
/**
A UID for each Navpopup. This constructor property is just a counter.
@type integer
@private
*/
Navpopup.uid=0;
/**
Retrieves the {@link #visible} attribute, indicating whether the popup is currently visible.
@type boolean
*/
Navpopup.prototype.isVisible=function() {
return this.visible;
};
/**
Repositions popup using CSS style.
@private
@param {integer} x x-coordinate (px)
@param {integer} y y-coordinate (px)
@param {boolean} noLimitHor Don't call {@link #limitHorizontalPosition}
*/
Navpopup.prototype.reposition= function (x,y, noLimitHor) {
log ('reposition('+x+','+y+','+noLimitHor+')');
if (typeof x != 'undefined' && x !== null) { this.left=x; }
if (typeof y != 'undefined' && y !== null) { this.top=y; }
if (typeof this.left != 'undefined' && typeof this.top != 'undefined') {
this.mainDiv.style.left=this.left + 'px';
this.mainDiv.style.top=this.top + 'px';
}
if (!noLimitHor) { this.limitHorizontalPosition(); }
//console.log('navpop'+this.uid+' - (left,top)=(' + this.left + ',' + this.top + '), css=('
//+ this.mainDiv.style.left + ',' + this.mainDiv.style.top + ')');
};
/**
Prevents popups from being in silly locations. Hopefully.
Should not be run if {@link #constrained} is true.
@private
*/
Navpopup.prototype.limitHorizontalPosition=function() {
if (!this.constrained || this.tooWide) { return; }
this.updateDimensions();
var x=this.left;
var w=this.width;
var cWidth=document.body.clientWidth;
// log('limitHorizontalPosition: x='+x+
// ', this.left=' + this.left +
// ', this.width=' + this.width +
// ', cWidth=' + cWidth);
if ( (x+w) >= cWidth ||
( x > 0 &&
this.maxWidth &&
this.width < this.maxWidth &&
this.height > this.width &&
x > cWidth - this.maxWidth ) ) {
// This is a very nasty hack. There has to be a better way!
// We find the "natural" width of the div by positioning it at the far left
// then reset it so that it should be flush right (well, nearly)
this.mainDiv.style.left='-10000px';
this.mainDiv.style.width = this.maxWidth + 'px';
var naturalWidth=parseInt(this.mainDiv.offsetWidth, 10);
var newLeft=cWidth - naturalWidth - 1;
if (newLeft < 0) { newLeft = 0; this.tooWide=true; } // still unstable for really wide popups?
log ('limitHorizontalPosition: moving to ('+newLeft + ','+ this.top+');' + ' naturalWidth=' + naturalWidth + ', clientWidth=' + cWidth);
this.reposition(newLeft, null, true);
}
};
/**
Counter indicating the z-order of the "highest" popup.
We start the z-index at 1000 so that popups are above everything
else on the screen.
@private
@type integer
*/
Navpopup.highest=1000;
/**
Brings popup to the top of the z-order.
We increment the {@link #highest} property of the contructor here.
@private
*/
Navpopup.prototype.raise = function () {
this.mainDiv.style.zIndex=Navpopup.highest + 1;
++Navpopup.highest;
};
/**
Shows the popup provided {@link #noshow} is not true.
Updates the position, brings the popup to the top of the z-order and unhides it.
*/
Navpopup.prototype.show = function () {
//document.title+='s';
if (this.noshow) { return; }
//document.title+='t';
this.reposition();
this.raise();
this.unhide();
};
/**
Checks to see if the mouse pointer has
stabilised (checking every <code>time</code>/2 milliseconds) and runs the
{@link #show} method if it has.
@param {integer} time The minimum time (ms) before the popup may be shown.
*/
Navpopup.prototype.showSoonIfStable = function (time) {
log ('showSoonIfStable, time='+time);
if (this.visible) { return; }
this.noshow = false;
//~ initialize these variables so that we never run @tt{show} after
//~ just half the time
this.stable_x = -10000; this.stable_y = -10000;
var stableShow = function() {
log('stableShow called');
var new_x = Navpopup.tracker.x, new_y = Navpopup.tracker.y;
var dx = savedThis.stable_x - new_x, dy = savedThis.stable_y - new_y;
var fuzz2 = 0; // savedThis.fuzz * savedThis.fuzz;
//document.title += '[' + [savedThis.stable_x,new_x, savedThis.stable_y,new_y, dx, dy, fuzz2].join(',') + '] ';
if ( dx * dx <= fuzz2 && dy * dy <= fuzz2 ) {
log ('mouse is stable');
clearInterval(savedThis.showSoonStableTimer);
savedThis.reposition.apply(savedThis, [new_x + 2, new_y + 2]);
savedThis.show.apply(savedThis, []);
savedThis.limitHorizontalPosition.apply(savedThis, []);
return;
}
savedThis.stable_x = new_x; savedThis.stable_y = new_y;
};
var savedThis = this;
this.showSoonStableTimer = setInterval(stableShow, time/2);
};
/**
Sets the {@link #noshow} flag and hides the popup. This should be called
when the mouse leaves the link before
(or after) it's actually been displayed.
*/
Navpopup.prototype.banish = function () {
log ('banish called');
// hide and prevent showing with showSoon in the future
this.noshow=true;
if (this.showSoonStableTimer) {
log('clearing showSoonStableTimer');
clearInterval(this.showSoonStableTimer);
}
this.hide();
};
/**
Runs hooks added with {@link #addHook}.
@private
@param {String} key Key name of the {@link #hooks} array - one of 'create', 'unhide', 'hide'
@param {String} when Controls exactly when the hook is run: either 'before' or 'after'
*/
Navpopup.prototype.runHooks = function (key, when) {
if (!this.hooks[key]) { return; }
var keyHooks=this.hooks[key];
var len=keyHooks.length;
for (var i=0; i< len; ++i) {
if (keyHooks[i] && keyHooks[i].when == when) {
if (keyHooks[i].hook.apply(this, [])) {
// remove the hook
if (keyHooks[i].hookId) {
delete this.hookIds[keyHooks[i].hookId];
}
keyHooks[i]=null;
}
}
}
};
/**
Adds a hook to the popup. Hook functions are run with <code>this</code> set to refer to the Navpopup instance, and no arguments.
@param {Function} hook The hook function. Functions that return true are deleted.
@param {String} key Key name of the {@link #hooks} array - one of 'create', 'unhide', 'hide'
@param {String} when Controls exactly when the hook is run: either 'before' or 'after'
@param {String} uid A truthy string identifying the hook function; if it matches another hook in this position, it won't be added again.
*/
Navpopup.prototype.addHook = function ( hook, key, when, uid ) {
when = when || 'after';
if (!this.hooks[key]) { return; }
// if uid is specified, don't add duplicates
var hookId=null;
if (uid) {
hookId=[key,when,uid].join('|');
if (this.hookIds[hookId]) {
return;
}
this.hookIds[hookId]=true;
}
this.hooks[key].push( {hook: hook, when: when, hookId: hookId} );
};
/**
Creates the main DIV element, which contains all the actual popup content.
Runs hooks with key 'create'.
@private
*/
Navpopup.prototype.createMainDiv = function () {
if (this.mainDiv) { return; }
this.runHooks('create', 'before');
var mainDiv=document.createElement('div');
var savedThis=this;
mainDiv.onclick=function(e) {savedThis.onclickHandler(e);};
mainDiv.className=(this.className) ? this.className : 'navpopup_maindiv';
mainDiv.id=mainDiv.className + this.uid;
mainDiv.style.position='absolute';
mainDiv.style.minWidth = '350px';
mainDiv.style.display='none';
mainDiv.className='navpopup';
// easy access to javascript object through DOM functions
mainDiv.navpopup=this;
this.mainDiv=mainDiv;
document.body.appendChild(mainDiv);
this.runHooks('create', 'after');
};
/**
Calls the {@link #raise} method.
@private
*/
Navpopup.prototype.onclickHandler=function(/*e*/) {
this.raise();
};
/**
Makes the popup draggable, using a {@link Drag} object.
@private
*/
Navpopup.prototype.makeDraggable=function(handleName) {
if (!this.mainDiv) { this.createMainDiv(); }
var drag=new Drag();
if (!handleName) {
drag.startCondition=function(e) {
try { if (!e.shiftKey) { return false; } } catch (err) { return false; }
return true;
};
}
var dragHandle;
if (handleName) dragHandle = document.getElementById(handleName);
if (!dragHandle) dragHandle = this.mainDiv;
var np=this;
drag.endHook=function(x,y) {
Navpopup.tracker.dirty=true;
np.reposition(x,y);
};
drag.init(dragHandle,this.mainDiv);
};
/** Hides the popup using CSS. Runs hooks with key 'hide'.
Sets {@link #visible} appropriately. {@link #banish} should be called externally instead of this method.
@private
*/
Navpopup.prototype.hide = function () {
this.runHooks('hide', 'before');
this.abortDownloads();
if (typeof this.visible != 'undefined' && this.visible) {
this.mainDiv.style.display='none';
this.visible=false;
}
this.runHooks('hide', 'after');
};
/** Shows the popup using CSS. Runs hooks with key 'unhide'.
Sets {@link #visible} appropriately. {@link #show} should be called externally instead of this method.
@private
*/
Navpopup.prototype.unhide = function () {
this.runHooks('unhide', 'before');
if (typeof this.visible != 'undefined' && !this.visible) {
this.mainDiv.style.display='inline';
this.visible=true;
}
this.runHooks('unhide', 'after');
};
/**
Sets the <code>innerHTML</code> attribute of the main div containing the popup content.
@param {String} html The HTML to set.
*/
Navpopup.prototype.setInnerHTML = function (html) {
this.mainDiv.innerHTML = html;
};
/**
Updates the {@link #width} and {@link #height} attributes with the CSS properties.
@private
*/
Navpopup.prototype.updateDimensions = function () {
this.width=parseInt(this.mainDiv.offsetWidth, 10);
this.height=parseInt(this.mainDiv.offsetHeight, 10);
};
/**
Checks if the point (x,y) is within {@link #fuzz} of the
{@link #mainDiv}.
@param {integer} x x-coordinate (px)
@param {integer} y y-coordinate (px)
@type boolean
*/
Navpopup.prototype.isWithin = function(x,y) {
//~ If we're not even visible, no point should be considered as
//~ being within the popup.
if (!this.visible) { return false; }
this.updateDimensions();
var fuzz=this.fuzz || 0;
//~ Use a simple box metric here.
return (x+fuzz >= this.left && x-fuzz <= this.left + this.width &&
y+fuzz >= this.top && y-fuzz <= this.top + this.height);
};
/**
Adds a download to {@link #downloads}.
@param {Downloader} download
*/
Navpopup.prototype.addDownload=function(download) {
if (!download) { return; }
this.downloads.push(download);
};
/**
Aborts the downloads listed in {@link #downloads}.
@see Downloader#abort
*/
Navpopup.prototype.abortDownloads=function() {
for(var i=0; i<this.downloads.length; ++i) {
var d=this.downloads[i];
if (d && d.abort) { d.abort(); }
}
this.downloads=[];
};
/**
A {@link Mousetracker} instance which is a property of the constructor (pseudo-global).
*/
Navpopup.tracker=new Mousetracker();
// ENDFILE: navpopup.js
// STARTFILE: diff.js
//<NOLITE>
/*
* Javascript Diff Algorithm
* By John Resig (http://ejohn.org/) and [[:en:User:Lupin]]
*
* More Info:
* http://ejohn.org/projects/javascript-diff-algorithm/
*/
function delFmt(x) {
if (!x.length) { return ''; }
return "<del class='popupDiff'>" + x.join('') +"</del>";
}
function insFmt(x) {
if (!x.length) { return ''; }
return "<ins class='popupDiff'>" + x.join('') +"</ins>";
}
function countCrossings(a, b, i, eject) {
// count the crossings on the edge starting at b[i]
if (!b[i].row && b[i].row !== 0) { return -1; }
var count=0;
for (var j=0; j<a.length; ++j) {
if (!a[j].row && a[j].row !== 0) { continue; }
if ( (j-b[i].row)*(i-a[j].row) > 0) {
if(eject) { return true; }
count++;
}
}
return count;
}
function shortenDiffString(str, context) {
var re=RegExp('(<del[\\s\\S]*?</del>|<ins[\\s\\S]*?</ins>)');
var splitted=str.parenSplit(re);
var ret=[''];
for (var i=0; i<splitted.length; i+=2) {
if (splitted[i].length < 2*context) {
ret[ret.length-1] += splitted[i];
if (i+1<splitted.length) { ret[ret.length-1] += splitted[i+1]; }
continue;
}
else {
if (i > 0) { ret[ret.length-1] += splitted[i].substring(0,context); }
if (i+1 < splitted.length) {
ret.push(splitted[i].substring(splitted[i].length-context) +
splitted[i+1]);
}
}
}
while (ret.length > 0 && !ret[0]) { ret = ret.slice(1); }
return ret;
}
function diffString( o, n, simpleSplit ) {
var splitRe=RegExp('([[]{2}|[\\]]{2}|[{]{2,3}|[}]{2,3}|[|]|=|<|>|[*:]+|\\s|\\b)');
// We need to split the strings o and n first, and entify() the parts
// individually, so that the HTML entities are never cut apart. (AxelBoldt)
var out, i, oSplitted, nSplitted;
if (simpleSplit) {
oSplitted=o.split(/\b/);
nSplitted=n.split(/\b/);
} else {
oSplitted=o.parenSplit(splitRe);
nSplitted=n.parenSplit(splitRe);
}
for (i=0; i<oSplitted.length; ++i) {oSplitted[i]=oSplitted[i].entify();}
for (i=0; i<nSplitted.length; ++i) {nSplitted[i]=nSplitted[i].entify();}
out = diff (oSplitted, nSplitted);
var str = "";
var acc=[]; // accumulator for prettier output
// crossing pairings -- eg 'A B' vs 'B A' -- cause problems, so let's iron them out
// this doesn't always do things optimally but it should be fast enough
var maxOutputPair=0;
for (i=0; i<out.n.length; ++i) {
if ( out.n[i].paired ) {
if( maxOutputPair > out.n[i].row ) {
// tangle - delete pairing
out.o[ out.n[i].row ]=out.o[ out.n[i].row ].text;
out.n[i]=out.n[i].text;
}
if (maxOutputPair < out.n[i].row) { maxOutputPair = out.n[i].row; }
}
}
// output the stuff preceding the first paired old line
for (i=0; i<out.o.length && !out.o[i].paired; ++i) { acc.push( out.o[i] ); }
str += delFmt(acc); acc=[];
// main loop
for ( i = 0; i < out.n.length; ++i ) {
// output unpaired new "lines"
while ( i < out.n.length && !out.n[i].paired ) { acc.push( out.n[i++] ); }
str += insFmt(acc); acc=[];
if ( i < out.n.length ) { // this new "line" is paired with the (out.n[i].row)th old "line"
str += out.n[i].text;
// output unpaired old rows starting after this new line's partner
var m = out.n[i].row + 1;
while ( m < out.o.length && !out.o[m].paired ) { acc.push ( out.o[m++] ); }
str += delFmt(acc); acc=[];
}
}
return str;
}
// see http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object
// FIXME: use obj.hasOwnProperty instead of this kludge!
var jsReservedProperties=RegExp('^(constructor|prototype|__((define|lookup)[GS]etter)__' +
'|eval|hasOwnProperty|propertyIsEnumerable' +
'|to(Source|String|LocaleString)|(un)?watch|valueOf)$');
function diffBugAlert(word) {
if (!diffBugAlert.list[word]) {
diffBugAlert.list[word]=1;
alert('Bad word: '+word+'\n\nPlease report this bug.');
}
}
diffBugAlert.list={};
function makeDiffHashtable(src) {
var ret={};
for ( var i = 0; i < src.length; i++ ) {
if ( jsReservedProperties.test(src[i]) ) { src[i] += '<!-- -->'; }
if ( !ret[ src[i] ] ) { ret[ src[i] ] = []; }
try { ret[ src[i] ].push( i ); } catch (err) { diffBugAlert(src[i]); }
}
return ret;
}
function diff( o, n ) {
// pass 1: make hashtable ns with new rows as keys
var ns = makeDiffHashtable(n);
// pass 2: make hashtable os with old rows as keys
var os = makeDiffHashtable(o);
// pass 3: pair unique new rows and matching unique old rows
var i;
for ( i in ns ) {
if ( ns[i].length == 1 && os[i] && os[i].length == 1 ) {
n[ ns[i][0] ] = { text: n[ ns[i][0] ], row: os[i][0], paired: true };
o[ os[i][0] ] = { text: o[ os[i][0] ], row: ns[i][0], paired: true };
}
}
// pass 4: pair matching rows immediately following paired rows (not necessarily unique)
for ( i = 0; i < n.length - 1; i++ ) {
if ( n[i].paired && ! n[i+1].paired && n[i].row + 1 < o.length && ! o[ n[i].row + 1 ].paired &&
n[i+1] == o[ n[i].row + 1 ] ) {
n[i+1] = { text: n[i+1], row: n[i].row + 1, paired: true };
o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1, paired: true };
}
}
// pass 5: pair matching rows immediately preceding paired rows (not necessarily unique)
for ( i = n.length - 1; i > 0; i-- ) {
if ( n[i].paired && ! n[i-1].paired && n[i].row > 0 && ! o[ n[i].row - 1 ].paired &&
n[i-1] == o[ n[i].row - 1 ] ) {
n[i-1] = { text: n[i-1], row: n[i].row - 1, paired: true };
o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1, paired: true };
}
}
return { o: o, n: n };
}
//</NOLITE>
// ENDFILE: diff.js
// STARTFILE: init.js
function setSiteInfo() {
if (window.popupLocalDebug) {
pg.wiki.hostname = 'en.wikipedia.org';
} else {
pg.wiki.hostname = location.hostname; // use in preference to location.hostname for flexibility (?)
}
pg.wiki.wikimedia=RegExp('(wiki([pm]edia|source|books|news|quote|versity)|wiktionary|mediawiki)[.]org').test(pg.wiki.hostname);
pg.wiki.wikia=RegExp('[.]wikia[.]com$', 'i').test(pg.wiki.hostname);
pg.wiki.isLocal=RegExp('^localhost').test(pg.wiki.hostname);
pg.wiki.commons=( pg.wiki.wikimedia && pg.wiki.hostname != 'commons.wikimedia.org') ? 'commons.wikimedia.org' : null;
pg.wiki.lang = mw.config.get('wgContentLanguage');
var port = location.port ? ':' + location.port : '';
pg.wiki.sitebase = pg.wiki.hostname + port;
}
function setUserInfo() {
var api = new mw.Api( {
ajax: {
headers: { 'Api-User-Agent': pg.misc.userAgent }
}
} );
var params = {
action: 'query',
list: 'users',
ususers: mw.config.get('wgUserName'),
usprop: 'rights'
};
pg.user.canReview = false;
if (getValueOf('popupReview')) {
api.get(params).done(function(data){
var rights = data.query.users[0].rights;
pg.user.canReview = rights.indexOf('review') !== -1; // TODO: Should it be a getValueOf('ReviewRight') ?
});
}
}
function setTitleBase() {
var protocol = ( window.popupLocalDebug ? 'http:' : location.protocol );
pg.wiki.articlePath = mw.config.get('wgArticlePath').replace(/\/\$1/, ""); // as in http://some.thing.com/wiki/Article
pg.wiki.botInterfacePath = mw.config.get('wgScript');
pg.wiki.APIPath = mw.config.get('wgScriptPath') +"/api.php";
// default mediawiki setting is paths like http://some.thing.com/articlePath/index.php?title=foo
var titletail = pg.wiki.botInterfacePath + '?title=';
//var titletail2 = joinPath([pg.wiki.botInterfacePath, 'wiki.phtml?title=']);
// other sites may need to add code here to set titletail depending on how their urls work
pg.wiki.titlebase = protocol + '//' + pg.wiki.sitebase + titletail;
//pg.wiki.titlebase2 = protocol + '//' + joinPath([pg.wiki.sitebase, titletail2]);
pg.wiki.wikibase = protocol + '//' + pg.wiki.sitebase + pg.wiki.botInterfacePath;
pg.wiki.apiwikibase = protocol + '//' + pg.wiki.sitebase + pg.wiki.APIPath;
pg.wiki.articlebase = protocol + '//' + pg.wiki.sitebase + pg.wiki.articlePath;
pg.wiki.commonsbase = protocol + '//' + pg.wiki.commons + pg.wiki.botInterfacePath;
pg.wiki.apicommonsbase = protocol + '//' + pg.wiki.commons + pg.wiki.APIPath;
pg.re.basenames = RegExp( '^(' +
map( literalizeRegex, [ pg.wiki.titlebase, //pg.wiki.titlebase2,
pg.wiki.articlebase ]).join('|') + ')' );
}
//////////////////////////////////////////////////
// Global regexps
function setMainRegex() {
var reStart='[^:]*://';
var preTitles = literalizeRegex( mw.config.get('wgScriptPath') ) + '/(?:index[.]php|wiki[.]phtml)[?]title=';
preTitles += '|' + literalizeRegex( pg.wiki.articlePath + '/' );
var reEnd='(' + preTitles + ')([^&?#]*)[^#]*(?:#(.+))?';
pg.re.main = RegExp(reStart + literalizeRegex(pg.wiki.sitebase) + reEnd);
}
function setRegexps() {
// TODO: We shoud use an api call to get the aliases for special pages, now it does not work for non-English wikipedias:
// E.g., https://ru.wikipedia.org/w/api.php?action=query&meta=siteinfo&siprop=specialpagealiases&formatversion=2
setMainRegex();
var sp=nsRe(pg.nsSpecialId);
pg.re.urlNoPopup=RegExp('((title=|/)' + sp + '(?:%3A|:)|section=[0-9]|^#$)') ;
pg.re.contribs =RegExp('(title=|/)' + sp + '(?:%3A|:)Contributions' + '(&target=|/|/' + nsRe(pg.nsUserId)+':)(.*)') ;
pg.re.email =RegExp('(title=|/)' + sp + '(?:%3A|:)EmailUser' + '(&target=|/|/(?:' + nsRe(pg.nsUserId)+':)?)(.*)') ;
pg.re.backlinks =RegExp('(title=|/)' + sp + '(?:%3A|:)WhatLinksHere' + '(&target=|/)([^&]*)');
pg.re.specialdiff=RegExp('/' + sp + '(?:%3A|:)Diff/([^?#]*)');
//<NOLITE>
var im=nsReImage();
// note: tries to get images in infobox templates too, e.g. movie pages, album pages etc
// (^|\[\[)image: *([^|\]]*[^|\] ]) *
// (^|\[\[)image: *([^|\]]*[^|\] ])([^0-9\]]*([0-9]+) *px)?
// $4 = 120 as in 120px
pg.re.image = RegExp('(^|\\[\\[)' + im + ': *([^|\\]]*[^|\\] ])' +
'([^0-9\\]]*([0-9]+) *px)?|(?:\\n *[|]?|[|]) *' +
'(' + getValueOf('popupImageVarsRegexp') + ')' +
' *= *(?:\\[\\[ *)?(?:' + im + ':)?' +
'([^|]*?)(?:\\]\\])? *[|]? *\\n', 'img') ;
pg.re.imageBracketCount = 6;
pg.re.category = RegExp('\\[\\[' +nsRe(pg.nsCategoryId) +
': *([^|\\]]*[^|\\] ]) *', 'i');
pg.re.categoryBracketCount = 1;
pg.re.ipUser=RegExp('^' +
// IPv6
'(?::(?::|(?::[0-9A-Fa-f]{1,4}){1,7})|[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,6}::|[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){7})' +
// IPv4
'|(((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}' +
'(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]))$');
pg.re.stub= RegExp(getValueOf('popupStubRegexp'), 'im');
pg.re.disambig=RegExp(getValueOf('popupDabRegexp'), 'im');
//</NOLITE>
// FIXME replace with general parameter parsing function, this is daft
pg.re.oldid=RegExp('[?&]oldid=([^&]*)');
pg.re.diff=RegExp('[?&]diff=([^&]*)');
}
//////////////////////////////////////////////////
// miscellany
function setupCache() {
// page caching
pg.cache.pages = [];
}
function setMisc() {
pg.current.link=null;
pg.current.links=[];
pg.current.linksHash={};
setupCache();
pg.timer.checkPopupPosition=null;
pg.counter.loop=0;
// ids change with each popup: popupImage0, popupImage1 etc
pg.idNumber=0;
// for myDecodeURI
pg.misc.decodeExtras = [
{from: '%2C', to: ',' },
{from: '_', to: ' ' },
{from: '%24', to: '$'},
{from: '%26', to: '&' } // no ,
];
pg.misc.userAgent = 'Navigation popups/1.0 (' + mw.config.get( 'wgServerName' ) +')';
}
// We need a callback since this might end up asynchronous because of
// the mw.loader.using() call.
function setupPopups( callback ) {
if ( setupPopups.completed ) {
if ( typeof callback === 'function' ) {
callback();
}
return;
}
// These dependencies are also enforced from the gadget,
// but not everyone loads this as a gadget, so double check
mw.loader.using( ['mediawiki.util', 'mediawiki.user', 'user.options'] ).then( function() {
// NB translatable strings should be set up first (strings.js)
// basics
setupDebugging();
setSiteInfo();
setTitleBase();
setOptions(); // see options.js
setUserInfo();
// namespaces etc
setNamespaces();
setInterwiki();
// regexps
setRegexps();
setRedirs();
// other stuff
setMisc();
setupLivePreview();
// main deal here
setupTooltips();
log('In setupPopups(), just called setupTooltips()');
Navpopup.tracker.enable();
setupPopups.completed = true;
if ( typeof callback === 'function' ) {
callback();
}
});
}
// ENDFILE: init.js
// STARTFILE: navlinks.js
//<NOLITE>
//////////////////////////////////////////////////
// navlinks... let the fun begin
//
function defaultNavlinkSpec() {
var str='';
str += '<b><<mainlink|shortcut= >></b>';
if (getValueOf('popupLastEditLink')) {
str += '*<<lastEdit|shortcut=/>>|<<lastContrib>>|<<sinceMe>>if(oldid){|<<oldEdit>>|<<diffCur>>}';
}
// user links
// contribs - log - count - email - block
// count only if applicable; block only if popupAdminLinks
str += 'if(user){<br><<contribs|shortcut=c>>*<<userlog|shortcut=L|log>>';
str+='if(ipuser){*<<arin>>}if(wikimedia){*<<count|shortcut=#>>}';
str+='if(ipuser){}else{*<<email|shortcut=E>>}if(admin){*<<block|shortcut=b>>|<<blocklog|log>>}}';
// editing links
// talkpage -> edit|new - history - un|watch - article|edit
// other page -> edit - history - un|watch - talk|edit|new
var editstr='<<edit|shortcut=e>>';
var editOldidStr='if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' + editstr + '}';
var historystr='<<history|shortcut=h>>|<<editors|shortcut=E|>>';
var watchstr='<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
str+='<br>if(talk){' +
editOldidStr+'|<<new|shortcut=+>>' + '*' + historystr+'*'+watchstr + '*' +
'<b><<article|shortcut=a>></b>|<<editArticle|edit>>' +
'}else{' + // not a talk page
editOldidStr + '*' + historystr + '*' + watchstr + '*' +
'<b><<talk|shortcut=t>></b>|<<editTalk|edit>>|<<newTalk|shortcut=+|new>>}';
// misc links
str += '<br><<whatLinksHere|shortcut=l>>*<<relatedChanges|shortcut=r>>*<<move|shortcut=m>>';
// admin links
str += 'if(admin){<br><<unprotect|unprotectShort>>|<<protect|shortcut=p>>|<<protectlog|log>>*' +
'<<undelete|undeleteShort>>|<<delete|shortcut=d>>|<<deletelog|log>>}';
return str;
}
function navLinksHTML (article, hint, params) { //oldid, rcid) {
var str = '<span class="popupNavLinks">' + defaultNavlinkSpec() + '</span>';
// BAM
return navlinkStringToHTML(str, article, params);
}
function expandConditionalNavlinkString(s,article,z,recursionCount) {
var oldid=z.oldid, rcid=z.rcid, diff=z.diff;
// nested conditionals (up to 10 deep) are ok, hopefully! (work from the inside out)
if (typeof recursionCount!=typeof 0) { recursionCount=0; }
var conditionalSplitRegex=RegExp(
//(1 if \\( (2 2) \\) {(3 3)} (4 else {(5 5)} 4)1)
'(;?\\s*if\\s*\\(\\s*([\\w]*)\\s*\\)\\s*\\{([^{}]*)\\}(\\s*else\\s*\\{([^{}]*?)\\}|))', 'i');
var splitted=s.parenSplit(conditionalSplitRegex);
// $1: whole conditional
// $2: test condition
// $3: true expansion
// $4: else clause (possibly empty)
// $5: false expansion (possibly null)
var numParens=5;
var ret = splitted[0];
for (var i=1; i<splitted.length; i=i+numParens+1) {
var testString=splitted[i+2-1];
var trueString=splitted[i+3-1];
var falseString=splitted[i+5-1];
if (typeof falseString=='undefined' || !falseString) { falseString=''; }
var testResult=null;
switch (testString) {
case 'user':
testResult=(article.userName())?true:false;
break;
case 'talk':
testResult=(article.talkPage())?false:true; // talkPage converts _articles_ to talkPages
break;
case 'admin':
testResult=getValueOf('popupAdminLinks')?true:false;
break;
case 'oldid':
testResult=(typeof oldid != 'undefined' && oldid)?true:false;
break;
case 'rcid':
testResult=(typeof rcid != 'undefined' && rcid)?true:false;
break;
case 'ipuser':
testResult=(article.isIpUser())?true:false;
break;
case 'mainspace_en':
testResult=isInMainNamespace(article) &&
pg.wiki.hostname=='en.wikipedia.org';
break;
case 'wikimedia':
testResult=(pg.wiki.wikimedia) ? true : false;
break;
case 'diff':
testResult=(typeof diff != 'undefined' && diff)?true:false;
break;
}
switch(testResult) {
case null: ret+=splitted[i]; break;
case true: ret+=trueString; break;
case false: ret+=falseString; break;
}
// append non-conditional string
ret += splitted[i+numParens];
}
if (conditionalSplitRegex.test(ret) && recursionCount < 10) {
return expandConditionalNavlinkString(ret,article,z,recursionCount+1);
}
return ret;
}
function navlinkStringToArray(s, article, params) {
s=expandConditionalNavlinkString(s,article,params);
var splitted=s.parenSplit(RegExp('<<(.*?)>>'));
var ret=[];
for (var i=0; i<splitted.length; ++i) {
if (i%2) { // i odd, so s is a tag
var t=new navlinkTag();
var ss=splitted[i].split('|');
t.id=ss[0];
for (var j=1; j<ss.length; ++j) {
var sss=ss[j].split('=');
if (sss.length>1) {
t[sss[0]]=sss[1];
}
else { // no assignment (no "="), so treat this as a title (overwriting the last one)
t.text=popupString(sss[0]);
}
}
t.article=article;
var oldid=params.oldid, rcid=params.rcid, diff=params.diff;
if (typeof oldid !== 'undefined' && oldid !== null) { t.oldid=oldid; }
if (typeof rcid !== 'undefined' && rcid !== null) { t.rcid=rcid; }
if (typeof diff !== 'undefined' && diff !== null) { t.diff=diff; }
if (!t.text && t.id !== 'mainlink') { t.text=popupString(t.id); }
ret.push(t);
}
else { // plain HTML
ret.push(splitted[i]);
}
}
return ret;
}
function navlinkSubstituteHTML(s) {
return s.split('*').join(getValueOf('popupNavLinkSeparator'))
.split('<menurow>').join('<li class="popup_menu_row">')
.split('</menurow>').join('</li>')
.split('<menu>').join('<ul class="popup_menu">')
.split('</menu>').join('</ul>');
}
function navlinkDepth(magic,s) {
return s.split('<' + magic + '>').length - s.split('</' + magic + '>').length;
}
// navlinkString: * becomes the separator
// <<foo|bar=baz|fubar>> becomes a foo-link with attribute bar='baz'
// and visible text 'fubar'
// if(test){...} and if(test){...}else{...} work too (nested ok)
function navlinkStringToHTML(s,article,params) {
//limitAlert(navlinkStringToHTML, 5, 'navlinkStringToHTML\n' + article + '\n' + (typeof article));
var p=navlinkStringToArray(s,article,params);
var html='';
var menudepth = 0; // nested menus not currently allowed, but doesn't do any harm to code for it
var menurowdepth = 0;
for (var i=0; i<p.length; ++i) {
if (typeof p[i] == typeof '') {
html+=navlinkSubstituteHTML(p[i]);
menudepth += navlinkDepth('menu', p[i]);
menurowdepth += navlinkDepth('menurow', p[i]);
// if (menudepth === 0) {
// tagType='span';
// } else if (menurowdepth === 0) {
// tagType='li';
// } else {
// tagType = null;
// }
} else if (typeof p[i].type != 'undefined' && p[i].type=='navlinkTag') {
if (menudepth > 0 && menurowdepth === 0) {
html += '<li class="popup_menu_item">' + p[i].html() + '</li>';
} else {
html+=p[i].html();
}
}
}
return html;
}
function navlinkTag() {
this.type='navlinkTag';
}
navlinkTag.prototype.html=function () {
this.getNewWin();
this.getPrintFunction();
var html='';
var opening, closing;
var tagType='span';
if (!tagType) {
opening = ''; closing = '';
} else {
opening = '<' + tagType + ' class="popup_' + this.id + '">';
closing = '</' + tagType + '>';
}
if (typeof this.print!='function') {
errlog ('Oh dear - invalid print function for a navlinkTag, id='+this.id);
} else {
html=this.print(this);
if (typeof html != typeof '') {html='';}
else if (typeof this.shortcut!='undefined') html=addPopupShortcut(html, this.shortcut);
}
return opening + html + closing;
};
navlinkTag.prototype.getNewWin=function() {
getValueOf('popupLinksNewWindow');
if (typeof pg.option.popupLinksNewWindow[this.id] === 'undefined') { this.newWin=null; }
this.newWin=pg.option.popupLinksNewWindow[this.id];
};
navlinkTag.prototype.getPrintFunction=function() { //think about this some more
// this.id and this.article should already be defined
if (typeof this.id!=typeof '' || typeof this.article!=typeof {} ) { return; }
this.noPopup=1;
switch (this.id) {
case 'contribs': case 'history': case 'whatLinksHere':
case 'userPage': case 'monobook': case 'userTalk':
case 'talk': case 'article': case 'lastEdit':
this.noPopup=null;
}
switch (this.id) {
case 'email': case 'contribs': case 'block': case 'unblock':
case 'userlog': case 'userSpace': case 'deletedContribs':
this.article=this.article.userName();
}
switch (this.id) {
case 'userTalk': case 'newUserTalk': case 'editUserTalk':
case 'userPage': case 'monobook': case 'editMonobook': case 'blocklog':
this.article=this.article.userName(true);
/* fall through */
case 'pagelog': case 'deletelog': case 'protectlog':
delete this.oldid;
}
if (this.id=='editMonobook' || this.id=='monobook') { this.article.append('/monobook.js'); }
if (this.id != 'mainlink') {
// FIXME anchor handling should be done differently with Title object
this.article=this.article.removeAnchor();
// if (typeof this.text=='undefined') this.text=popupString(this.id);
}
switch (this.id) {
case 'undelete': this.print=specialLink; this.specialpage='Undelete'; this.sep='/'; break;
case 'whatLinksHere': this.print=specialLink; this.specialpage='Whatlinkshere'; break;
case 'relatedChanges': this.print=specialLink; this.specialpage='Recentchangeslinked'; break;
case 'move': this.print=specialLink; this.specialpage='Movepage'; break;
case 'contribs': this.print=specialLink; this.specialpage='Contributions'; break;
case 'deletedContribs':this.print=specialLink; this.specialpage='Deletedcontributions'; break;
case 'email': this.print=specialLink; this.specialpage='EmailUser'; this.sep='/'; break;
case 'block': this.print=specialLink; this.specialpage='Blockip'; this.sep='&ip='; break;
case 'unblock': this.print=specialLink; this.specialpage='Ipblocklist'; this.sep='&action=unblock&ip='; break;
case 'userlog': this.print=specialLink; this.specialpage='Log'; this.sep='&user='; break;
case 'blocklog': this.print=specialLink; this.specialpage='Log'; this.sep='&type=block&page='; break;
case 'pagelog': this.print=specialLink; this.specialpage='Log'; this.sep='&page='; break;
case 'protectlog': this.print=specialLink; this.specialpage='Log'; this.sep='&type=protect&page='; break;
case 'deletelog': this.print=specialLink; this.specialpage='Log'; this.sep='&type=delete&page='; break;
case 'userSpace': this.print=specialLink; this.specialpage='PrefixIndex'; this.sep='&namespace=2&prefix='; break;
case 'search': this.print=specialLink; this.specialpage='Search'; this.sep='&fulltext=Search&search='; break;
case 'thank': this.print=specialLink; this.specialpage='Thanks'; this.sep='/'; this.article.value = this.diff; break;
case 'unwatch': case 'watch':
this.print=magicWatchLink; this.action=this.id+'&autowatchlist=1&autoimpl=' + popupString('autoedit_version') + '&actoken='+autoClickToken(); break;
case 'history': case 'historyfeed':
case 'unprotect': case 'protect':
this.print=wikiLink; this.action=this.id; break;
case 'delete':
this.print=wikiLink; this.action='delete';
if (this.article.namespaceId()==pg.nsImageId) {
var img=this.article.stripNamespace();
this.action+='&image='+img;
}
break;
case 'markpatrolled':
case 'edit': // editOld should keep the oldid, but edit should not.
delete this.oldid;
/* fall through */
case 'view': case 'purge': case 'render':
this.print=wikiLink;
this.action=this.id; break;
case 'raw':
this.print=wikiLink; this.action='raw'; break;
case 'new':
this.print=wikiLink; this.action='edit§ion=new'; break;
case 'mainlink':
if (typeof this.text=='undefined') { this.text=this.article.toString().entify(); }
if (getValueOf('popupSimplifyMainLink') && isInStrippableNamespace(this.article)) {
// only show the /subpage part of the title text
var s=this.text.split('/'); this.text=s[s.length-1];
if (this.text==='' && s.length > 1) { this.text=s[s.length-2]; }
}
this.print=titledWikiLink;
if (typeof this.title==='undefined' && pg.current.link && typeof pg.current.link.href !== 'undefined') {
this.title=safeDecodeURI((pg.current.link.originalTitle)?pg.current.link.originalTitle:this.article);
if (typeof this.oldid !== 'undefined' && this.oldid) {
this.title=tprintf('Revision %s of %s', [this.oldid, this.title]);
}
}
this.action='view'; break;
case 'userPage':
case 'article':
case 'monobook':
case 'editMonobook':
case 'editArticle':
delete this.oldid;
//alert(this.id+'\n'+this.article + '\n'+ typeof this.article);
this.article=this.article.articleFromTalkOrArticle();
//alert(this.id+'\n'+this.article + '\n'+ typeof this.article);
this.print=wikiLink;
if (this.id.indexOf('edit')===0) {
this.action='edit';
} else { this.action='view';}
break;
case 'userTalk':
case 'talk':
this.article=this.article.talkPage();
delete this.oldid;
this.print=wikiLink;
this.action='view'; break;
case 'arin':
this.print=arinLink; break;
case 'count':
this.print=editCounterLink; break;
case 'google':
this.print=googleLink; break;
case 'editors':
this.print=editorListLink; break;
case 'globalsearch':
this.print=globalSearchLink; break;
case 'lastEdit':
this.print=titledDiffLink;
this.title=popupString('Show the last edit');
this.from='prev'; this.to='cur'; break;
case 'oldEdit':
this.print=titledDiffLink;
this.title=popupString('Show the edit made to get revision') + ' ' + this.oldid;
this.from='prev'; this.to=this.oldid; break;
case 'editOld':
this.print=wikiLink; this.action='edit'; break;
case 'undo':
this.print=wikiLink; this.action='edit&undo='; break;
case 'revert':
this.print=wikiLink; this.action='revert'; break;
case 'nullEdit':
this.print=wikiLink; this.action='nullEdit'; break;
case 'diffCur':
this.print=titledDiffLink;
this.title=tprintf('Show changes since revision %s', [this.oldid]);
this.from=this.oldid; this.to='cur'; break;
case 'editUserTalk':
case 'editTalk':
delete this.oldid;
this.article=this.article.talkPage();
this.action='edit'; this.print=wikiLink; break;
case 'newUserTalk':
case 'newTalk':
this.article=this.article.talkPage();
this.action='edit§ion=new'; this.print=wikiLink; break;
case 'lastContrib':
case 'sinceMe':
this.print=magicHistoryLink;
break;
case 'togglePreviews':
this.text=popupString(pg.option.simplePopups ? 'enable previews' : 'disable previews');
/* fall through */
case 'disablePopups': case 'purgePopups':
this.print=popupMenuLink;
break;
default:
this.print=function () {return 'Unknown navlink type: '+this.id+'';};
}
};
//
// end navlinks
//////////////////////////////////////////////////
//</NOLITE>
// ENDFILE: navlinks.js
// STARTFILE: shortcutkeys.js
//<NOLITE>
function popupHandleKeypress(evt) {
var keyCode = window.event ? window.event.keyCode : ( evt.keyCode ? evt.keyCode : evt.which);
if (!keyCode || !pg.current.link || !pg.current.link.navpopup) { return; }
if (keyCode==27) { // escape
killPopup();
return false; // swallow keypress
}
var letter=String.fromCharCode(keyCode);
var links=pg.current.link.navpopup.mainDiv.getElementsByTagName('A');
var startLink=0;
var i,j;
if (popupHandleKeypress.lastPopupLinkSelected) {
for (i=0; i<links.length; ++i) {
if (links[i]==popupHandleKeypress.lastPopupLinkSelected) { startLink=i; }
}
}
for (j=0; j<links.length; ++j) {
i=(startLink + j + 1) % links.length;
if (links[i].getAttribute('popupkey')==letter) {
if (evt && evt.preventDefault) evt.preventDefault();
links[i].focus();
popupHandleKeypress.lastPopupLinkSelected=links[i];
return false; // swallow keypress
}
}
// pass keypress on
if (document.oldPopupOnkeypress) { return document.oldPopupOnkeypress(evt); }
return true;
}
function addPopupShortcuts() {
if (document.onkeypress!=popupHandleKeypress) {
document.oldPopupOnkeypress=document.onkeypress;
}
document.onkeypress=popupHandleKeypress;
}
function rmPopupShortcuts() {
popupHandleKeypress.lastPopupLinkSelected=null;
try {
if (document.oldPopupOnkeypress && document.oldPopupOnkeypress==popupHandleKeypress) {
// panic
document.onkeypress=null; //function () {};
return;
}
document.onkeypress=document.oldPopupOnkeypress;
} catch (nasties) { /* IE goes here */ }
}
function addLinkProperty(html, property) {
// take "<a href=...>...</a> and add a property
// not sophisticated at all, easily broken
var i=html.indexOf('>');
if (i<0) { return html; }
return html.substring(0,i) + ' ' + property + html.substring(i);
}
function addPopupShortcut(html, key) {
if (!getValueOf('popupShortcutKeys')) { return html; }
var ret= addLinkProperty(html, 'popupkey="'+key+'"');
if (key==' ') { key=popupString('spacebar'); }
return ret.replace(RegExp('^(.*?)(title=")(.*?)(".*)$', 'i'),'$1$2$3 ['+key+']$4');
}
//</NOLITE>
// ENDFILE: shortcutkeys.js
// STARTFILE: diffpreview.js
//<NOLITE>
//lets jump through hoops to find the rev ids we need to retrieve
function loadDiff(article, oldid, diff, navpop) {
navpop.diffData={ oldRev: {}, newRev: {} };
mw.loader.using( 'mediawiki.api' ).then( function() {
var api = new mw.Api( {
ajax: {
headers: { 'Api-User-Agent': pg.misc.userAgent }
}
} );
var params = {
action: 'compare',
prop: 'ids|title'
};
if(article.title){
params.fromtitle = article.title;
}
switch (diff) {
case 'cur':
switch ( oldid ) {
case null:
case '':
case 'prev':
// this can only work if we have the title
// cur -> prev
params.torelative = 'prev';
break;
default:
params.fromrev = oldid;
params.torelative = 'cur';
break;
}
break;
case 'prev':
if( oldid ) {
params.fromrev = oldid;
} else {
params.fromtitle;
}
params.torelative = 'prev';
break;
case 'next':
params.fromrev = oldid || 0;
params.torelative = 'next';
break;
default:
params.fromrev = oldid || 0;
params.torev = diff || 0;
break;
}
api.get( params ).then( function( data ) {
navpop.diffData.oldRev.revid = data.compare.fromrevid;
navpop.diffData.newRev.revid = data.compare.torevid;
addReviewLink(navpop, 'popupMiscTools');
var go = function() {
pendingNavpopTask(navpop);
var url=pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
url += 'revids=' + navpop.diffData.oldRev.revid + '|' + navpop.diffData.newRev.revid;
url += '&prop=revisions&rvprop=ids|timestamp|content';
getPageWithCaching(url, doneDiff, navpop);
return true; // remove hook once run
};
if (navpop.visible || !getValueOf('popupLazyDownloads')) { go(); }
else { navpop.addHook(go, 'unhide', 'before', 'DOWNLOAD_DIFFS'); }
} );
} );
}
// Put a "mark patrolled" link to an element target
// TODO: Allow patrol a revision, as well as a diff
function addReviewLink (navpop, target) {
if (! pg.user.canReview) return;
// If 'newRev' is older than 'oldRev' than it could be confusing, so we do not show the review link.
if (navpop.diffData.newRev.revid <= navpop.diffData.oldRev.revid) return;
var api = new mw.Api( {
ajax: {
headers: { 'Api-User-Agent': pg.misc.userAgent }
}
} );
var params = {
action: 'query',
prop: 'info|flagged',
revids: navpop.diffData.oldRev.revid,
formatversion : 2
};
api.get (params).then(function(data){
var stable_revid = data.query.pages[0].flagged && data.query.pages[0].flagged.stable_revid || 0;
// The diff can be reviewed if the old version is the last reviewed version
// TODO: Other possible conditions that we may want to implement instead of this one:
// * old version is patrolled and the new version is not patrolled
// * old version is patrolled and the new version is more recent than the last reviewed version
if (stable_revid == navpop.diffData.oldRev.revid) {
var a = document.createElement('a');
a.innerHTML = popupString('mark patrolled');
a.title=popupString('markpatrolledHint');
a.onclick = function() {
var params = {
action: 'review',
revid: navpop.diffData.newRev.revid,
comment: tprintf('defaultpopupReviewedSummary', [navpop.diffData.oldRev.revid, navpop.diffData.newRev.revid])
};
api.postWithToken('csrf',params).done(function(){
a.style.display = "none";
// TODO: Update current page and other already constructed popups
} ).fail(function(){
alert(popupString('Could not marked this edit as patrolled'));
});
};
setPopupHTML(a, target, navpop.idNumber,null,true);
}
});
}
function doneDiff(download) {
if (!download.owner || !download.owner.diffData) { return; }
var navpop=download.owner;
completedNavpopTask(navpop);
var pages, revisions=[];
try{
// Process the downloads
pages = getJsObj(download.data).query.pages;
for(var i=0; i < pages.length; i++ ) {
revisions = revisions.concat(pages[i].revisions);
}
for(i=0; i< revisions.length; i++){
if(revisions[i].revid == navpop.diffData.oldRev.revid) {
navpop.diffData.oldRev.revision = revisions[i];
} else if (revisions[i].revid == navpop.diffData.newRev.revid) {
navpop.diffData.newRev.revision = revisions[i];
}
}
} catch(someError) {
errlog( 'Could not get diff' );
}
insertDiff(navpop);
}
function rmBoringLines(a,b,context) {
if (typeof context == 'undefined') { context=2; }
// this is fairly slow... i think it's quicker than doing a word-based diff from the off, though
var aa=[], aaa=[];
var bb=[], bbb=[];
var i, j;
// first, gather all disconnected nodes in a and all crossing nodes in a and b
for (i=0; i<a.length; ++i ) {
if(!a[i].paired) { aa[i]=1; }
else if (countCrossings(b,a,i, true)) {
aa[i]=1;
bb[ a[i].row ] = 1;
}
}
// pick up remaining disconnected nodes in b
for (i=0; i<b.length; ++i ) {
if (bb[i]==1) { continue; }
if(!b[i].paired) { bb[i]=1; }
}
// another pass to gather context: we want the neighbours of included nodes which are not yet included
// we have to add in partners of these nodes, but we don't want to add context for *those* nodes in the next pass
for (i=0; i<b.length; ++i) {
if ( bb[i] == 1 ) {
for (j=Math.max(0,i-context); j < Math.min(b.length, i+context); ++j) {
if ( !bb[j] ) { bb[j] = 1; aa[ b[j].row ] = 0.5; }
}
}
}
for (i=0; i<a.length; ++i) {
if ( aa[i] == 1 ) {
for (j=Math.max(0,i-context); j < Math.min(a.length, i+context); ++j) {
if ( !aa[j] ) { aa[j] = 1; bb[ a[j].row ] = 0.5; }
}
}
}
for (i=0; i<bb.length; ++i) {
if (bb[i] > 0) { // it's a row we need
if (b[i].paired) { bbb.push(b[i].text); } // joined; partner should be in aa
else {
bbb.push(b[i]);
}
}
}
for (i=0; i<aa.length; ++i) {
if (aa[i] > 0) { // it's a row we need
if (a[i].paired) { aaa.push(a[i].text); } // joined; partner should be in aa
else {
aaa.push(a[i]);
}
}
}
return { a: aaa, b: bbb};
}
function stripOuterCommonLines(a,b,context) {
var i=0;
while (i<a.length && i < b.length && a[i]==b[i]) { ++i; }
var j=a.length-1; var k=b.length-1;
while ( j>=0 && k>=0 && a[j]==b[k] ) { --j; --k; }
return { a: a.slice(Math.max(0,i - 1 - context), Math.min(a.length+1, j + context+1)),
b: b.slice(Math.max(0,i - 1 - context), Math.min(b.length+1, k + context+1)) };
}
function insertDiff(navpop) {
// for speed reasons, we first do a line-based diff, discard stuff that seems boring, then do a word-based diff
// FIXME: sometimes this gives misleading diffs as distant chunks are squashed together
var oldlines = navpop.diffData.oldRev.revision.content.split('\n');
var newlines = navpop.diffData.newRev.revision.content.split('\n');
var inner=stripOuterCommonLines(oldlines,newlines,getValueOf('popupDiffContextLines'));
oldlines=inner.a; newlines=inner.b;
var truncated=false;
getValueOf('popupDiffMaxLines');
if (oldlines.length > pg.option.popupDiffMaxLines || newlines.length > pg.option.popupDiffMaxLines) {
// truncate
truncated=true;
inner=stripOuterCommonLines(oldlines.slice(0,pg.option.popupDiffMaxLines),
newlines.slice(0,pg.option.popupDiffMaxLines),
pg.option.popupDiffContextLines);
oldlines=inner.a; newlines=inner.b;
}
var lineDiff=diff(oldlines, newlines);
var lines2=rmBoringLines(lineDiff.o, lineDiff.n);
var oldlines2=lines2.a; var newlines2=lines2.b;
var simpleSplit = !String.prototype.parenSplit.isNative;
var html='<hr />';
if (getValueOf('popupDiffDates')) {
html += diffDatesTable(navpop);
html += '<hr />';
}
html += shortenDiffString(
diffString(oldlines2.join('\n'), newlines2.join('\n'), simpleSplit),
getValueOf('popupDiffContextCharacters') ).join('<hr />');
setPopupTipsAndHTML(html.split('\n').join('<br>') +
(truncated ? '<hr /><b>'+popupString('Diff truncated for performance reasons')+'</b>' : '') ,
'popupPreview', navpop.idNumber);
}
function diffDatesTable( navpop ) {
var html='<table class="popup_diff_dates">';
html += diffDatesTableRow( navpop.diffData.newRev.revision, tprintf('New revision'));
html += diffDatesTableRow( navpop.diffData.oldRev.revision, tprintf('Old revision'));
html += '</table>';
return html;
}
function diffDatesTableRow( revision, label ) {
var txt='';
var lastModifiedDate = new Date(revision.timestamp);
var datePrint=getValueOf('popupDiffDatePrinter');
if (typeof lastModifiedDate[datePrint] == 'function') {
var d2 = adjustDate(lastModifiedDate, getTimeOffset());
txt = dayFormat(d2, true) + ' ' + timeFormat(d2, true);
} else {
txt = tprintf('Invalid %s %s', ['popupDiffDatePrinter', datePrint]);
}
var revlink = generalLink({url: mw.config.get('wgScript') + '?oldid='+revision.revid,
text: label, title: label});
return simplePrintf('<tr><td>%s</td><td>%s</td></tr>', [ revlink, txt ]);
}
//</NOLITE>
// ENDFILE: diffpreview.js
// STARTFILE: links.js
//<NOLITE>
/////////////////////
// LINK GENERATION //
/////////////////////
// titledDiffLink --> titledWikiLink --> generalLink
// wikiLink --> titledWikiLink --> generalLink
// editCounterLink --> generalLink
// TODO Make these functions return Element objects, not just raw HTML strings.
function titledDiffLink(l) { // article, text, title, from, to) {
return titledWikiLink({article: l.article, action: l.to + '&oldid=' + l.from,
newWin: l.newWin,
noPopup: l.noPopup,
text: l.text, title: l.title,
/* hack: no oldid here */
actionName: 'diff'});
}
function wikiLink(l) {
//{article:article, action:action, text:text, oldid, newid}) {
if (! (typeof l.article == typeof {} &&
typeof l.action == typeof '' &&
typeof l.text==typeof '')) return null;
if (typeof l.oldid == 'undefined') { l.oldid=null; }
var savedOldid = l.oldid;
if (!/^(edit|view|revert|render)$|^raw/.test(l.action)) { l.oldid=null; }
var hint=popupString(l.action + 'Hint'); // revertHint etc etc etc
var oldidData=[l.oldid, safeDecodeURI(l.article)];
var revisionString = tprintf('revision %s of %s', oldidData);
log('revisionString='+revisionString);
switch (l.action) {
case 'edit§ion=new': hint = popupString('newSectionHint'); break;
case 'edit&undo=':
if (l.diff && l.diff != 'prev' && savedOldid ) {
l.action += l.diff + '&undoafter=' + savedOldid;
} else if (savedOldid) {
l.action += savedOldid;
}
hint = popupString('undoHint');
break;
case 'raw&ctype=text/css': hint=popupString('rawHint'); break;
case 'revert':
var p=parseParams(pg.current.link.href);
l.action='edit&autoclick=wpSave&actoken=' + autoClickToken() + '&autoimpl=' + popupString('autoedit_version') + '&autosummary=' + revertSummary(l.oldid, p.diff);
if (p.diff=='prev') {
l.action += '&direction=prev';
revisionString = tprintf('the revision prior to revision %s of %s', oldidData);
}
if (getValueOf('popupRevertSummaryPrompt')) { l.action += '&autosummaryprompt=true'; }
if (getValueOf('popupMinorReverts')) { l.action += '&autominor=true'; }
log('revisionString is now '+revisionString);
break;
case 'nullEdit':
l.action='edit&autoclick=wpSave&actoken=' + autoClickToken() + '&autoimpl=' + popupString('autoedit_version') + '&autosummary=null';
break;
case 'historyfeed':
l.action='history&feed=rss';
break;
case 'markpatrolled':
l.action='markpatrolled&rcid='+l.rcid;
}
if (hint) {
if (l.oldid) {
hint = simplePrintf(hint, [revisionString]);
}
else {
hint = simplePrintf(hint, [safeDecodeURI(l.article)]);
}
}
else {
hint = safeDecodeURI(l.article + '&action=' + l.action) + (l.oldid) ? '&oldid='+l.oldid : '';
}
return titledWikiLink({article: l.article, action: l.action, text: l.text, newWin:l.newWin,
title: hint, oldid: l.oldid, noPopup: l.noPopup, onclick: l.onclick});
}
function revertSummary(oldid, diff) {
var ret='';
if (diff == 'prev') {
ret=getValueOf('popupQueriedRevertToPreviousSummary');
} else { ret = getValueOf('popupQueriedRevertSummary'); }
return ret + '&autorv=' + oldid;
}
function titledWikiLink(l) {
// possible properties of argument:
// article, action, text, title, oldid, actionName, className, noPopup
// oldid = null is fine here
// article and action are mandatory args
if (typeof l.article == 'undefined' || typeof l.action=='undefined') {
errlog('got undefined article or action in titledWikiLink');
return null;
}
var base = pg.wiki.titlebase + l.article.urlString();
var url=base;
if (typeof l.actionName=='undefined' || !l.actionName) { l.actionName='action'; }
// no need to add &action=view, and this confuses anchors
if (l.action != 'view') { url = base + '&' + l.actionName + '=' + l.action; }
if (typeof l.oldid!='undefined' && l.oldid) { url+='&oldid='+l.oldid; }
var cssClass=pg.misc.defaultNavlinkClassname;
if (typeof l.className!='undefined' && l.className) { cssClass=l.className; }
return generalNavLink({url: url, newWin: l.newWin,
title: (typeof l.title != 'undefined') ? l.title : null,
text: (typeof l.text!='undefined')?l.text:null,
className: cssClass, noPopup:l.noPopup, onclick:l.onclick});
}
pg.fn.getLastContrib = function getLastContrib(wikipage, newWin) {
getHistoryInfo(wikipage, function(x) {
processLastContribInfo(x, {page: wikipage, newWin: newWin});
});
};
function processLastContribInfo(info, stuff) {
if(!info.edits || !info.edits.length) { alert('Popups: an odd thing happened. Please retry.'); return; }
if(!info.firstNewEditor) {
alert(tprintf('Only found one editor: %s made %s edits', [info.edits[0].editor,info.edits.length]));
return;
}
var newUrl=pg.wiki.titlebase + new Title(stuff.page).urlString() + '&diff=cur&oldid='+info.firstNewEditor.oldid;
displayUrl(newUrl, stuff.newWin);
}
pg.fn.getDiffSinceMyEdit = function getDiffSinceMyEdit(wikipage, newWin) {
getHistoryInfo(wikipage, function(x){
processDiffSinceMyEdit(x, {page: wikipage, newWin: newWin});
});
};
function processDiffSinceMyEdit(info, stuff) {
if(!info.edits || !info.edits.length) { alert('Popups: something fishy happened. Please try again.'); return; }
var friendlyName=stuff.page.split('_').join(' ');
if(!info.myLastEdit) {
alert(tprintf('Couldn\'t find an edit by %s\nin the last %s edits to\n%s',
[info.userName, getValueOf('popupHistoryLimit'), friendlyName]));
return;
}
if(info.myLastEdit.index === 0) {
alert(tprintf("%s seems to be the last editor to the page %s", [info.userName, friendlyName]));
return;
}
var newUrl=pg.wiki.titlebase + new Title(stuff.page).urlString() + '&diff=cur&oldid='+ info.myLastEdit.oldid;
displayUrl(newUrl, stuff.newWin);
}
function displayUrl(url, newWin){
if(newWin) { window.open(url); }
else { document.location=url; }
}
pg.fn.purgePopups = function purgePopups() {
processAllPopups(true);
setupCache(); // deletes all cached items (not browser cached, though...)
pg.option={};
abortAllDownloads();
};
function processAllPopups(nullify, banish) {
for (var i=0; pg.current.links && i<pg.current.links.length; ++i) {
if (!pg.current.links[i].navpopup) { continue; }
if (nullify || banish) pg.current.links[i].navpopup.banish();
pg.current.links[i].simpleNoMore=false;
if (nullify) pg.current.links[i].navpopup=null;
}
}
pg.fn.disablePopups = function disablePopups(){
processAllPopups(false, true);
setupTooltips(null, true);
};
pg.fn.togglePreviews = function togglePreviews() {
processAllPopups(true, true);
pg.option.simplePopups=!pg.option.simplePopups;
abortAllDownloads();
};
function magicWatchLink(l) {
//Yuck!! Would require a thorough redesign to add this as a click event though ...
l.onclick = simplePrintf( 'pg.fn.modifyWatchlist(\'%s\',\'%s\');return false;', [l.article.toString(true).split("\\").join("\\\\").split("'").join("\\'"), this.id] );
return wikiLink(l);
}
pg.fn.modifyWatchlist = function modifyWatchlist(title, action) {
var reqData = {
'action': 'watch',
'formatversion': 2,
'titles': title,
'uselang': mw.config.get('wgUserLanguage')
};
if ( action === 'unwatch' ) reqData.unwatch = true;
var api = new mw.Api( {
ajax: {
headers: { 'Api-User-Agent': pg.misc.userAgent }
}
} );
// Load the Addedwatchtext or Removedwatchtext message and show it
var mwTitle = mw.Title.newFromText( title );
var messageName;
if ( mwTitle && mwTitle.getNamespaceId() > 0 && mwTitle.getNamespaceId() % 2 === 1 ) {
messageName = action === 'watch' ? 'addedwatchtext-talk' : 'removedwatchtext-talk';
} else {
messageName = action === 'watch' ? 'addedwatchtext' : 'removedwatchtext';
}
$.when(
api.postWithToken( 'watch', reqData ),
mw.loader.using( [ 'mediawiki.api', 'mediawiki.jqueryMsg' ] ).then( function () {
return api.loadMessagesIfMissing( [ messageName ] );
} )
).done( function () {
mw.notify( mw.message( messageName, title ).parseDom() );
} );
};
function magicHistoryLink(l) {
// FIXME use onclick change href trick to sort this out instead of window.open
var jsUrl='', title='', onClick='';
switch(l.id) {
case 'lastContrib':
onClick=simplePrintf('pg.fn.getLastContrib(\'%s\',%s)',
[l.article.toString(true).split("\\").join("\\\\").split("'").join("\\'"), l.newWin]);
title=popupString('lastContribHint');
break;
case 'sinceMe':
onClick=simplePrintf('pg.fn.getDiffSinceMyEdit(\'%s\',%s)',
[l.article.toString(true).split("\\").join("\\\\").split("'").join("\\'"), l.newWin]);
title=popupString('sinceMeHint');
break;
}
jsUrl = 'javascript:' + onClick; // jshint ignore:line
onClick += ';return false;';
return generalNavLink({url: jsUrl, newWin: false, // can't have new windows with JS links, I think
title: title, text: l.text, noPopup: l.noPopup, onclick: onClick });
}
function popupMenuLink(l) {
var jsUrl=simplePrintf('javascript:pg.fn.%s()', [l.id]); // jshint ignore:line
var title=popupString(simplePrintf('%sHint', [l.id]));
var onClick=simplePrintf('pg.fn.%s();return false;', [l.id]);
return generalNavLink({url: jsUrl, newWin:false, title:title, text:l.text, noPopup:l.noPopup, onclick: onClick});
}
function specialLink(l) {
// properties: article, specialpage, text, sep
if (typeof l.specialpage=='undefined'||!l.specialpage) return null;
var base = pg.wiki.titlebase + mw.config.get('wgFormattedNamespaces')[pg.nsSpecialId]+':'+l.specialpage;
if (typeof l.sep == 'undefined' || l.sep === null) l.sep='&target=';
var article=l.article.urlString({keepSpaces: l.specialpage=='Search'});
var hint=popupString(l.specialpage+'Hint');
switch (l.specialpage) {
case 'Log':
switch (l.sep) {
case '&user=': hint=popupString('userLogHint'); break;
case '&type=block&page=': hint=popupString('blockLogHint'); break;
case '&page=': hint=popupString('pageLogHint'); break;
case '&type=protect&page=': hint=popupString('protectLogHint'); break;
case '&type=delete&page=': hint=popupString('deleteLogHint'); break;
default: log('Unknown log type, sep=' + l.sep); hint='Missing hint (FIXME)';
}
break;
case 'PrefixIndex': article += '/'; break;
}
if (hint) hint = simplePrintf(hint, [safeDecodeURI(l.article)]);
else hint = safeDecodeURI(l.specialpage+':'+l.article) ;
var url = base + l.sep + article;
return generalNavLink({url: url, title: hint, text: l.text, newWin:l.newWin, noPopup:l.noPopup});
}
function generalLink(l) {
// l.url, l.text, l.title, l.newWin, l.className, l.noPopup, l.onclick
if (typeof l.url=='undefined') return null;
// only quotation marks in the url can screw us up now... I think
var url=l.url.split('"').join('%22');
var ret='<a href="' + url + '"';
if (typeof l.title!='undefined' && l.title) { ret += ' title="' + pg.escapeQuotesHTML(l.title) + '"'; }
if (typeof l.onclick!='undefined' && l.onclick) { ret += ' onclick="' + pg.escapeQuotesHTML(l.onclick) + '"'; }
if (l.noPopup) { ret += ' noPopup=1'; }
var newWin;
if (typeof l.newWin=='undefined' || l.newWin === null) { newWin=getValueOf('popupNewWindows'); }
else { newWin=l.newWin; }
if (newWin) { ret += ' target="_blank"'; }
if (typeof l.className!='undefined'&&l.className) { ret+=' class="'+l.className+'"'; }
ret += '>';
if (typeof l.text==typeof '') { ret+= l.text; }
ret +='</a>';
return ret;
}
function appendParamsToLink(linkstr, params) {
var sp=linkstr.parenSplit(RegExp('(href="[^"]+?)"', 'i'));
if (sp.length<2) return null;
var ret=sp.shift() + sp.shift();
ret += '&' + params + '"';
ret += sp.join('');
return ret;
}
function changeLinkTargetLink(x) { // newTarget, text, hint, summary, clickButton, minor, title (optional), alsoChangeLabel {
if (x.newTarget) {
log ('changeLinkTargetLink: newTarget=' + x.newTarget);
}
if (x.oldTarget !== decodeURIComponent( x.oldTarget ) ) {
log ('This might be an input problem: ' + x.oldTarget );
}
// FIXME: first character of page title as well as namespace should be case insensitive
// eg [[category:X1]] and [[Category:X1]] are equivalent
// this'll break if charAt(0) is nasty
var cA = mw.util.escapeRegExp(x.oldTarget);
var chs = cA.charAt(0).toUpperCase();
chs='['+chs + chs.toLowerCase()+']';
var currentArticleRegexBit=chs+cA.substring(1);
currentArticleRegexBit=currentArticleRegexBit
.split(RegExp('(?:[_ ]+|%20)', 'g')).join('(?:[_ ]+|%20)')
.split('\\(').join('(?:%28|\\()')
.split('\\)').join('(?:%29|\\))'); // why does this need to match encoded strings ? links in the document ?
// leading and trailing space should be ignored, and anchor bits optional:
currentArticleRegexBit = '\\s*(' + currentArticleRegexBit + '(?:#[^\\[\\|]*)?)\\s*';
// e.g. Computer (archaic) -> \s*([Cc]omputer[_ ](?:%2528|\()archaic(?:%2528|\)))\s*
// autoedit=s~\[\[([Cc]ad)\]\]~[[Computer-aided%20design|$1]]~g;s~\[\[([Cc]AD)[|]~[[Computer-aided%20design|~g
var title=x.title || mw.config.get('wgPageName').split('_').join(' ');
var lk=titledWikiLink({article: new Title(title), newWin:x.newWin,
action: 'edit',
text: x.text,
title: x.hint,
className: 'popup_change_title_link'
});
var cmd='';
if (x.newTarget) {
// escape '&' and other nasties
var t = x.newTarget;
var s = mw.util.escapeRegExp(x.newTarget);
if (x.alsoChangeLabel) {
cmd += 's~\\[\\[' + currentArticleRegexBit + '\\]\\]~[[' + t + ']]~g;';
cmd += 's~\\[\\[' + currentArticleRegexBit + '[|]~[[' + t + '|~g;';
cmd += 's~\\[\\[' + s + '\\|' + s + '\\]\\]~[[' + t + ']]~g';
} else {
cmd += 's~\\[\\[' + currentArticleRegexBit + '\\]\\]~[[' + t + '|$1]]~g;';
cmd += 's~\\[\\[' + currentArticleRegexBit + '[|]~[[' + t + '|~g;';
cmd += 's~\\[\\[' + s + '\\|' + s + '\\]\\]~[[' + t + ']]~g';
}
} else {
cmd += 's~\\[\\['+currentArticleRegexBit+'\\]\\]~$1~g;';
cmd += 's~\\[\\['+currentArticleRegexBit+'[|](.*?)\\]\\]~$2~g';
}
// Build query
cmd = 'autoedit=' + encodeURIComponent ( cmd );
cmd += '&autoclick='+ encodeURIComponent( x.clickButton ) + '&actoken=' + encodeURIComponent( autoClickToken() );
cmd += ( x.minor === null ) ? '' : '&autominor='+ encodeURIComponent( x.minor );
cmd += ( x.watch === null ) ? '' : '&autowatch='+ encodeURIComponent( x.watch );
cmd += '&autosummary='+encodeURIComponent(x.summary);
cmd += '&autoimpl='+encodeURIComponent( popupString('autoedit_version') );
return appendParamsToLink(lk, cmd);
}
function redirLink(redirMatch, article) {
// NB redirMatch is in wikiText
var ret='';
if (getValueOf('popupAppendRedirNavLinks') && getValueOf('popupNavLinks')) {
ret += '<hr />';
if (getValueOf('popupFixRedirs') && typeof autoEdit != 'undefined' && autoEdit) {
ret += popupString('Redirects to: (Fix ');
log('redirLink: newTarget=' + redirMatch);
ret += addPopupShortcut(changeLinkTargetLink({
newTarget: redirMatch,
text: popupString('target'),
hint: popupString('Fix this redirect, changing just the link target'),
summary: simplePrintf(getValueOf('popupFixRedirsSummary'),[article.toString(), redirMatch]),
oldTarget: article.toString(),
clickButton: getValueOf('popupRedirAutoClick'),
minor: true,
watch: getValueOf('popupWatchRedirredPages')
}), 'R');
ret += popupString(' or ');
ret += addPopupShortcut(changeLinkTargetLink({
newTarget: redirMatch,
text: popupString('target & label'),
hint: popupString('Fix this redirect, changing the link target and label'),
summary: simplePrintf(getValueOf('popupFixRedirsSummary'),[article.toString(), redirMatch]),
oldTarget: article.toString(),
clickButton: getValueOf('popupRedirAutoClick'),
minor: true,
watch: getValueOf('popupWatchRedirredPages'),
alsoChangeLabel: true
}), 'R');
ret += popupString(')');
}
else ret += popupString('Redirects') + popupString(' to ');
return ret;
}
else return '<br> ' + popupString('Redirects') + popupString(' to ') +
titledWikiLink({article: new Title().fromWikiText(redirMatch), action: 'view', /* FIXME: newWin */
text: safeDecodeURI(redirMatch), title: popupString('Bypass redirect')});
}
function arinLink(l) {
if (!saneLinkCheck(l)) { return null; }
if ( ! l.article.isIpUser() || ! pg.wiki.wikimedia) return null;
var uN=l.article.userName();
return generalNavLink({url:'http://ws.arin.net/cgi-bin/whois.pl?queryinput=' + encodeURIComponent(uN), newWin:l.newWin,
title: tprintf('Look up %s in ARIN whois database', [uN]),
text: l.text, noPopup:1});
}
function toolDbName(cookieStyle) {
var ret = mw.config.get('wgDBname');
if (!cookieStyle) { ret+= '_p'; }
return ret;
}
function saneLinkCheck(l) {
if (typeof l.article != typeof {} || typeof l.text != typeof '') { return false; }
return true;
}
function editCounterLink(l) {
if(!saneLinkCheck(l)) return null;
if (! pg.wiki.wikimedia) return null;
var uN=l.article.userName();
var tool=getValueOf('popupEditCounterTool');
var url;
var defaultToolUrl='//tools.wmflabs.org/supercount/index.php?user=$1&project=$2.$3';
switch(tool) {
case 'custom':
url=simplePrintf(getValueOf('popupEditCounterUrl'), [ encodeURIComponent(uN), toolDbName() ]);
break;
case 'soxred': // no longer available
case 'kate': // no longer available
case 'interiot':// no longer available
/* fall through */
case 'supercount':
default:
var theWiki=pg.wiki.hostname.split('.');
url=simplePrintf(defaultToolUrl, [ encodeURIComponent(uN), theWiki[0], theWiki[1] ]);
}
return generalNavLink({url:url, title: tprintf('editCounterLinkHint', [uN]),
newWin:l.newWin, text: l.text, noPopup:1});
}
function globalSearchLink(l) {
if(!saneLinkCheck(l)) return null;
var base='http://vs.aka-online.de/cgi-bin/globalwpsearch.pl?timeout=120&search=';
var article=l.article.urlString({keepSpaces:true});
return generalNavLink({url:base + article, newWin:l.newWin,
title: tprintf('globalSearchHint', [safeDecodeURI(l.article)]),
text: l.text, noPopup:1});
}
function googleLink(l) {
if(!saneLinkCheck(l)) return null;
var base='https://www.google.com/search?q=';
var article=l.article.urlString({keepSpaces:true});
return generalNavLink({url:base + '%22' + article + '%22', newWin:l.newWin,
title: tprintf('googleSearchHint', [safeDecodeURI(l.article)]),
text: l.text, noPopup:1});
}
function editorListLink(l) {
if(!saneLinkCheck(l)) return null;
var article= l.article.articleFromTalkPage() || l.article;
var url='https://xtools.wmflabs.org/articleinfo/' +
encodeURI( pg.wiki.hostname ) + '/' +
article.urlString() +
'?uselang=' + mw.config.get('wgUserLanguage');
return generalNavLink({url:url,
title: tprintf('editorListHint', [article]),
newWin:l.newWin, text: l.text, noPopup:1});
}
function generalNavLink(l) {
l.className = (l.className === null) ? 'popupNavLink' : l.className;
return generalLink(l);
}
//////////////////////////////////////////////////
// magic history links
//
function getHistoryInfo(wikipage, whatNext) {
log('getHistoryInfo');
getHistory(wikipage, whatNext ? function(d){whatNext(processHistory(d));} : processHistory);
}
// FIXME eliminate pg.idNumber ... how? :-(
function getHistory(wikipage, onComplete) {
log('getHistory');
var url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&prop=revisions&titles=' +
new Title(wikipage).urlString() + '&rvlimit=' + getValueOf('popupHistoryLimit');
log('getHistory: url='+url);
return startDownload(url, pg.idNumber+'history', onComplete);
}
function processHistory(download) {
var jsobj = getJsObj(download.data);
try {
var revisions = anyChild(jsobj.query.pages).revisions;
var edits=[];
for (var i=0; i<revisions.length; ++i) {
edits.push({ oldid: revisions[i].revid, editor: revisions[i].user });
}
log('processed ' + edits.length + ' edits');
return finishProcessHistory( edits, mw.config.get('wgUserName') );
} catch (someError) {
log('Something went wrong with JSON business');
return finishProcessHistory([]);
}
}
function finishProcessHistory(edits, userName) {
var histInfo={};
histInfo.edits=edits;
histInfo.userName=userName;
for (var i=0; i<edits.length; ++i) {
if (typeof histInfo.myLastEdit === 'undefined' && userName && edits[i].editor==userName) {
histInfo.myLastEdit={index: i, oldid: edits[i].oldid, previd: (i === 0 ? null : edits[i-1].oldid)};
}
if (typeof histInfo.firstNewEditor === 'undefined' && edits[i].editor != edits[0].editor) {
histInfo.firstNewEditor={index:i, oldid:edits[i].oldid, previd: (i === 0 ? null : edits[i-1].oldid)};
}
}
//pg.misc.historyInfo=histInfo;
return histInfo;
}
//</NOLITE>
// ENDFILE: links.js
// STARTFILE: options.js
//////////////////////////////////////////////////
// options
// check for existing value, else use default
function defaultize(x) {
if (pg.option[x]===null || typeof pg.option[x]=='undefined') {
if (typeof window[x] != 'undefined' ) pg.option[x]=window[x];
else pg.option[x]=pg.optionDefault[x];
}
}
function newOption(x, def) {
pg.optionDefault[x]=def;
}
function setDefault(x, def) {
return newOption(x, def);
}
function getValueOf(varName) {
defaultize(varName);
return pg.option[varName];
}
/*eslint-disable */
function useDefaultOptions() { // for testing
for (var p in pg.optionDefault) {
pg.option[p]=pg.optionDefault[p];
if (typeof window[p]!='undefined') { delete window[p]; }
}
}
/*eslint-enable */
function setOptions() {
// user-settable parameters and defaults
var userIsSysop = false;
if ( mw.config.get('wgUserGroups') ) {
for ( var g = 0; g < mw.config.get('wgUserGroups').length; ++g ) {
if ( mw.config.get('wgUserGroups')[g] == "sysop" )
userIsSysop = true;
}
}
// Basic options
newOption('popupDelay', 0.5);
newOption('popupHideDelay', 0.5);
newOption('simplePopups', false);
newOption('popupStructure', 'shortmenus'); // see later - default for popupStructure is 'original' if simplePopups is true
newOption('popupActionsMenu', true);
newOption('popupSetupMenu', true);
newOption('popupAdminLinks', userIsSysop);
newOption('popupShortcutKeys', false);
newOption('popupHistoricalLinks', true);
newOption('popupOnlyArticleLinks', true);
newOption('removeTitles', true);
newOption('popupMaxWidth', 350);
newOption('popupSimplifyMainLink', true);
newOption('popupAppendRedirNavLinks', true);
newOption('popupTocLinks', false);
newOption('popupSubpopups', true);
newOption('popupDragHandle', false /* 'popupTopLinks'*/);
newOption('popupLazyPreviews', true);
newOption('popupLazyDownloads', true);
newOption('popupAllDabsStubs', false);
newOption('popupDebugging', false);
newOption('popupActiveNavlinks', true);
newOption('popupModifier', false); // ctrl, shift, alt or meta
newOption('popupModifierAction', 'enable'); // or 'disable'
newOption('popupDraggable', true);
newOption('popupReview', false);
//<NOLITE>
// images
newOption('popupImages', true);
newOption('imagePopupsForImages', true);
newOption('popupNeverGetThumbs', false);
//newOption('popupImagesToggleSize', true);
newOption('popupThumbAction', 'imagepage'); //'sizetoggle');
newOption('popupImageSize', 60);
newOption('popupImageSizeLarge', 200);
// redirs, dabs, reversion
newOption('popupFixRedirs', false);
newOption('popupRedirAutoClick', 'wpDiff');
newOption('popupFixDabs', false);
newOption('popupDabsAutoClick', 'wpDiff');
newOption('popupRevertSummaryPrompt', false);
newOption('popupMinorReverts', false);
newOption('popupRedlinkRemoval', false);
newOption('popupRedlinkAutoClick', 'wpDiff');
newOption('popupWatchDisambiggedPages', null);
newOption('popupWatchRedirredPages', null);
newOption('popupDabWiktionary', 'last');
// navlinks
newOption('popupNavLinks', true);
newOption('popupNavLinkSeparator', ' ⋅ ');
newOption('popupLastEditLink', true);
newOption('popupEditCounterTool', 'supercount');
newOption('popupEditCounterUrl', '');
//</NOLITE>
// previews etc
newOption('popupPreviews', true);
newOption('popupSummaryData', true);
newOption('popupMaxPreviewSentences', 9);
newOption('popupMaxPreviewCharacters', 900);
newOption('popupLastModified', true);
newOption('popupPreviewKillTemplates', true);
newOption('popupPreviewRawTemplates', true);
newOption('popupPreviewFirstParOnly', false);
newOption('popupPreviewCutHeadings', false);
newOption('popupPreviewButton', false);
newOption('popupPreviewButtonEvent', 'click');
//<NOLITE>
// diffs
newOption('popupPreviewDiffs', true);
newOption('popupDiffMaxLines', 100);
newOption('popupDiffContextLines', 2);
newOption('popupDiffContextCharacters', 40);
newOption('popupDiffDates', true);
newOption('popupDiffDatePrinter', 'toLocaleString');
// edit summaries. God, these are ugly.
newOption('popupReviewedSummary', popupString('defaultpopupReviewedSummary') );
newOption('popupFixDabsSummary', popupString('defaultpopupFixDabsSummary') );
newOption('popupExtendedRevertSummary', popupString('defaultpopupExtendedRevertSummary') );
newOption('popupRevertSummary', popupString('defaultpopupRevertSummary') );
newOption('popupRevertToPreviousSummary', popupString('defaultpopupRevertToPreviousSummary') );
newOption('popupQueriedRevertSummary', popupString('defaultpopupQueriedRevertSummary') );
newOption('popupQueriedRevertToPreviousSummary', popupString('defaultpopupQueriedRevertToPreviousSummary') );
newOption('popupFixRedirsSummary', popupString('defaultpopupFixRedirsSummary') );
newOption('popupRedlinkSummary', popupString('defaultpopupRedlinkSummary') );
newOption('popupRmDabLinkSummary', popupString('defaultpopupRmDabLinkSummary') );
//</NOLITE>
// misc
newOption('popupHistoryLimit', 50);
//<NOLITE>
newOption('popupFilters', [popupFilterStubDetect, popupFilterDisambigDetect,
popupFilterPageSize, popupFilterCountLinks,
popupFilterCountImages, popupFilterCountCategories,
popupFilterLastModified]);
newOption('extraPopupFilters', []);
newOption('popupOnEditSelection', 'cursor');
newOption('popupPreviewHistory', true);
newOption('popupImageLinks', true);
newOption('popupCategoryMembers', true);
newOption('popupUserInfo', true);
newOption('popupHistoryPreviewLimit', 25);
newOption('popupContribsPreviewLimit',25);
newOption('popupRevDelUrl', '//en.wikipedia.org/wiki/Wikipedia:Revision_deletion');
newOption('popupShowGender', true);
//</NOLITE>
// new windows
newOption('popupNewWindows', false);
newOption('popupLinksNewWindow', {'lastContrib': true, 'sinceMe': true});
// regexps
newOption('popupDabRegexp', '(\\{\\{\\s*disambig(?!uation needed)|disambig(uation|)\\s*\\}\\}|disamb\\s*\\}\\}|dab\\s*\\}\\})|\\{\\{\\s*(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index)(\\s*[|][^}]*)?\\s*[}][}]|is a .*disambiguation.*page');
newOption('popupAnchorRegexp', 'anchors?'); //how to identify an anchors template
newOption('popupStubRegexp', '(sect)?stub[}][}]|This .*-related article is a .*stub');
newOption('popupImageVarsRegexp', 'image|image_(?:file|skyline|name|flag|seal)|cover|badge|logo');
}
// ENDFILE: options.js
// STARTFILE: strings.js
//<NOLITE>
//////////////////////////////////////////////////
// Translatable strings
//////////////////////////////////////////////////
//
// See instructions at
// https://en.wikipedia.org/wiki/Wikipedia:Tools/Navigation_popups/Translation
pg.string = {
/////////////////////////////////////
// summary data, searching etc.
/////////////////////////////////////
'article': 'bài viết',
'category': 'thể loại',
'categories': 'thể loại',
'image': 'image',
'images': 'tập tin',
'stub': 'stub',
'section stub': 'section stub',
'Empty page': 'Trang trống',
'kB': 'kB',
'bytes': 'byte',
'day': 'ngày',
'days': 'ngày',
'hour': 'giờ',
'hours': 'giờ',
'minute': 'minute',
'minutes': 'minutes',
'second': 'second',
'seconds': 'seconds',
'week': 'tuần',
'weeks': 'weeks',
'search': 'search',
'SearchHint': 'Find English Wikipedia articles containing %s',
'web': 'web',
'global': 'global',
'globalSearchHint': 'Search across Wikipedias in different languages for %s',
'googleSearchHint': 'Google for %s',
/////////////////////////////////////
// article-related actions and info
// (some actions also apply to user pages)
/////////////////////////////////////
'tác vụ': 'tác vụ', ///// view articles and view talk
'popupsMenu': 'popups',
'togglePreviewsHint': 'Toggle preview generation in popups on this page',
'enable previews': 'enable previews',
'disable previews': 'disable previews',
'toggle previews': 'toggle previews',
'show preview': 'show preview',
'reset': 'tái tạo',
'more...': 'more...',
'disable': 'tắt popup',
'disablePopupsHint': 'Disable popups on this page. Reload page to re-enable.',
'historyfeedHint': 'RSS feed of recent changes to this page',
'purgePopupsHint': 'Reset popups, clearing all cached popup data.',
'PopupsHint': 'Reset popups, clearing all cached popup data.',
'spacebar': 'space',
'view': 'view',
'view article': 'xem bài viết',
'viewHint': 'Go to %s',
'talk': 'talk',
'talk page': 'trang thảo luận',
'this revision': 'this revision',
'revision %s of %s': 'revision %s of %s',
'Revision %s of %s': 'Revision %s of %s',
'the revision prior to revision %s of %s': 'the revision prior to revision %s of %s',
'Toggle image size': 'Click to toggle image size',
'del': 'del', ///// delete, protect, move
'delete': 'xóa',
'deleteHint': 'xóa %s',
'undeleteShort': 'un',
'UndeleteHint': 'Show the deletion history for %s',
'protect': 'protect',
'protectHint': 'Restrict editing rights to %s',
'unprotectShort': 'un',
'unprotectHint': 'Allow %s to be edited by anyone again',
'send thanks': 'send thanks',
'ThanksHint': 'Send a thank you notification to this user',
'move': 'di chuyển',
'move page': 'di chuyển trang',
'MovepageHint': 'Change the title of %s',
'sửa': 'sửa', ///// edit articles and talk
'edit article': 'sửa đổi',
'editHint': 'Change the content of %s',
'edit talk': 'edit talk',
'new': 'mới',
'new topic': 'chủ đề mới',
'newSectionHint': 'Start a new section on %s',
'null edit': 'null edit',
'nullEditHint': 'Submit an edit to %s, making no changes ',
'hist': 'hist', ///// history, diffs, editors, related
'history': 'lịch sử',
'historyHint': 'List the changes made to %s',
'last': 'prev', // For labelling the previous revision in history pages; the key is "last" for backwards compatibility
'lastEdit': 'lastEdit',
'mark patrolled': 'đánh dấu tuần tra',
'markpatrolledHint': 'Mark this edit as patrolled',
'Could not marked this edit as patrolled': 'Could not marked this edit as patrolled',
'show last edit': 'lần sửa đổi gần nhất',
'Show the last edit': 'Show the effects of the most recent change',
'lastContrib': 'lastContrib',
'last set of edits': 'latest edits',
'lastContribHint': 'Show the net effect of changes made by the last editor',
'cur': 'cur',
'diffCur': 'diffCur',
'Show changes since revision %s': 'Show changes since revision %s',
'%s old': '%s old', // as in 4 weeks old
'oldEdit': 'oldEdit',
'purge': 'purge',
'purgeHint': 'Demand a fresh copy of %s',
'raw': 'source',
'rawHint': 'Download the source of %s',
'render': 'simple',
'renderHint': 'Show a plain HTML version of %s',
'Show the edit made to get revision': 'Show the edit made to get revision',
'sinceMe': 'sinceMe',
'changes since mine': 'diff my edit',
'sinceMeHint': 'Show changes since my last edit',
'Couldn\'t find an edit by %s\nin the last %s edits to\n%s': 'Couldn\'t find an edit by %s\nin the last %s edits to\n%s',
'eds': 'eds',
'editors': 'editors',
'editorListHint': 'List the users who have edited %s',
'related': 'related',
'relatedChanges': 'relatedChanges',
'related changes': 'related changes',
'RecentchangeslinkedHint': 'Show changes in articles related to %s',
'editOld': 'editOld', ///// edit old version, or revert
'rv': 'rv',
'revert': 'revert',
'revertHint': 'Revert to %s',
'defaultpopupReviewedSummary': 'Accepted by reviewing the [[Special:diff/%s/%s|difference]] between this version and previously accepted version using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupRedlinkSummary': 'Removing link to empty page [[%s]] using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupFixDabsSummary': 'Disambiguate [[%s]] to [[%s]] using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupFixRedirsSummary': 'Redirect bypass from [[%s]] to [[%s]] using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupExtendedRevertSummary': 'Revert to revision dated %s by %s, oldid %s using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupRevertToPreviousSummary': 'Revert to the revision prior to revision %s using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupRevertSummary': 'Revert to revision %s using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupQueriedRevertToPreviousSummary': 'Revert to the revision prior to revision $1 dated $2 by $3 using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupQueriedRevertSummary': 'Revert to revision $1 dated $2 by $3 using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'defaultpopupRmDabLinkSummary': 'Remove link to dab page [[%s]] using [[:en:Wikipedia:Tools/Navigation_popups|popups]]',
'Redirects': 'Redirects', // as in Redirects to ...
' to ': ' to ', // as in Redirects to ...
'Bypass redirect': 'Bypass redirect',
'Fix this redirect': 'Fix this redirect',
'disambig': 'disambig', ///// add or remove dab etc.
'disambigHint': 'Disambiguate this link to [[%s]]',
'Click to disambiguate this link to:': 'Click to disambiguate this link to:',
'remove this link': 'remove this link',
'remove all links to this page from this article': 'remove all links to this page from this article',
'remove all links to this disambig page from this article': 'remove all links to this disambig page from this article',
'mainlink': 'mainlink', ///// links, watch, unwatch
'wikiLink': 'wikiLink',
'wikiLinks': 'liên kết wiki',
'links here': 'links here',
'whatLinksHere': 'whatLinksHere',
'what links here': 'what links here',
'WhatlinkshereHint': 'List the pages that are hyperlinked to %s',
'unwatchShort': 'un',
'watchThingy': 'xem', // called watchThingy because {}.watch is a function
'watchHint': 'Thêm %s vào danh sách theo dõi',
'unwatchHint': 'Remove %s from my watchlist',
'Only found one editor: %s made %s edits': 'Only found one editor: %s made %s edits',
'%s seems to be the last editor to the page %s': '%s seems to be the last editor to the page %s',
'rss': 'rss',
/////////////////////////////////////
// diff previews
/////////////////////////////////////
'Diff truncated for performance reasons': 'Diff truncated for performance reasons',
'Old revision': 'Old revision',
'New revision': 'New revision',
'Something went wrong :-(': 'Something went wrong :-(',
'Empty revision, maybe non-existent': 'Empty revision, maybe non-existent',
'Unknown date': 'Unknown date',
/////////////////////////////////////
// other special previews
/////////////////////////////////////
'Empty category': 'Thể loại trống',
'Category members (%s shown)': 'Category members (%s shown)',
'No image links found': 'No image links found',
'File links': 'File links',
'No image found': 'No image found',
'Image from Commons': 'Image from Commons',
'Description page': 'Description page',
'Alt text:': 'Alt text:',
'revdel':'Hidden revision',
/////////////////////////////////////
// user-related actions and info
/////////////////////////////////////
'user': 'user', ///// user page, talk, email, space
'user page': 'user page',
'user talk': 'user talk',
'edit user talk': 'edit user talk',
'leave comment': 'leave comment',
'email': 'email',
'email user': 'email cho thành viên',
'EmailuserHint': 'Send an email to %s',
'space': 'space', // short form for userSpace link
'PrefixIndexHint': 'Show pages in the userspace of %s',
'count': 'count', ///// contributions, log
'edit counter': 'đếm sửa đổi',
'editCounterLinkHint': 'Count the contributions made by %s',
'contribs': 'đóng góp',
'contributions': 'đóng góp',
'deletedContribs': 'đóng góp bị xóa',
'DeletedcontributionsHint': 'List deleted edits made by %s',
'ContributionsHint': 'List the contributions made by %s',
'log': 'nhật trình',
'user log': 'user log',
'userLogHint': 'Show %s\'s user log',
'arin': 'ARIN lookup', ///// ARIN lookup, block user or IP
'Look up %s in ARIN whois database': 'Look up %s in the ARIN whois database',
'unblockShort': 'un',
'block': 'cấm',
'block user': 'cấm thành viên',
'IpblocklistHint': 'Unblock %s',
'BlockipHint': 'Prevent %s from editing',
'block log': 'nhật trình cấm',
'blockLogHint': 'Show the block log for %s',
'protectLogHint': 'Show the protection log for %s',
'pageLogHint': 'Show the page log for %s',
'deleteLogHint': 'Show the deletion log for %s',
'Invalid %s %s': 'The option %s is invalid: %s',
'No backlinks found': 'No backlinks found',
' and more': ' and more',
'undo': 'undo',
'undoHint': 'undo this edit',
'Download preview data': 'Download preview data',
'Invalid or IP user': 'Invalid or IP user',
'Not a registered username': 'Not a registered username',
'CẤM': 'CẤM',
'Has blocks': 'Cấm một phần',
' sửa đổi từ: ': ' sửa đổi từ: ',
'sửa đổi lần cuối vào ': 'sửa đổi lần cuối vào ',
/////////////////////////////////////
// Autoediting
/////////////////////////////////////
'Enter a non-empty edit summary or press cancel to abort': 'Enter a non-empty edit summary or press cancel to abort',
'Failed to get revision information, please edit manually.\n\n': 'Failed to get revision information, please edit manually.\n\n',
'The %s button has been automatically clicked. Please wait for the next page to load.': 'The %s button has been automatically clicked. Please wait for the next page to load.',
'Could not find button %s. Please check the settings in your javascript file.': 'Could not find button %s. Please check the settings in your javascript file.',
/////////////////////////////////////
// Popups setup
/////////////////////////////////////
'Open full-size image': 'Open full-size image',
'zxy': 'zxy',
'autoedit_version': 'np20140416'
};
function popupString(str) {
if (typeof popupStrings != 'undefined' && popupStrings && popupStrings[str]) { return popupStrings[str]; }
if (pg.string[str]) { return pg.string[str]; }
return str;
}
function tprintf(str,subs) {
if (typeof subs != typeof []) { subs = [subs]; }
return simplePrintf(popupString(str), subs);
}
//</NOLITE>
// ENDFILE: strings.js
// STARTFILE: run.js
////////////////////////////////////////////////////////////////////
// Run things
////////////////////////////////////////////////////////////////////
// For some reason popups requires a fully loaded page jQuery.ready(...) causes problems for some.
// The old addOnloadHook did something similar to the below
if (document.readyState=="complete")
autoEdit(); //will setup popups
else
$( window ).on( 'load', autoEdit );
// Support for MediaWiki's live preview, VisualEditor's saves and Echo's flyout.
( function () {
var once = true;
function dynamicContentHandler( $content ) {
// Try to detect the hook fired on initial page load and disregard
// it, we already hook to onload (possibly to different parts of
// page - it's configurable) and running twice might be bad. Ugly…
if ( $content.attr( 'id' ) == 'mw-content-text' ) {
if ( once ) {
once = false;
return;
}
}
function registerHooksForVisibleNavpops () {
for (var i=0; pg.current.links && i<pg.current.links.length; ++i) {
var navpop = pg.current.links[i].navpopup;
if (!navpop || !navpop.isVisible()) { continue; }
Navpopup.tracker.addHook(posCheckerHook(navpop));
}
}
function doIt () {
registerHooksForVisibleNavpops();
$content.each( function () {
this.ranSetupTooltipsAlready = false;
setupTooltips( this );
} );
}
setupPopups( doIt );
}
// This hook is also fired after page load.
mw.hook( 'wikipage.content' ).add( dynamicContentHandler );
mw.hook( 'ext.echo.overlay.beforeShowingOverlay' ).add( function($overlay){
dynamicContentHandler( $overlay.find(".mw-echo-state") );
});
} )();
// Forked from User:Connel MacKenzie/mess-with-popups.js
Previewmaker.prototype.firstBit = function() {
try{
if (mw.config.get("wgNamespaceNumber") !== 0){
// dont't be givin' me no subsequent paragraphs, you hear me?
/// first we "normalize" section headings, removing whitespace after, adding before
var d = this.data;
if (getValueOf('popupPreviewCutHeadings')) {
this.data = this.data.replace(RegExp('\\s*(==+[^=]*==+)\\s*', 'g'), '\n\n$1 ');
/// then we want to get rid of paragraph breaks whose text ends badly
this.data = this.data.replace(RegExp('([:;]) *\\n{2,}', 'g'), '$1\n');
this.data = this.data.replace(RegExp('^[\\s\\n]*'), '');
stuff = (RegExp('^([^\\n]|\\n[^\\n\\s])*')).exec(this.data);
if (stuff) {
d = stuff[0];
}
if (!getValueOf('popupPreviewFirstParOnly')) {
d = this.data;
}
/// now put \n\n after sections so that bullets and numbered lists work
d = d.replace(RegExp('(==+[^=]*==+)\\s*', 'g'), '$1\n\n');
}
// superfluous sentences are RIGHT OUT.
// note: exactly 1 set of parens here needed to make the slice work
d = d.parenSplit(RegExp('([!?.]+["' + "'" + ']*\\s)', 'g'));
// leading space is bad, mmkay?
d[0] = d[0].replace(RegExp('^\\s*'), '');
var notSentenceEnds = RegExp('([^.][a-z][.][a-z]|etc|sic|Dr|Mr|Mrs|Ms|St|no|\\[[^\\]]*|\\s[A-Zvclm])$', 'i');
d = this.fixSentenceEnds(d, notSentenceEnds);
var maxChars=getValueOf('popupMaxPreviewCharacters');
var n = getValueOf('popupMaxPreviewSentences');
var dd;
do {
dd = this.firstSentences(d, n);
--n;
}
while (dd.length > maxChars && n > 0);
this.data = dd;
} else {
//TODO: Limit this override to urls that start with http://*.wiktionary.org/
//TODO: extend the above section to also preview Wikipedia links
var charsWikt = 0;
var linesWikt = this.data.split('\n');
for (jWikt = 0; jWikt < linesWikt.length; jWikt++) {
linesWikt[jWikt] = linesWikt[jWikt].replace(/\{\{[in]transitive}}/g, '');
linesWikt[jWikt] = linesWikt[jWikt].replace(/\{\{[un]countable}}/g, '');
linesWikt[jWikt] = linesWikt[jWikt].replace(/\{\{cattag\|(.*?)}}/g, "");
linesWikt[jWikt] = linesWikt[jWikt].replace(/[\{\}]/g, "'");
if (linesWikt[jWikt].search(/^[#]/) == -1) {
if (linesWikt[jWikt].search(/^==[A-Z]/) == -1) {
linesWikt[jWikt] = '';
}
}
charsWikt += linesWikt[jWikt].length;
}
if (charsWikt < 2) {
linesWikt[0] = "No properly formatted content";
}
var maxChars = getValueOf('popupMaxPreviewCharacters');
var n = getValueOf('popupMaxPreviewSentences');
var dd = '';
for (jWikt = 0; jWikt < linesWikt.length; jWikt++) {
if (linesWikt[jWikt] !== '') {
dd += linesWikt[jWikt] + '\n';
}
if (dd.length < maxChars) {
this.data = dd;
}
}
}
}
catch (e) {
console.log("error from mess with popups: ", e);
}
};
});
bewhy5tf6wcoz3fhfl78dc3dvq6picc
Thành viên:Hiyuune/Gadget-PagePreviews.js
2
412110
2514176
2513943
2026-08-15T09:18:45Z
Hiyuune
50834
Xóa đổi hướng đến trang [[Thành viên:Hiyuune/Gadget-popups.js]]
2514176
javascript
text/javascript
// Page Previews for Wiktionary, by User:Ioaxxere
// <nowiki>
// Generated using: [[MediaWiki:Gadget-PagePreviews.js/ConstGeneration]]
const INTERWIKI_PREFIXES = new Map([["aa","aa"],["ab","ab"],["abstract","abstract"],["acc",0],["ace","ace"],["acronym",0],["advisory",0],["ady","ady"],["af","af"],["ak","ak"],["als","als"],["alt","alt"],["am","am"],["ami","ami"],["an","an"],["ang","ang"],["ann","ann"],["anp","anp"],["antwiki",0],["appropedia",0],["aquariumwiki",0],["ar","ar"],["arbcom-zh",0],["arborwiki",0],["arc","arc"],["arxiv",0],["ary","ary"],["arz","arz"],["as","as"],["ast","ast"],["atj","atj"],["av","av"],["avk","avk"],["awa","awa"],["ay","ay"],["az","az"],["azb","azb"],["b",0],["ba","ba"],["ban","ban"],["bar","bar"],["bat-smg","bat-smg"],["battlestarwiki",0],["bbc","bbc"],["bcl","bcl"],["bcnbio",0],["bdr","bdr"],["be","be"],["be-tarask","be-tarask"],["be-x-old","be-tarask"],["beacha",0],["betawiki",0],["betawikiversity",0],["bew","bew"],["bg","bg"],["bh","bh"],["bi","bi"],["bibcode",0],["bibliowiki",0],["bjn","bjn"],["blk","blk"],["bm","bm"],["bn","bn"],["bo","bo"],["botwiki",0],["boxrec",0],["bpy","bpy"],["br","br"],["bs","bs"],["btm","btm"],["bug","bug"],["bugzilla",0],["bulba",0],["bxr","bxr"],["c",0],["c2",0],["ca","ca"],["cache",0],["cbk-zam","cbk-zam"],["ccorg",0],["cdo","cdo"],["ce","ce"],["ceb","ceb"],["centralwikia",0],["ch","ch"],["chapter",0],["cho","cho"],["choralwiki",0],["chr","chr"],["chy","chy"],["citizendium",0],["ckb","ckb"],["cmn","zh"],["co","co"],["commons",0],["communitywiki",0],["comune",0],["cr","cr"],["creativecommons",0],["creativecommonswiki",0],["crh","crh"],["cs","cs"],["csb","csb"],["cu","cu"],["cv","cv"],["cy","cy"],["cz","cs"],["d",0],["da","da"],["dag","dag"],["dbdump",0],["dcdatabase",0],["dcw",0],["de","de"],["debian",0],["devmo",0],["dga","dga"],["dico",0],["dicoado",0],["dict",0],["dictionary",0],["diffblog",0],["din","din"],["diq","diq"],["discord",0],["disinfopedia",0],["dk","da"],["dmoz",0],["dmozs",0],["doi",0],["donate",0],["doom_wiki",0],["download",0],["dpd",0],["dpla",0],["drae",0],["dsb","dsb"],["dtp","dtp"],["dty","dty"],["dv","dv"],["dz","dz"],["ee","ee"],["egl","eml"],["el","el"],["elibre",0],["emacswiki",0],["eml","eml"],["en","en"],["en-simple","simple"],["encyc",0],["englyphwiki",0],["enkol",0],["eo","eo"],["epo","eo"],["es","es"],["esolang",0],["et","et"],["etherpad",0],["etherpadbackup",0],["ethnologue",0],["ethnologuefamily",0],["eu","eu"],["exkcd",0],["exotica",0],["ext","ext"],["f",0],["fa","fa"],["fandom",0],["fanimutationwiki",0],["fat","fat"],["fedora",0],["ff","ff"],["fi","fi"],["finalfantasy",0],["finnix",0],["fiu-vro","fiu-vro"],["fj","fj"],["flickrphoto",0],["flickruser",0],["fo","fo"],["foldoc",0],["fon","fon"],["foundation",0],["foundationsite",0],["fr","fr"],["freebsdman",0],["freedomdefined",0],["freenode",0],["freesoft",0],["frp","frp"],["frr","frr"],["fur","fur"],["fy","fy"],["ga","ga"],["gag","gag"],["gan","gan"],["gcr","gcr"],["gd","gd"],["gentoo",0],["genwiki",0],["gerrit",0],["git",0],["github",0],["gitiles",0],["gitlab",0],["gl","gl"],["glk","glk"],["globalcontribs",0],["glottolog",0],["glottopedia",0],["gn","gn"],["gom","gom"],["google",0],["googledefine",0],["googlegroups",0],["gor","gor"],["got","got"],["gpe","gpe"],["gs",0],["gsw","als"],["gu","gu"],["guc","guc"],["gucprefix",0],["guildwarswiki",0],["gur","gur"],["gutenberg",0],["gutenbergwiki",0],["guw","guw"],["gv","gv"],["ha","ha"],["hackerspaces",0],["hak","hak"],["hammondwiki",0],["haw","haw"],["hdl",0],["he","he"],["heraldik",0],["hi","hi"],["hif","hif"],["ho","ho"],["horizonlabs",0],["hr","hr"],["hrfwiki",0],["hrwiki",0],["hsb","hsb"],["ht","ht"],["hu","hu"],["hy","hy"],["hyw","hyw"],["hz","hz"],["ia","ia"],["iarchive",0],["iba","iba"],["id","id"],["ie","ie"],["ig","ig"],["igl","igl"],["ii","ii"],["ik","ik"],["ilo","ilo"],["imdbcompany",0],["imdbname",0],["imdbtitle",0],["incubator",0],["infosphere",0],["inh","inh"],["io","io"],["irc",0],["ircrc",0],["ircs",0],["is","is"],["isni",0],["iso639-3",0],["issn",0],["it","it"],["iu","iu"],["ja","ja"],["jaglyphwiki",0],["jam","jam"],["jbo","jbo"],["jira",0],["jp","ja"],["jstor",0],["jv","jv"],["ka","ka"],["kaa","kaa"],["kab","kab"],["kai","kai"],["kaj","kaj"],["kamelo",0],["karlsruhe",0],["kbd","kbd"],["kbp","kbp"],["kcg","kcg"],["kg","kg"],["kge","kge"],["ki","ki"],["kj","kj"],["kk","kk"],["kl","kl"],["km","km"],["kn","kn"],["knc","knc"],["ko","ko"],["koi","koi"],["kr","kr"],["krc","krc"],["ks","ks"],["ksh","ksh"],["ku","ku"],["kus","kus"],["kv","kv"],["kw","kw"],["ky","ky"],["la","la"],["labsconsole",0],["lad","lad"],["lb","lb"],["lbe","lbe"],["lexemes",0],["lez","lez"],["lfn","lfn"],["lg","lg"],["li","li"],["liberachat",0],["libreplanet",0],["lij","lij"],["lingualibre",0],["linguistlist",0],["listarchive",0],["lld","lld"],["lmo","lmo"],["ln","ln"],["lo","lo"],["localwiki",0],["lofc",0],["lojban",0],["lokalhistoriewiki",0],["lostpedia",0],["lrc","lrc"],["lt","lt"],["ltg","ltg"],["luxo",0],["lv","lv"],["lzh","zh-classical"],["m",0],["mad","mad"],["mag","mag"],["mai","mai"],["mail",0],["mailarchive",0],["map-bms","map-bms"],["mariowiki",0],["marveldatabase",0],["mdf","mdf"],["mdwiki",0],["meatball",0],["mediawikiwiki",0],["mediazilla",0],["memoryalpha",0],["meta",0],["metawiki",0],["metawikimedia",0],["metawikipedia",0],["mg","mg"],["mh","mh"],["mhr","mhr"],["mi","mi"],["min","min"],["mineralienatlas",0],["miraheze",0],["mixnmatch",0],["mk","mk"],["ml","ml"],["mn","mn"],["mni","mni"],["mnw","mnw"],["mo","mo"],["moinmoin",0],["mos","mos"],["mosapedia",0],["mozillawiki",0],["mozillazinekb",0],["mr","mr"],["mrj","mrj"],["ms","ms"],["mt","mt"],["mus","mus"],["mw",0],["mwl","mwl"],["mwod",0],["mwot",0],["my","my"],["myv","myv"],["mzn","mzn"],["n",0],["na","na"],["nah","nah"],["nan","zh-min-nan"],["nap","nap"],["nara",0],["nb","no"],["nds","nds"],["nds-nl","nds-nl"],["ne","ne"],["new","new"],["ng","ng"],["nia","nia"],["nl","nl"],["nlab",0],["nn","nn"],["no","no"],["nost","nostalgia"],["nostalgia","nostalgia"],["nov","nov"],["nqo","nqo"],["nr","nr"],["nrm","nrm"],["nso","nso"],["nup","nup"],["nv","nv"],["ny","ny"],["oc","oc"],["oclc",0],["oeis",0],["oewiki",0],["oldwikisource",0],["olo","olo"],["olpc",0],["om","om"],["openlibrary",0],["openstreetmap",0],["openwetware",0],["or","or"],["organicdesign",0],["orthodoxwiki",0],["os","os"],["osmwiki",0],["otrs",0],["otrswiki",0],["outreach",0],["outreachwiki",0],["owasp",0],["pa","pa"],["pag","pag"],["pam","pam"],["pap","pap"],["paws",0],["pcd","pcd"],["pcm","pcm"],["pdc","pdc"],["petscan",0],["pfl","pfl"],["phab",0],["phabricator",0],["pi","pi"],["pih","pih"],["pl","pl"],["planetmath",0],["pmid",0],["pms","pms"],["pnb","pnb"],["pnt","pnt"],["pokewiki",0],["pokéwiki",0],["policy",0],["ppl","ppl"],["proofwiki",0],["ps","ps"],["pt","pt"],["pwn","pwn"],["pyrev",0],["pythoninfo",0],["q",0],["qu","qu"],["quality",0],["quarry",0],["rcirc",0],["regiowiki",0],["rev",0],["revo",0],["rfc",0],["rheinneckar",0],["rki","rki"],["rm","rm"],["rmy","rmy"],["rn","rn"],["ro","ro"],["roa-rup","roa-rup"],["roa-tara","roa-tara"],["rodovid",0],["rsk","rsk"],["rt",0],["ru","ru"],["rue","rue"],["rup","roa-rup"],["rw","rw"],["s",0],["sa","sa"],["sah","sah"],["sat","sat"],["sc","sc"],["scholar",0],["schoolswp",0],["schoolwiki",0],["scn","scn"],["sco","sco"],["scores",0],["scoutwiki",0],["sd","sd"],["se","se"],["securewikidc",0],["semantic-mw",0],["senseislibrary",0],["sep11",0],["sg","sg"],["sgs","bat-smg"],["sh","sh"],["sharemap",0],["shi","shi"],["shn","shn"],["shoutwiki",0],["shy","shy"],["si","si"],["silcode",0],["simple","simple"],["sk","sk"],["skr","skr"],["sl","sl"],["slashdot",0],["sm","sm"],["smn","smn"],["sn","sn"],["so","so"],["sourceforge",0],["spamcheck",0],["spcom",0],["species",0],["sq","sq"],["sr","sr"],["srn","srn"],["ss","ss"],["st","st"],["stats",0],["stewardry",0],["stq","stq"],["strategy",0],["strategywiki",0],["su","su"],["sulutil",0],["sv","sv"],["svn",0],["sw","sw"],["swtrain",0],["syl","syl"],["szl","szl"],["szy","szy"],["ta","ta"],["tardis",0],["tay","tay"],["tclerswiki",0],["tcy","tcy"],["tdd","tdd"],["te","te"],["tenwiki","ten"],["test2wiki","test2"],["testcommons",0],["testwiki","test"],["testwikidata",0],["tet","tet"],["tfwiki",0],["tg","tg"],["th","th"],["thelemapedia",0],["theopedia",0],["ti","ti"],["ticket",0],["tig","tig"],["tk","tk"],["tl","tl"],["tly","tly"],["tmbw",0],["tn","tn"],["to","to"],["tok","tok"],["tolkiengateway",0],["toolforge",0],["toolhub",0],["toollabs",0],["tools",0],["tpi","tpi"],["tr","tr"],["translatewiki",0],["trv","trv"],["ts","ts"],["tswiki",0],["tt","tt"],["tum","tum"],["tviv",0],["tw","tw"],["twiki",0],["twl",0],["ty","ty"],["tyv","tyv"],["tyvawiki",0],["udm","udm"],["ug","ug"],["uk","uk"],["umap",0],["uncyclopedia",0],["unihan",0],["ur","ur"],["urbandict",0],["usability",0],["usemod",0],["utrs",0],["uz","uz"],["v",0],["ve","ve"],["vec","vec"],["vep","vep"],["vi","vi"],["viaf",0],["vikidia",0],["vlos",0],["vls","vls"],["vo","vo"],["votewiki",0],["voy",0],["vro","fiu-vro"],["vrts",0],["vrtwiki",0],["w","en"],["wa","wa"],["war","war"],["wcna",0],["weirdgloop",0],["werelate",0],["wg","wg-en"],["wikia",0],["wikiapiary",0],["wikiasite",0],["wikibooks",0],["wikicities",0],["wikicity",0],["wikiconference",0],["wikidata",0],["wikiedudashboard",0],["wikifunctions",0],["wikifur",0],["wikihow",0],["wikiindex",0],["wikilivres",0],["wikilivresru",0],["wikimania",0],["wikimedia",0],["wikinews",0],["wikinfo",0],["wikinvest",0],["wikipapers",0],["wikipedia",0],["wikipediawikipedia",0],["wikiquote",0],["wikiskripta",0],["wikisophia",0],["wikisource",0],["wikisp",0],["wikispecies",0],["wikispore",0],["wikispot",0],["wikitech",0],["wikiti",0],["wikitrek",0],["wikiversity",0],["wikivoyage",0],["wikiwikiweb",0],["wikt",0],["wiktionary",0],["wm2005",0],["wm2006",0],["wm2007",0],["wm2008",0],["wm2009",0],["wm2010",0],["wm2011",0],["wm2012",0],["wm2013",0],["wm2014",0],["wm2015",0],["wm2016",0],["wm2017",0],["wm2018",0],["wmam",0],["wmania",0],["wmar",0],["wmat",0],["wmau",0],["wmbd",0],["wmbe",0],["wmbr",0],["wmca",0],["wmch",0],["wmcl",0],["wmcn",0],["wmco",0],["wmcz",0],["wmcz_docs",0],["wmcz_old",0],["wmdc",0],["wmde",0],["wmdeblog",0],["wmdk",0],["wmdoc",0],["wmec",0],["wmee",0],["wmes",0],["wmet",0],["wmf",0],["wmfblog",0],["wmfdashboard",0],["wmfi",0],["wmfr",0],["wmge",0],["wmhi",0],["wmhk",0],["wmhu",0],["wmid",0],["wmil",0],["wmin",0],["wmit",0],["wmke",0],["wmmk",0],["wmmx",0],["wmnl",0],["wmno",0],["wmnoc",0],["wmnoch",0],["wmnyc",0],["wmpa-us",0],["wmph",0],["wmpl",0],["wmplsite",0],["wmpt",0],["wmpunjabi",0],["wmromd",0],["wmrs",0],["wmru",0],["wmse",0],["wmsk",0],["wmteam",0],["wmtr",0],["wmtw",0],["wmua",0],["wmuk",0],["wmve",0],["wmza",0],["wo","wo"],["wookieepedia",0],["wowwiki",0],["wplibrary",0],["wurmpedia",0],["wuu","wuu"],["xal","xal"],["xh","xh"],["xkcd",0],["xmf","xmf"],["xtools",0],["yi","yi"],["yo","yo"],["yue","zh-yue"],["za","za"],["zea","zea"],["zgh","zgh"],["zh","zh"],["zh-classical","zh-classical"],["zh-cn","zh"],["zh-min-nan","zh-min-nan"],["zh-tw","zh"],["zh-yue","zh-yue"],["zu","zu"],["zum",0]]);
const WP_LANGUAGES = new Map([["ab","Abkhazian"],["ace","Acehnese"],["ady","Adyghe"],["af","Afrikaans"],["als","Alemannic"],["alt","Southern Altai"],["am","Amharic"],["ami","Amis"],["an","Aragonese"],["ang","Old English"],["ann","Obolo"],["anp","Angika"],["ar","Arabic"],["arc","Aramaic"],["ary","Moroccan Arabic"],["arz","Egyptian Arabic"],["as","Assamese"],["ast","Asturian"],["atj","Atikamekw"],["av","Avaric"],["avk","Kotava"],["awa","Awadhi"],["ay","Aymara"],["az","Azerbaijani"],["azb","South Azerbaijani"],["ba","Bashkir"],["ban","Balinese"],["bar","Bavarian"],["bat-smg","Samogitian"],["bbc","Batak Toba"],["bcl","Central Bikol"],["bdr","West Coast Bajau"],["be","Belarusian"],["be-tarask","Belarusian (Taraškievica orthography)"],["bew","Betawi"],["bg","Bulgarian"],["bh","Bhojpuri"],["bi","Bislama"],["bjn","Banjar"],["blk","Pa'O"],["bm","Bambara"],["bn","Bangla"],["bo","Tibetan"],["bpy","Bishnupriya"],["br","Breton"],["bs","Bosnian"],["btm","Batak Mandailing"],["bug","Buginese"],["bxr","Russia Buriat"],["ca","Catalan"],["cbk-zam","Chavacano"],["cdo","Mindong"],["ce","Chechen"],["ceb","Cebuano"],["ch","Chamorro"],["chr","Cherokee"],["chy","Cheyenne"],["ckb","Central Kurdish"],["co","Corsican"],["crh","Crimean Tatar"],["cs","Czech"],["csb","Kashubian"],["cu","Church Slavic"],["cv","Chuvash"],["cy","Welsh"],["da","Danish"],["dag","Dagbani"],["de","German"],["dga","Southern Dagaare"],["din","Dinka"],["diq","Dimli"],["dsb","Lower Sorbian"],["dtp","Central Dusun"],["dty","Doteli"],["dv","Divehi"],["dz","Dzongkha"],["ee","Ewe"],["el","Greek"],["eml","Emiliano-Romagnolo"],["en","English"],["eo","Esperanto"],["es","Spanish"],["et","Estonian"],["eu","Basque"],["ext","Extremaduran"],["fa","Persian"],["fat","Fanti"],["ff","Fula"],["fi","Finnish"],["fiu-vro","Võro"],["fj","Fijian"],["fo","Faroese"],["fon","Fon"],["fr","French"],["frp","Arpitan"],["frr","Northern Frisian"],["fur","Friulian"],["fy","Western Frisian"],["ga","Irish"],["gag","Gagauz"],["gan","Gan"],["gcr","Guianan Creole"],["gd","Scottish Gaelic"],["gl","Galician"],["glk","Gilaki"],["gn","Guarani"],["gom","Goan Konkani"],["gor","Gorontalo"],["got","Gothic"],["gpe","Ghanaian Pidgin"],["gu","Gujarati"],["guc","Wayuu"],["gur","Frafra"],["guw","Gun"],["gv","Manx"],["ha","Hausa"],["hak","Hakka Chinese"],["haw","Hawaiian"],["he","Hebrew"],["hi","Hindi"],["hif","Fiji Hindi"],["hr","Croatian"],["hsb","Upper Sorbian"],["ht","Haitian Creole"],["hu","Hungarian"],["hy","Armenian"],["hyw","Western Armenian"],["ia","Interlingua"],["iba","Iban"],["id","Indonesian"],["ie","Interlingue"],["ig","Igbo"],["igl","Igala"],["ik","Inupiaq"],["ilo","Iloko"],["inh","Ingush"],["io","Ido"],["is","Icelandic"],["it","Italian"],["iu","Inuktitut"],["ja","Japanese"],["jam","Jamaican Creole English"],["jbo","Lojban"],["jv","Javanese"],["ka","Georgian"],["kaa","Kara-Kalpak"],["kab","Kabyle"],["kai","Karekare"],["kaj","Jju"],["kbd","Kabardian"],["kbp","Kabiye"],["kcg","Tyap"],["kg","Kongo"],["kge","Komering"],["ki","Kikuyu"],["kk","Kazakh"],["km","Khmer"],["kn","Kannada"],["knc","Central Kanuri"],["ko","Korean"],["koi","Komi-Permyak"],["krc","Karachay-Balkar"],["ks","Kashmiri"],["ksh","Colognian"],["ku","Kurdish"],["kus","Kusaal"],["kv","Komi"],["kw","Cornish"],["ky","Kyrgyz"],["la","Latin"],["lad","Ladino"],["lb","Luxembourgish"],["lbe","Lak"],["lez","Lezghian"],["lfn","Lingua Franca Nova"],["lg","Ganda"],["li","Limburgish"],["lij","Ligurian"],["lld","Ladin"],["lmo","Lombard"],["ln","Lingala"],["lo","Lao"],["lt","Lithuanian"],["ltg","Latgalian"],["lv","Latvian"],["mad","Madurese"],["mag","Magahi"],["mai","Maithili"],["map-bms","Banyumasan"],["mdf","Moksha"],["mg","Malagasy"],["mhr","Eastern Mari"],["mi","Māori"],["min","Minangkabau"],["mk","Macedonian"],["ml","Malayalam"],["mn","Mongolian"],["mni","Manipuri"],["mnw","Mon"],["mos","Mossi"],["mr","Marathi"],["mrj","Western Mari"],["ms","Malay"],["mt","Maltese"],["mwl","Mirandese"],["my","Burmese"],["myv","Erzya"],["mzn","Mazanderani"],["nah","Nahuatl"],["nap","Neapolitan"],["nds","Low German"],["nds-nl","Low Saxon"],["ne","Nepali"],["new","Newari"],["nia","Nias"],["nl","Dutch"],["nn","Norwegian Nynorsk"],["no","Norwegian"],["nov","Novial"],["nqo","N’Ko"],["nr","South Ndebele"],["nrm","Norman"],["nso","Northern Sotho"],["nup","Nupe"],["nv","Navajo"],["ny","Nyanja"],["oc","Occitan"],["olo","Livvi-Karelian"],["om","Oromo"],["or","Odia"],["os","Ossetic"],["pa","Punjabi"],["pag","Pangasinan"],["pam","Pampanga"],["pap","Papiamento"],["pcd","Picard"],["pcm","Nigerian Pidgin"],["pdc","Pennsylvania German"],["pfl","Palatine German"],["pi","Pali"],["pl","Polish"],["pms","Piedmontese"],["pnb","Western Punjabi"],["pnt","Pontic"],["ppl","Nawat"],["ps","Pashto"],["pt","Portuguese"],["pwn","Paiwan"],["qu","Quechua"],["rki","Arakanese"],["rm","Romansh"],["rmy","Vlax Romani"],["rn","Rundi"],["ro","Romanian"],["roa-rup","Aromanian"],["roa-tara","Tarantino"],["rsk","Pannonian Rusyn"],["ru","Russian"],["rue","Rusyn"],["rw","Kinyarwanda"],["sa","Sanskrit"],["sah","Yakut"],["sat","Santali"],["sc","Sardinian"],["scn","Sicilian"],["sco","Scots"],["sd","Sindhi"],["se","Northern Sami"],["sg","Sango"],["sh","Serbo-Croatian"],["shi","Tachelhit"],["shn","Shan"],["si","Sinhala"],["simple","Simple English"],["sk","Slovak"],["skr","Saraiki"],["sl","Slovenian"],["sm","Samoan"],["smn","Inari Sami"],["sn","Shona"],["so","Somali"],["sq","Albanian"],["sr","Serbian"],["srn","Sranan Tongo"],["ss","Swati"],["st","Southern Sotho"],["stq","Saterland Frisian"],["su","Sundanese"],["sv","Swedish"],["sw","Swahili"],["syl","Sylheti"],["szl","Silesian"],["szy","Sakizaya"],["ta","Tamil"],["tay","Atayal"],["tcy","Tulu"],["tdd","Tai Nuea"],["te","Telugu"],["tet","Tetum"],["tg","Tajik"],["th","Thai"],["ti","Tigrinya"],["tig","Tigre"],["tk","Turkmen"],["tl","Tagalog"],["tly","Talysh"],["tn","Tswana"],["to","Tongan"],["tok","Toki Pona"],["tpi","Tok Pisin"],["tr","Turkish"],["trv","Taroko"],["ts","Tsonga"],["tt","Tatar"],["tum","Tumbuka"],["tw","Twi"],["ty","Tahitian"],["tyv","Tuvinian"],["udm","Udmurt"],["ug","Uyghur"],["uk","Ukrainian"],["ur","Urdu"],["uz","Uzbek"],["ve","Venda"],["vec","Venetian"],["vep","Veps"],["vi","Tiếng Việt"],["vls","West Flemish"],["vo","Volapük"],["wa","Walloon"],["war","Waray"],["wo","Wolof"],["wuu","Wu"],["xal","Kalmyk"],["xh","Xhosa"],["xmf","Mingrelian"],["yi","Yiddish"],["yo","Yoruba"],["za","Zhuang"],["zea","Zeelandic"],["zgh","Standard Moroccan Tamazight"],["zh","Chinese"],["zh-classical","Literary Chinese"],["zh-min-nan","Minnan"],["zh-yue","Cantonese"],["zu","Zulu"]]);
const appendixWithSlash = ["Adûni", "Afrihili", "Arabic_roots", "Belter_Creole", "Bibliography", "Black_Speech", "Bolak", "Communicationssprache", "Dothraki", "Eloi", "Gestures", "Glosa", "Goa'uld", "High_Valyrian", "Idiom_Neutral", "Interlingue", "Interslavic", "Klingon", "Kotava", "Láadan", "Lapine", "Lingua_Franca_Nova", "Lojban", "Mandalorian", "Medefaidrin", "Minecraft", "Mundolinco", "Na'vi", "Neo", "Novial", "Noxilo", "Protologisms/Long_words", "Quenya", "Romanova", "Sindarin", "Snowclones", "Talossan", "Toki_Pona", "Unas"];
const appendixNoSlash = ["Boldface", "Capital_letter", "Italics", "Lowercase_letter", "Possessive", "Repetition", "Small_caps", "Strikethrough", "Subscript", "Superscript", "Underline", "Uppercase_letter"];
const animationSpeed = 0.2; // seconds
mw.util.addCSS(`
.wikt-page-preview ol {
margin: 0 0.5em 0 1.5em;
padding: 0;
}
.wikt-page-preview dl {
margin-bottom: 0;
}
.wikt-page-preview p {
margin: 0;
}
/* popupContainer has the opacity animation, while popup gets translated. */
.popup-fade-in-up, .popup-fade-in-down {
animation: popup-fade-in ${animationSpeed}s ease forwards;
}
.popup-fade-out-up, .popup-fade-out-down {
animation: popup-fade-out ${animationSpeed}s ease forwards;
}
.popup-fade-in-up > div {
animation: popup-move-in-up ${animationSpeed}s ease forwards;
}
.popup-fade-in-down > div {
animation: popup-move-in-down ${animationSpeed}s ease forwards;
}
.popup-fade-out-up > div {
animation: popup-move-out-up ${animationSpeed}s ease forwards;
}
.popup-fade-out-down > div {
animation: popup-move-out-down ${animationSpeed}s ease forwards;
}
@keyframes popup-move-in-up {
0% {
transform: translate(0, 20px);
}
}
@keyframes popup-move-in-down {
0% {
transform: translate(0, -20px);
}
}
@keyframes popup-move-out-up {
100% {
transform: translate(0, -20px);
}
}
@keyframes popup-move-out-down {
100% {
transform: translate(0, 20px);
}
}
@keyframes popup-fade-out {
100% {
opacity: 0;
}
}
@keyframes popup-fade-in {
0% {
opacity: 0;
}
}
.ring-loader {
margin: auto;
width: 24px;
height: 24px;
border-radius: 50%;
border-top: 5px solid var(--wikt-palette-black);
border-bottom: 5px solid var(--wikt-palette-black);
border-left: 5px solid transparent;
border-right: 5px solid transparent;
animation: spin 1.2s linear infinite;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
.preview-headerlink, .preview-headerlink:visited {
color: inherit;
font-weight: bold;
}
/* Hack: get the speaker icon on Wikipedia articles without having to load Phonos. */
.ext-phonos .oo-ui-buttonElement-button:after {
content: "🔊";
}
.ext-phonos * {
display: inline !important;
padding: 0 !important;
margin: 0 !important;
}
`);
const definitionIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M15 2a7.65 7.65 0 00-5 2 7.65 7.65 0 00-5-2H1v15h4a7.65 7.65 0 015 2 7.65 7.65 0 015-2h4V2zm2.5 13.5H14a4.38 4.38 0 00-3 1V5s1-1.5 4-1.5h2.5z"></path></g></svg>`;
const glossaryIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M12.43 14.34A5 5 0 0110 15a5 5 0 113.95-2L17 16.09V3a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 001.45-.63z"></path><circle cx="10" cy="10" r="3"></circle></g></svg>`;
const articleIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M5 1a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 002-2V3a2 2 0 00-2-2zm0 3h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"></path></g></svg>`;
const bibliographyIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M3 2h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H3c0 0 .5-.5.5-1V3c0-.5-.5-1-.5-1zM4 6h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H4c0 0 .5-.5.5-1V7c0-.5-.5-1-.5-1zM3 10h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H3c0 0 .5-.5.5-1v-1c0-.5-.5-1-.5-1zM4 14h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H4c0 0 .5-.5.5-1v-1c0-.5-.5-1-.5-1z"/></g></svg>`;
const loader = document.createElement("div");
loader.className = "ring-loader";
const popupContainer = document.createElement("div");
const popup = document.createElement("div");
const popupContent = document.createElement("div");
popupContainer.style = `display: none; position: absolute; filter: drop-shadow(0px 30px 30px rgba(0, 0, 0, 0.15)) drop-shadow(0px 0px 0.75px var(--wikt-palette-dullblue)); z-index: 801`;
popupContainer.className = "wikt-page-preview";
popup.style = "box-sizing: border-box; height: 100%; background: var(--wikt-palette-white);color:inherit";
popupContent.style = "display: flex; flex-direction: column; border-radius: 2px; box-sizing: border-box; color: var(--wikt-palette-black); overflow: auto; height: 100%; overflow-wrap: break-word; scrollbar-width: thin";
document.body.append(popupContainer);
popupContainer.append(popup);
popup.append(popupContent);
let popupTimer;
let openLink;
let mouseX, mouseY;
let API_controller = new AbortController();
function closePopup() {
if (!openLink) return;
openLink = null;
API_controller.abort();
API_controller = new AbortController();
if (popupContainer.classList.contains("popup-fade-in-up")) {
popupContainer.classList.remove("popup-fade-in-up");
popupContainer.classList.add("popup-fade-out-down");
} else {
popupContainer.classList.remove("popup-fade-in-down");
popupContainer.classList.add("popup-fade-out-up");
}
// After the animation has completed, reset the popup to its initial state.
setTimeout(() => {
popupContainer.style.display = "none";
popupContainer.classList.remove("popup-fade-out-down", "popup-fade-out-up");
}, animationSpeed * 1000);
}
popup.addEventListener("pointerenter", () => {
clearTimeout(popupTimer);
});
popup.addEventListener("pointerleave", () => {
clearTimeout(popupTimer);
popupTimer = setTimeout(closePopup, 300);
});
function processLink(link) {
let linkTitle = decodeURIComponent(link.pathname.split("/wiki/")[1]);
let titlePrefix = linkTitle.includes(":") ? linkTitle.toLowerCase().split(":")[0] : "";
let resolvedTitle = linkTitle;
let API_domain = link.origin;
let linkAnchor = decodeURIComponent(link.hash.slice(1) || "");
let isWPlink = link.href.match(/^https:\/\/[^.]+.wikipedia.org\/wiki\//);
let isPreviewLink = Boolean(link.closest(".wikt-page-preview"));
let isGlossary = /^Appendix:.*[Gg]lossary$/.test(linkTitle);
// Start with various checks to determine whether a link should be processed.
if (link.matches(`nav a, .cancelLink a, .mw-widget-titleOptionWidget a, .new, .preview-headerlink, .external, [href$="#"]`)) {
return;
} else if (isGlossary) {
// Links to glossary *must* have an anchor.
if (!linkAnchor) return;
} else if (linkTitle.startsWith("Appendix:Bibliography/")) {
// Bibliography subpages must have an anchor starting with `bib-`.
if (!linkAnchor || !linkAnchor.startsWith("bib-")) return;
} else if (!isWPlink) {
// Other Wiktionary pages must not have a lowercase-starting anchor (filters out some unhelpful links).
if (/^[a-z]/.test(linkAnchor)) return;
}
if (link.href.startsWith("https://vi.wiktionary.org/wiki/")) {
// Filter out all interwiki prefixes.
if (INTERWIKI_PREFIXES.has(titlePrefix))
return;
let {namespace, title} = new mw.Title(linkTitle);
if (namespace === 0) { // Mainspace
if (title.endsWith("/translations"))
return;
} else if (namespace === 100) { // Appendix space
if (!appendixWithSlash.some(lang => title.startsWith(lang + "/")) && !appendixNoSlash.includes(title) && !isGlossary)
return;
} else if (namespace !== 118) { // Reconstruction space
return;
}
} else if (isWPlink) {
// Filter out invalid interwiki prefixes.
if (INTERWIKI_PREFIXES.get(titlePrefix) === 0)
return;
// Get the resolved title if it's a language interwiki.
if (INTERWIKI_PREFIXES.has(titlePrefix)) {
API_domain = `https://${INTERWIKI_PREFIXES.get(titlePrefix)}.wikipedia.org`;
resolvedTitle = linkTitle.substring(linkTitle.indexOf(":") + 1);
// If the resolved title contains another interwiki, return.
let resolvedTitlePrefix = resolvedTitle.includes(":") ? resolvedTitle.toLowerCase().split(":")[0] : ""; // same as titlePrefix
if (INTERWIKI_PREFIXES.has(resolvedTitlePrefix))
return;
}
} else {
return;
}
link.addEventListener("pointerover", event => {
[mouseX, mouseY] = [event.clientX, event.clientY];
clearTimeout(popupTimer);
// Ignore links which are already open.
if (link === openLink)
return;
if (!isPreviewLink)
closePopup();
// Fetch popup text immediately on hover to reduce delay.
let responsePromise = fetch(`${API_domain}/api/rest_v1/page/html/${encodeURIComponent(resolvedTitle)}`, {
headers: {"Api-User-Agent": "Gadget developed by User:Ioaxxere"},
signal: API_controller.signal
}).then(r => r.text()).catch(() => { /* fetch was aborted */ });
popupTimer = setTimeout(() => {
popupContainer.style.display = "";
popupContent.innerHTML = "";
popupContent.append(loader);
popupContent.style.padding = "14px 16px 8px";
// Disable link hovering until animation has completed.
popupContent.style.pointerEvents = "none";
setTimeout(() => popupContent.style.pointerEvents = "", animationSpeed * 1000);
// Adapt the popup for large, standard, and small size preference in Vector 2022.
let sizeSetting = 0;
if (document.documentElement.matches(".vector-feature-custom-font-size-clientpref-1"))
sizeSetting = 1;
else if (document.documentElement.matches(".vector-feature-custom-font-size-clientpref-2"))
sizeSetting = 2;
let width = [320, 340, 360][sizeSetting];
let height = [210, 225, 240][sizeSetting];
let triangleSize = [9, 10, 11][sizeSetting];
popupContainer.style.fontSize = ["14px", "15px", "17px"][sizeSetting];
popupContainer.style.lineHeight = ["21px", "22px", "24px"][sizeSetting];
popupContainer.style.width = width + "px";
popupContainer.style.height = height + "px";
if (isPreviewLink) {
// Trigger fade-in-down animation.
popupContainer.classList.remove("popup-fade-in-up", "popup-fade-in-down");
void popupContainer.offsetLeft; // force reflow
popupContainer.classList.add("popup-fade-in-down");
} else {
openLink = link;
// Get list of rects (lines) of the target element, then find the one whose midpoint is closest to mouseY.
// This ensures that the code can correctly handle multi-line links.
let linkBlock = [...event.target.getClientRects()].reduce((prev, next) => Math.abs((next.top + next.bottom) / 2 - mouseY) < Math.abs((prev.top + prev.bottom) / 2 - mouseY) ? next : prev);
// Horizontal position. Choose left or right depending on the side of the screen the mouse is in.
let leftPosition = mouseX - 30;
if (mouseX > document.documentElement.clientWidth / 2)
leftPosition = mouseX - width + 30;
// Ensure that the popup is at least 5px away from the side of the screen.
leftPosition = Math.max(5, Math.min(leftPosition, document.documentElement.clientWidth - width - 5));
popupContainer.style.left = leftPosition + document.documentElement.scrollLeft + "px";
// Vertical position. Prioritize fade-in-down unless there would be less than 10px of room above.
if (linkBlock.top > height + 10 || linkBlock.top > document.documentElement.clientHeight - linkBlock.bottom) {
popupContainer.style.top = linkBlock.top + document.documentElement.scrollTop - height + "px";
popupContainer.classList.add("popup-fade-in-down");
popup.style.padding = `0 0 ${triangleSize}px`;
// Create a triangle on the bottom.
popup.style.clipPath = `polygon(0 0, 100% 0, 100% calc(100% - ${triangleSize}px), ${mouseX - leftPosition + triangleSize}px calc(100% - ${triangleSize}px), ${mouseX - leftPosition}px 100%, ${mouseX - leftPosition - triangleSize}px calc(100% - ${triangleSize}px), 0 calc(100% - ${triangleSize}px))`;
} else {
popupContainer.style.top = linkBlock.bottom + document.documentElement.scrollTop + "px";
popupContainer.classList.add("popup-fade-in-up");
popup.style.padding = `${triangleSize}px 0 0`;
// Create a triangle on top.
popup.style.clipPath = `polygon(0 ${triangleSize}px, ${mouseX - leftPosition - triangleSize}px ${triangleSize}px, ${mouseX - leftPosition}px 0, ${mouseX - leftPosition + triangleSize}px ${triangleSize}px, 100% ${triangleSize}px, 100% 100%, 0 100%)`;
}
}
responsePromise.then(response => {
if (!response) return; // if the fetch was aborted
popupContent.innerHTML = "";
let responseDocument = new DOMParser().parseFromString(response, "text/html");
// Convert to absolute URLs.
responseDocument.querySelectorAll("a[href]").forEach(link => link.setAttribute("href", link.href));
let anchoredElement = responseDocument.getElementById(linkAnchor);
let popupHeader = document.createElement("div");
popupHeader.style = "font-size: 90%; color: var(--wikt-palette-deepblue)";
popupContent.append(popupHeader);
let iconContainer = document.createElement("span");
iconContainer.style = "float: right; margin-left: 10px; height: 20px; color: var(--wikt-palette-black)";
popupHeader.append(iconContainer);
let titleLink = document.createElement("a");
titleLink.href = link.href;
titleLink.title = link.title;
titleLink.className = "skin-invert-image preview-headerlink";
// Scrape entry content.
if (isWPlink) {
iconContainer.innerHTML = articleIcon;
titleLink.textContent = linkTitle.replaceAll("_", " ");
if (responseDocument.title)
titleLink.innerHTML = responseDocument.title; // sometimes gives HTML text
let WikipediaName = WP_LANGUAGES.get(API_domain.substr(8).split(".")[0]);
popupHeader.append(WikipediaName + " Wikipedia article for ", titleLink);
let articleContent = document.createElement("div");
articleContent.style.margin = "5px 0 0 10px";
let firstSection = responseDocument.querySelector("section");
if (firstSection && responseDocument.querySelector(`meta[property="mw:pageNamespace"][content="0"]`)) {
firstSection.querySelectorAll("b").forEach(boldElem => boldElem.outerHTML = boldElem.innerHTML);
firstSection.querySelectorAll(":scope > p, :scope > ul, :scope > ol").forEach(elem => articleContent.append(elem));
}
if (articleContent.childElementCount)
popupContent.append(articleContent);
} else if (isGlossary) {
iconContainer.innerHTML = glossaryIcon;
titleLink.textContent = linkAnchor.replaceAll("_", " ");
popupHeader.append("Glossary definition of ", titleLink);
if (anchoredElement && anchoredElement.matches(".template-anchor")) {
// Get succeeding `dd` elements. The HTML is <dt>...<span class="template-anchor"></span>...</dt><dd>...</dd><dd>...</dd>
for (let elem = anchoredElement.parentElement.nextElementSibling; elem && elem.matches("dd"); elem = elem.nextElementSibling) {
elem.style = "margin: 5px 0 0 15px";
popupContent.append(elem.cloneNode(true));
}
}
} else if (linkTitle.startsWith("Appendix:Bibliography/")) {
iconContainer.innerHTML = bibliographyIcon;
let language = linkTitle.slice(22).replaceAll("_", " "); // trim "Appendix:Bibliography/" prefix
popupHeader.append(`${language} bibliography`);
if (anchoredElement && anchoredElement.matches(".bibliography-id")) {
let bibliographyCitation = document.createElement("div");
bibliographyCitation.style = "margin: 5px 0 0 15px";
bibliographyCitation.innerHTML = anchoredElement.innerHTML;
popupContent.append(bibliographyCitation);
}
} else {
const hasDefinitions = elem => Boolean(elem.querySelector("ol:not(.references), .ja-see, .zh-see"));
iconContainer.innerHTML = definitionIcon;
// Try to resolve the anchor element to #Chinese.
if (!anchoredElement && ["Cantonese", "Gan", "Hakka", "Hokkien", "Literary_Chinese", "Mandarin", "Middle_Chinese", "Old_Chinese", "Wu", "Xiang"].includes(linkAnchor))
anchoredElement = responseDocument.querySelector("#Chinese");
// Try to guess the anchor target in the following order: English, Chinese, Translingual, [first h2 on page]
// Always prioritize an L2 section which contains definitions.
if (!linkAnchor) {
let pageH2s = [...responseDocument.querySelectorAll("h2")];
if (pageH2s.some(h2 => hasDefinitions(h2.parentElement)))
pageH2s = pageH2s.filter(h2 => hasDefinitions(h2.parentElement));
anchoredElement = pageH2s.find(h2 => h2.id === "English");
if (!anchoredElement) anchoredElement = pageH2s.find(h2 => h2.id === "Chinese");
if (!anchoredElement) anchoredElement = pageH2s.find(h2 => h2.id === "Translingual");
if (!anchoredElement) anchoredElement = pageH2s[0];
}
let displayTitle = document.createElement("strong");
displayTitle.textContent = linkTitle.split("/").pop().replaceAll("_", " ");
if (linkTitle.startsWith("Reconstruction:"))
displayTitle.textContent = "*" + displayTitle.textContent;
// Find localest section containing an h2.
let languageSection = anchoredElement;
while (languageSection && !languageSection.querySelector(":scope > h2"))
languageSection = languageSection.parentElement.closest("section");
// Make sure that the entry is well-formed.
if (languageSection) {
let language = languageSection.querySelector(":scope > h2").textContent;
let scrapeSection = anchoredElement.closest("section");
// Find localest section which contains any definitions.
while (scrapeSection && !hasDefinitions(scrapeSection))
scrapeSection = scrapeSection.parentElement.closest("section");
if (scrapeSection) {
let headwords = [...scrapeSection.querySelectorAll(".headword-line > strong")];
if (new Set(headwords.map(h => h.textContent)).size === 1) {
// If there is a single unique headword, replace the display title with that.
displayTitle = headwords[0];
if (displayTitle.querySelector("a > img"))
displayTitle = displayTitle.querySelector("a > img").cloneNode();
} else if (new Set(headwords.map(h => h.cloneNode().outerHTML)).size === 1) {
// If there is a single unique set of element attributes, use that with the display title.
headwords[0].innerHTML = displayTitle.innerHTML;
displayTitle = headwords[0];
}
// Remove existing links in the headword.
displayTitle.querySelectorAll("a").forEach(elem => elem.replaceWith(elem.textContent));
let ols = scrapeSection.querySelectorAll(":scope > ol:not(.references), section > ol:not(.references)");
if (anchoredElement.matches(".senseid")) {
[...anchoredElement.parentElement.childNodes].forEach(child => {
if (child !== anchoredElement) child.remove();
});
ols = [anchoredElement.closest("ol")];
}
for (let ol of ols) {
let POS_container = document.createElement("div");
POS_container.style.margin = "8px 0 5px 0";
let POS = document.createElement("span");
POS.style = "font-size: 110%; font-weight: bold";
POS.textContent = ol.closest("section").firstChild.textContent;
POS_container.append(POS);
let tlb = ol.closest("section").querySelector(".headword-line ~ .usage-label-term");
if (tlb)
POS_container.append(document.createElement("br"), tlb);
popupContent.append(POS_container, ol);
}
// {{ja-see}} and {{zh-see}} don't follow the normal format, so just insert them verbatim.
for (let seeTemplate of scrapeSection.querySelectorAll(".ja-see, .zh-see"))
popupContent.append(seeTemplate);
}
titleLink.append(displayTitle);
popupHeader.append("Preview definitions of " + language + " ", titleLink);
} else {
titleLink.append(displayTitle);
popupHeader.append("Preview definitions of ", titleLink);
}
}
// Post-fetch error handling.
if (popupContent.childElementCount > 1) {
// Clean up HTML.
popupContent.querySelectorAll("link, .previewonly, .maintenance-line, .mw-empty-elt, .reference, .Inline-Template, .vsHide").forEach(elem => elem.remove());
if (!isWPlink)
popupContent.querySelectorAll("li > ul").forEach(elem => elem.remove()); // remove quotations
for (let elem of popupContent.querySelectorAll("*"))
elem.removeAttribute("id"); // avoid inadvertently repeating IDs within a page
} else if (isWPlink) {
// Display a message if the Wikipedia article was invalid or not in mainspace.
let noArticle = document.createElement("div");
noArticle.style = "margin: 5px 0 0 15px; font-size: 90%";
noArticle.textContent = "(article content could not be previewed)";
popupContent.append(noArticle);
} else if (linkAnchor && !anchoredElement) {
// Display a message if the anchor is invalid.
let noSectionFound = document.createElement("div");
noSectionFound.style = "margin: 10px 0 0 7.5px; font-size: 90%";
let strong = document.createElement("strong");
strong.textContent = linkAnchor.replaceAll("_", " ");
noSectionFound.append("The ", strong, " section was not found on this page.");
popupContent.append(noSectionFound);
} else {
// Display a message if no definitions were found in the section.
let noDefinitionsFound = document.createElement("div");
noDefinitionsFound.style = "margin: 5px 0 0 15px; font-size: 90%";
noDefinitionsFound.textContent = "(no definitions found)";
popupContent.append(noDefinitionsFound);
}
// Reduce the padding if a scrollbar is present. The intended padding is 16px on each side.
if (width - popupHeader.clientWidth > 32)
popupContent.style.paddingRight = Math.max(4, 48 + popupHeader.clientWidth - width) + "px";
});
// (Hack?) make sure that `link pointerleave` doesn't cause the popup to immediately close.
setTimeout(() => clearTimeout(popupTimer), 0);
}, isPreviewLink ? 1200 : 400);
});
link.addEventListener("pointerout", () => {
clearTimeout(popupTimer);
if (link === openLink) {
popupTimer = setTimeout(closePopup, 300);
} else {
API_controller.abort();
API_controller = new AbortController();
}
});
link.addEventListener("pointermove", event => [mouseX, mouseY] = [event.clientX, event.clientY]);
link.addEventListener("click", () => clearTimeout(popupTimer));
}
// Process all links.
document.querySelectorAll("a").forEach(processLink);
// Process links which are added to the DOM after the gadget has run.
(new MutationObserver(events => events.flatMap(event => [...event.addedNodes]).forEach(node => {
if (node instanceof HTMLAnchorElement)
processLink(node);
if (node instanceof HTMLElement)
node.querySelectorAll("a").forEach(processLink);
}))).observe(document.body, {childList: true, subtree: true});
// Dispatch hover events to support [[w:MediaWiki:Gadget-ReferenceTooltips.js]].
const linkEvent = ev => openLink && openLink.dispatchEvent(new Event(ev, {bubbles: true, cancelable: true}));
// Note: for some reason an event listener on `popup` doesn't catch everything...
popupContainer.addEventListener("pointerenter", () => setTimeout(() => linkEvent("mouseover")));
popupContainer.addEventListener("pointerleave", () => linkEvent("mouseout"));
// Custom events
popupContainer.addEventListener("pointerenter", () => linkEvent("linkPopupHover"));
popupContainer.addEventListener("pointerleave", () => linkEvent("linkPopupUnhover"));
// </nowiki>
nyoc8johrs6vi7w6vt5yo4s9effgow2
2514178
2514176
2026-08-15T09:22:31Z
Hiyuune
50834
2514178
javascript
text/javascript
// Page Previews for Wiktionary, by User:Ioaxxere
// <nowiki>
// Generated using: [[MediaWiki:Gadget-PagePreviews.js/ConstGeneration]]
const INTERWIKI_PREFIXES = new Map([["aa","aa"],["ab","ab"],["abstract","abstract"],["acc",0],["ace","ace"],["acronym",0],["advisory",0],["ady","ady"],["af","af"],["ak","ak"],["als","als"],["alt","alt"],["am","am"],["ami","ami"],["an","an"],["ang","ang"],["ann","ann"],["anp","anp"],["antwiki",0],["appropedia",0],["aquariumwiki",0],["ar","ar"],["arbcom-zh",0],["arborwiki",0],["arc","arc"],["arxiv",0],["ary","ary"],["arz","arz"],["as","as"],["ast","ast"],["atj","atj"],["av","av"],["avk","avk"],["awa","awa"],["ay","ay"],["az","az"],["azb","azb"],["b",0],["ba","ba"],["ban","ban"],["bar","bar"],["bat-smg","bat-smg"],["battlestarwiki",0],["bbc","bbc"],["bcl","bcl"],["bcnbio",0],["bdr","bdr"],["be","be"],["be-tarask","be-tarask"],["be-x-old","be-tarask"],["beacha",0],["betawiki",0],["betawikiversity",0],["bew","bew"],["bg","bg"],["bh","bh"],["bi","bi"],["bibcode",0],["bibliowiki",0],["bjn","bjn"],["blk","blk"],["bm","bm"],["bn","bn"],["bo","bo"],["botwiki",0],["boxrec",0],["bpy","bpy"],["br","br"],["bs","bs"],["btm","btm"],["bug","bug"],["bugzilla",0],["bulba",0],["bxr","bxr"],["c",0],["c2",0],["ca","ca"],["cache",0],["cbk-zam","cbk-zam"],["ccorg",0],["cdo","cdo"],["ce","ce"],["ceb","ceb"],["centralwikia",0],["ch","ch"],["chapter",0],["cho","cho"],["choralwiki",0],["chr","chr"],["chy","chy"],["citizendium",0],["ckb","ckb"],["cmn","zh"],["co","co"],["commons",0],["communitywiki",0],["comune",0],["cr","cr"],["creativecommons",0],["creativecommonswiki",0],["crh","crh"],["cs","cs"],["csb","csb"],["cu","cu"],["cv","cv"],["cy","cy"],["cz","cs"],["d",0],["da","da"],["dag","dag"],["dbdump",0],["dcdatabase",0],["dcw",0],["de","de"],["debian",0],["devmo",0],["dga","dga"],["dico",0],["dicoado",0],["dict",0],["dictionary",0],["diffblog",0],["din","din"],["diq","diq"],["discord",0],["disinfopedia",0],["dk","da"],["dmoz",0],["dmozs",0],["doi",0],["donate",0],["doom_wiki",0],["download",0],["dpd",0],["dpla",0],["drae",0],["dsb","dsb"],["dtp","dtp"],["dty","dty"],["dv","dv"],["dz","dz"],["ee","ee"],["egl","eml"],["el","el"],["elibre",0],["emacswiki",0],["eml","eml"],["en","en"],["en-simple","simple"],["encyc",0],["englyphwiki",0],["enkol",0],["eo","eo"],["epo","eo"],["es","es"],["esolang",0],["et","et"],["etherpad",0],["etherpadbackup",0],["ethnologue",0],["ethnologuefamily",0],["eu","eu"],["exkcd",0],["exotica",0],["ext","ext"],["f",0],["fa","fa"],["fandom",0],["fanimutationwiki",0],["fat","fat"],["fedora",0],["ff","ff"],["fi","fi"],["finalfantasy",0],["finnix",0],["fiu-vro","fiu-vro"],["fj","fj"],["flickrphoto",0],["flickruser",0],["fo","fo"],["foldoc",0],["fon","fon"],["foundation",0],["foundationsite",0],["fr","fr"],["freebsdman",0],["freedomdefined",0],["freenode",0],["freesoft",0],["frp","frp"],["frr","frr"],["fur","fur"],["fy","fy"],["ga","ga"],["gag","gag"],["gan","gan"],["gcr","gcr"],["gd","gd"],["gentoo",0],["genwiki",0],["gerrit",0],["git",0],["github",0],["gitiles",0],["gitlab",0],["gl","gl"],["glk","glk"],["globalcontribs",0],["glottolog",0],["glottopedia",0],["gn","gn"],["gom","gom"],["google",0],["googledefine",0],["googlegroups",0],["gor","gor"],["got","got"],["gpe","gpe"],["gs",0],["gsw","als"],["gu","gu"],["guc","guc"],["gucprefix",0],["guildwarswiki",0],["gur","gur"],["gutenberg",0],["gutenbergwiki",0],["guw","guw"],["gv","gv"],["ha","ha"],["hackerspaces",0],["hak","hak"],["hammondwiki",0],["haw","haw"],["hdl",0],["he","he"],["heraldik",0],["hi","hi"],["hif","hif"],["ho","ho"],["horizonlabs",0],["hr","hr"],["hrfwiki",0],["hrwiki",0],["hsb","hsb"],["ht","ht"],["hu","hu"],["hy","hy"],["hyw","hyw"],["hz","hz"],["ia","ia"],["iarchive",0],["iba","iba"],["id","id"],["ie","ie"],["ig","ig"],["igl","igl"],["ii","ii"],["ik","ik"],["ilo","ilo"],["imdbcompany",0],["imdbname",0],["imdbtitle",0],["incubator",0],["infosphere",0],["inh","inh"],["io","io"],["irc",0],["ircrc",0],["ircs",0],["is","is"],["isni",0],["iso639-3",0],["issn",0],["it","it"],["iu","iu"],["ja","ja"],["jaglyphwiki",0],["jam","jam"],["jbo","jbo"],["jira",0],["jp","ja"],["jstor",0],["jv","jv"],["ka","ka"],["kaa","kaa"],["kab","kab"],["kai","kai"],["kaj","kaj"],["kamelo",0],["karlsruhe",0],["kbd","kbd"],["kbp","kbp"],["kcg","kcg"],["kg","kg"],["kge","kge"],["ki","ki"],["kj","kj"],["kk","kk"],["kl","kl"],["km","km"],["kn","kn"],["knc","knc"],["ko","ko"],["koi","koi"],["kr","kr"],["krc","krc"],["ks","ks"],["ksh","ksh"],["ku","ku"],["kus","kus"],["kv","kv"],["kw","kw"],["ky","ky"],["la","la"],["labsconsole",0],["lad","lad"],["lb","lb"],["lbe","lbe"],["lexemes",0],["lez","lez"],["lfn","lfn"],["lg","lg"],["li","li"],["liberachat",0],["libreplanet",0],["lij","lij"],["lingualibre",0],["linguistlist",0],["listarchive",0],["lld","lld"],["lmo","lmo"],["ln","ln"],["lo","lo"],["localwiki",0],["lofc",0],["lojban",0],["lokalhistoriewiki",0],["lostpedia",0],["lrc","lrc"],["lt","lt"],["ltg","ltg"],["luxo",0],["lv","lv"],["lzh","zh-classical"],["m",0],["mad","mad"],["mag","mag"],["mai","mai"],["mail",0],["mailarchive",0],["map-bms","map-bms"],["mariowiki",0],["marveldatabase",0],["mdf","mdf"],["mdwiki",0],["meatball",0],["mediawikiwiki",0],["mediazilla",0],["memoryalpha",0],["meta",0],["metawiki",0],["metawikimedia",0],["metawikipedia",0],["mg","mg"],["mh","mh"],["mhr","mhr"],["mi","mi"],["min","min"],["mineralienatlas",0],["miraheze",0],["mixnmatch",0],["mk","mk"],["ml","ml"],["mn","mn"],["mni","mni"],["mnw","mnw"],["mo","mo"],["moinmoin",0],["mos","mos"],["mosapedia",0],["mozillawiki",0],["mozillazinekb",0],["mr","mr"],["mrj","mrj"],["ms","ms"],["mt","mt"],["mus","mus"],["mw",0],["mwl","mwl"],["mwod",0],["mwot",0],["my","my"],["myv","myv"],["mzn","mzn"],["n",0],["na","na"],["nah","nah"],["nan","zh-min-nan"],["nap","nap"],["nara",0],["nb","no"],["nds","nds"],["nds-nl","nds-nl"],["ne","ne"],["new","new"],["ng","ng"],["nia","nia"],["nl","nl"],["nlab",0],["nn","nn"],["no","no"],["nost","nostalgia"],["nostalgia","nostalgia"],["nov","nov"],["nqo","nqo"],["nr","nr"],["nrm","nrm"],["nso","nso"],["nup","nup"],["nv","nv"],["ny","ny"],["oc","oc"],["oclc",0],["oeis",0],["oewiki",0],["oldwikisource",0],["olo","olo"],["olpc",0],["om","om"],["openlibrary",0],["openstreetmap",0],["openwetware",0],["or","or"],["organicdesign",0],["orthodoxwiki",0],["os","os"],["osmwiki",0],["otrs",0],["otrswiki",0],["outreach",0],["outreachwiki",0],["owasp",0],["pa","pa"],["pag","pag"],["pam","pam"],["pap","pap"],["paws",0],["pcd","pcd"],["pcm","pcm"],["pdc","pdc"],["petscan",0],["pfl","pfl"],["phab",0],["phabricator",0],["pi","pi"],["pih","pih"],["pl","pl"],["planetmath",0],["pmid",0],["pms","pms"],["pnb","pnb"],["pnt","pnt"],["pokewiki",0],["pokéwiki",0],["policy",0],["ppl","ppl"],["proofwiki",0],["ps","ps"],["pt","pt"],["pwn","pwn"],["pyrev",0],["pythoninfo",0],["q",0],["qu","qu"],["quality",0],["quarry",0],["rcirc",0],["regiowiki",0],["rev",0],["revo",0],["rfc",0],["rheinneckar",0],["rki","rki"],["rm","rm"],["rmy","rmy"],["rn","rn"],["ro","ro"],["roa-rup","roa-rup"],["roa-tara","roa-tara"],["rodovid",0],["rsk","rsk"],["rt",0],["ru","ru"],["rue","rue"],["rup","roa-rup"],["rw","rw"],["s",0],["sa","sa"],["sah","sah"],["sat","sat"],["sc","sc"],["scholar",0],["schoolswp",0],["schoolwiki",0],["scn","scn"],["sco","sco"],["scores",0],["scoutwiki",0],["sd","sd"],["se","se"],["securewikidc",0],["semantic-mw",0],["senseislibrary",0],["sep11",0],["sg","sg"],["sgs","bat-smg"],["sh","sh"],["sharemap",0],["shi","shi"],["shn","shn"],["shoutwiki",0],["shy","shy"],["si","si"],["silcode",0],["simple","simple"],["sk","sk"],["skr","skr"],["sl","sl"],["slashdot",0],["sm","sm"],["smn","smn"],["sn","sn"],["so","so"],["sourceforge",0],["spamcheck",0],["spcom",0],["species",0],["sq","sq"],["sr","sr"],["srn","srn"],["ss","ss"],["st","st"],["stats",0],["stewardry",0],["stq","stq"],["strategy",0],["strategywiki",0],["su","su"],["sulutil",0],["sv","sv"],["svn",0],["sw","sw"],["swtrain",0],["syl","syl"],["szl","szl"],["szy","szy"],["ta","ta"],["tardis",0],["tay","tay"],["tclerswiki",0],["tcy","tcy"],["tdd","tdd"],["te","te"],["tenwiki","ten"],["test2wiki","test2"],["testcommons",0],["testwiki","test"],["testwikidata",0],["tet","tet"],["tfwiki",0],["tg","tg"],["th","th"],["thelemapedia",0],["theopedia",0],["ti","ti"],["ticket",0],["tig","tig"],["tk","tk"],["tl","tl"],["tly","tly"],["tmbw",0],["tn","tn"],["to","to"],["tok","tok"],["tolkiengateway",0],["toolforge",0],["toolhub",0],["toollabs",0],["tools",0],["tpi","tpi"],["tr","tr"],["translatewiki",0],["trv","trv"],["ts","ts"],["tswiki",0],["tt","tt"],["tum","tum"],["tviv",0],["tw","tw"],["twiki",0],["twl",0],["ty","ty"],["tyv","tyv"],["tyvawiki",0],["udm","udm"],["ug","ug"],["uk","uk"],["umap",0],["uncyclopedia",0],["unihan",0],["ur","ur"],["urbandict",0],["usability",0],["usemod",0],["utrs",0],["uz","uz"],["v",0],["ve","ve"],["vec","vec"],["vep","vep"],["vi","vi"],["viaf",0],["vikidia",0],["vlos",0],["vls","vls"],["vo","vo"],["votewiki",0],["voy",0],["vro","fiu-vro"],["vrts",0],["vrtwiki",0],["w","en"],["wa","wa"],["war","war"],["wcna",0],["weirdgloop",0],["werelate",0],["wg","wg-en"],["wikia",0],["wikiapiary",0],["wikiasite",0],["wikibooks",0],["wikicities",0],["wikicity",0],["wikiconference",0],["wikidata",0],["wikiedudashboard",0],["wikifunctions",0],["wikifur",0],["wikihow",0],["wikiindex",0],["wikilivres",0],["wikilivresru",0],["wikimania",0],["wikimedia",0],["wikinews",0],["wikinfo",0],["wikinvest",0],["wikipapers",0],["wikipedia",0],["wikipediawikipedia",0],["wikiquote",0],["wikiskripta",0],["wikisophia",0],["wikisource",0],["wikisp",0],["wikispecies",0],["wikispore",0],["wikispot",0],["wikitech",0],["wikiti",0],["wikitrek",0],["wikiversity",0],["wikivoyage",0],["wikiwikiweb",0],["wikt",0],["wiktionary",0],["wm2005",0],["wm2006",0],["wm2007",0],["wm2008",0],["wm2009",0],["wm2010",0],["wm2011",0],["wm2012",0],["wm2013",0],["wm2014",0],["wm2015",0],["wm2016",0],["wm2017",0],["wm2018",0],["wmam",0],["wmania",0],["wmar",0],["wmat",0],["wmau",0],["wmbd",0],["wmbe",0],["wmbr",0],["wmca",0],["wmch",0],["wmcl",0],["wmcn",0],["wmco",0],["wmcz",0],["wmcz_docs",0],["wmcz_old",0],["wmdc",0],["wmde",0],["wmdeblog",0],["wmdk",0],["wmdoc",0],["wmec",0],["wmee",0],["wmes",0],["wmet",0],["wmf",0],["wmfblog",0],["wmfdashboard",0],["wmfi",0],["wmfr",0],["wmge",0],["wmhi",0],["wmhk",0],["wmhu",0],["wmid",0],["wmil",0],["wmin",0],["wmit",0],["wmke",0],["wmmk",0],["wmmx",0],["wmnl",0],["wmno",0],["wmnoc",0],["wmnoch",0],["wmnyc",0],["wmpa-us",0],["wmph",0],["wmpl",0],["wmplsite",0],["wmpt",0],["wmpunjabi",0],["wmromd",0],["wmrs",0],["wmru",0],["wmse",0],["wmsk",0],["wmteam",0],["wmtr",0],["wmtw",0],["wmua",0],["wmuk",0],["wmve",0],["wmza",0],["wo","wo"],["wookieepedia",0],["wowwiki",0],["wplibrary",0],["wurmpedia",0],["wuu","wuu"],["xal","xal"],["xh","xh"],["xkcd",0],["xmf","xmf"],["xtools",0],["yi","yi"],["yo","yo"],["yue","zh-yue"],["za","za"],["zea","zea"],["zgh","zgh"],["zh","zh"],["zh-classical","zh-classical"],["zh-cn","zh"],["zh-min-nan","zh-min-nan"],["zh-tw","zh"],["zh-yue","zh-yue"],["zu","zu"],["zum",0]]);
const WP_LANGUAGES = new Map([["ab","Abkhazian"],["ace","Acehnese"],["ady","Adyghe"],["af","Afrikaans"],["als","Alemannic"],["alt","Southern Altai"],["am","Amharic"],["ami","Amis"],["an","Aragonese"],["ang","Old English"],["ann","Obolo"],["anp","Angika"],["ar","Arabic"],["arc","Aramaic"],["ary","Moroccan Arabic"],["arz","Egyptian Arabic"],["as","Assamese"],["ast","Asturian"],["atj","Atikamekw"],["av","Avaric"],["avk","Kotava"],["awa","Awadhi"],["ay","Aymara"],["az","Azerbaijani"],["azb","South Azerbaijani"],["ba","Bashkir"],["ban","Balinese"],["bar","Bavarian"],["bat-smg","Samogitian"],["bbc","Batak Toba"],["bcl","Central Bikol"],["bdr","West Coast Bajau"],["be","Belarusian"],["be-tarask","Belarusian (Taraškievica orthography)"],["bew","Betawi"],["bg","Bulgarian"],["bh","Bhojpuri"],["bi","Bislama"],["bjn","Banjar"],["blk","Pa'O"],["bm","Bambara"],["bn","Bangla"],["bo","Tibetan"],["bpy","Bishnupriya"],["br","Breton"],["bs","Bosnian"],["btm","Batak Mandailing"],["bug","Buginese"],["bxr","Russia Buriat"],["ca","Catalan"],["cbk-zam","Chavacano"],["cdo","Mindong"],["ce","Chechen"],["ceb","Cebuano"],["ch","Chamorro"],["chr","Cherokee"],["chy","Cheyenne"],["ckb","Central Kurdish"],["co","Corsican"],["crh","Crimean Tatar"],["cs","Czech"],["csb","Kashubian"],["cu","Church Slavic"],["cv","Chuvash"],["cy","Welsh"],["da","Danish"],["dag","Dagbani"],["de","German"],["dga","Southern Dagaare"],["din","Dinka"],["diq","Dimli"],["dsb","Lower Sorbian"],["dtp","Central Dusun"],["dty","Doteli"],["dv","Divehi"],["dz","Dzongkha"],["ee","Ewe"],["el","Greek"],["eml","Emiliano-Romagnolo"],["en","English"],["eo","Esperanto"],["es","Spanish"],["et","Estonian"],["eu","Basque"],["ext","Extremaduran"],["fa","Persian"],["fat","Fanti"],["ff","Fula"],["fi","Finnish"],["fiu-vro","Võro"],["fj","Fijian"],["fo","Faroese"],["fon","Fon"],["fr","French"],["frp","Arpitan"],["frr","Northern Frisian"],["fur","Friulian"],["fy","Western Frisian"],["ga","Irish"],["gag","Gagauz"],["gan","Gan"],["gcr","Guianan Creole"],["gd","Scottish Gaelic"],["gl","Galician"],["glk","Gilaki"],["gn","Guarani"],["gom","Goan Konkani"],["gor","Gorontalo"],["got","Gothic"],["gpe","Ghanaian Pidgin"],["gu","Gujarati"],["guc","Wayuu"],["gur","Frafra"],["guw","Gun"],["gv","Manx"],["ha","Hausa"],["hak","Hakka Chinese"],["haw","Hawaiian"],["he","Hebrew"],["hi","Hindi"],["hif","Fiji Hindi"],["hr","Croatian"],["hsb","Upper Sorbian"],["ht","Haitian Creole"],["hu","Hungarian"],["hy","Armenian"],["hyw","Western Armenian"],["ia","Interlingua"],["iba","Iban"],["id","Indonesian"],["ie","Interlingue"],["ig","Igbo"],["igl","Igala"],["ik","Inupiaq"],["ilo","Iloko"],["inh","Ingush"],["io","Ido"],["is","Icelandic"],["it","Italian"],["iu","Inuktitut"],["ja","Japanese"],["jam","Jamaican Creole English"],["jbo","Lojban"],["jv","Javanese"],["ka","Georgian"],["kaa","Kara-Kalpak"],["kab","Kabyle"],["kai","Karekare"],["kaj","Jju"],["kbd","Kabardian"],["kbp","Kabiye"],["kcg","Tyap"],["kg","Kongo"],["kge","Komering"],["ki","Kikuyu"],["kk","Kazakh"],["km","Khmer"],["kn","Kannada"],["knc","Central Kanuri"],["ko","Korean"],["koi","Komi-Permyak"],["krc","Karachay-Balkar"],["ks","Kashmiri"],["ksh","Colognian"],["ku","Kurdish"],["kus","Kusaal"],["kv","Komi"],["kw","Cornish"],["ky","Kyrgyz"],["la","Latin"],["lad","Ladino"],["lb","Luxembourgish"],["lbe","Lak"],["lez","Lezghian"],["lfn","Lingua Franca Nova"],["lg","Ganda"],["li","Limburgish"],["lij","Ligurian"],["lld","Ladin"],["lmo","Lombard"],["ln","Lingala"],["lo","Lao"],["lt","Lithuanian"],["ltg","Latgalian"],["lv","Latvian"],["mad","Madurese"],["mag","Magahi"],["mai","Maithili"],["map-bms","Banyumasan"],["mdf","Moksha"],["mg","Malagasy"],["mhr","Eastern Mari"],["mi","Māori"],["min","Minangkabau"],["mk","Macedonian"],["ml","Malayalam"],["mn","Mongolian"],["mni","Manipuri"],["mnw","Mon"],["mos","Mossi"],["mr","Marathi"],["mrj","Western Mari"],["ms","Malay"],["mt","Maltese"],["mwl","Mirandese"],["my","Burmese"],["myv","Erzya"],["mzn","Mazanderani"],["nah","Nahuatl"],["nap","Neapolitan"],["nds","Low German"],["nds-nl","Low Saxon"],["ne","Nepali"],["new","Newari"],["nia","Nias"],["nl","Dutch"],["nn","Norwegian Nynorsk"],["no","Norwegian"],["nov","Novial"],["nqo","N’Ko"],["nr","South Ndebele"],["nrm","Norman"],["nso","Northern Sotho"],["nup","Nupe"],["nv","Navajo"],["ny","Nyanja"],["oc","Occitan"],["olo","Livvi-Karelian"],["om","Oromo"],["or","Odia"],["os","Ossetic"],["pa","Punjabi"],["pag","Pangasinan"],["pam","Pampanga"],["pap","Papiamento"],["pcd","Picard"],["pcm","Nigerian Pidgin"],["pdc","Pennsylvania German"],["pfl","Palatine German"],["pi","Pali"],["pl","Polish"],["pms","Piedmontese"],["pnb","Western Punjabi"],["pnt","Pontic"],["ppl","Nawat"],["ps","Pashto"],["pt","Portuguese"],["pwn","Paiwan"],["qu","Quechua"],["rki","Arakanese"],["rm","Romansh"],["rmy","Vlax Romani"],["rn","Rundi"],["ro","Romanian"],["roa-rup","Aromanian"],["roa-tara","Tarantino"],["rsk","Pannonian Rusyn"],["ru","Russian"],["rue","Rusyn"],["rw","Kinyarwanda"],["sa","Sanskrit"],["sah","Yakut"],["sat","Santali"],["sc","Sardinian"],["scn","Sicilian"],["sco","Scots"],["sd","Sindhi"],["se","Northern Sami"],["sg","Sango"],["sh","Serbo-Croatian"],["shi","Tachelhit"],["shn","Shan"],["si","Sinhala"],["simple","Simple English"],["sk","Slovak"],["skr","Saraiki"],["sl","Slovenian"],["sm","Samoan"],["smn","Inari Sami"],["sn","Shona"],["so","Somali"],["sq","Albanian"],["sr","Serbian"],["srn","Sranan Tongo"],["ss","Swati"],["st","Southern Sotho"],["stq","Saterland Frisian"],["su","Sundanese"],["sv","Swedish"],["sw","Swahili"],["syl","Sylheti"],["szl","Silesian"],["szy","Sakizaya"],["ta","Tamil"],["tay","Atayal"],["tcy","Tulu"],["tdd","Tai Nuea"],["te","Telugu"],["tet","Tetum"],["tg","Tajik"],["th","Thai"],["ti","Tigrinya"],["tig","Tigre"],["tk","Turkmen"],["tl","Tagalog"],["tly","Talysh"],["tn","Tswana"],["to","Tongan"],["tok","Toki Pona"],["tpi","Tok Pisin"],["tr","Turkish"],["trv","Taroko"],["ts","Tsonga"],["tt","Tatar"],["tum","Tumbuka"],["tw","Twi"],["ty","Tahitian"],["tyv","Tuvinian"],["udm","Udmurt"],["ug","Uyghur"],["uk","Ukrainian"],["ur","Urdu"],["uz","Uzbek"],["ve","Venda"],["vec","Venetian"],["vep","Veps"],["vi","Tiếng Việt"],["vls","West Flemish"],["vo","Volapük"],["wa","Walloon"],["war","Waray"],["wo","Wolof"],["wuu","Wu"],["xal","Kalmyk"],["xh","Xhosa"],["xmf","Mingrelian"],["yi","Yiddish"],["yo","Yoruba"],["za","Zhuang"],["zea","Zeelandic"],["zgh","Standard Moroccan Tamazight"],["zh","Chinese"],["zh-classical","Literary Chinese"],["zh-min-nan","Minnan"],["zh-yue","Cantonese"],["zu","Zulu"]]);
const appendixWithSlash = ["Adûni", "Afrihili", "Arabic_roots", "Belter_Creole", "Bibliography", "Black_Speech", "Bolak", "Communicationssprache", "Dothraki", "Eloi", "Gestures", "Glosa", "Goa'uld", "High_Valyrian", "Idiom_Neutral", "Interlingue", "Interslavic", "Klingon", "Kotava", "Láadan", "Lapine", "Lingua_Franca_Nova", "Lojban", "Mandalorian", "Medefaidrin", "Minecraft", "Mundolinco", "Na'vi", "Neo", "Novial", "Noxilo", "Protologisms/Long_words", "Quenya", "Romanova", "Sindarin", "Snowclones", "Talossan", "Toki_Pona", "Unas"];
const appendixNoSlash = ["Boldface", "Capital_letter", "Italics", "Lowercase_letter", "Possessive", "Repetition", "Small_caps", "Strikethrough", "Subscript", "Superscript", "Underline", "Uppercase_letter"];
const animationSpeed = 0.2; // seconds
mw.util.addCSS(`
.wikt-page-preview ol {
margin: 0 0.5em 0 1.5em;
padding: 0;
}
.wikt-page-preview dl {
margin-bottom: 0;
}
.wikt-page-preview p {
margin: 0;
}
/* popupContainer has the opacity animation, while popup gets translated. */
.popup-fade-in-up, .popup-fade-in-down {
animation: popup-fade-in ${animationSpeed}s ease forwards;
}
.popup-fade-out-up, .popup-fade-out-down {
animation: popup-fade-out ${animationSpeed}s ease forwards;
}
.popup-fade-in-up > div {
animation: popup-move-in-up ${animationSpeed}s ease forwards;
}
.popup-fade-in-down > div {
animation: popup-move-in-down ${animationSpeed}s ease forwards;
}
.popup-fade-out-up > div {
animation: popup-move-out-up ${animationSpeed}s ease forwards;
}
.popup-fade-out-down > div {
animation: popup-move-out-down ${animationSpeed}s ease forwards;
}
@keyframes popup-move-in-up {
0% {
transform: translate(0, 20px);
}
}
@keyframes popup-move-in-down {
0% {
transform: translate(0, -20px);
}
}
@keyframes popup-move-out-up {
100% {
transform: translate(0, -20px);
}
}
@keyframes popup-move-out-down {
100% {
transform: translate(0, 20px);
}
}
@keyframes popup-fade-out {
100% {
opacity: 0;
}
}
@keyframes popup-fade-in {
0% {
opacity: 0;
}
}
.ring-loader {
margin: auto;
width: 24px;
height: 24px;
border-radius: 50%;
border-top: 5px solid var(--wikt-palette-black);
border-bottom: 5px solid var(--wikt-palette-black);
border-left: 5px solid transparent;
border-right: 5px solid transparent;
animation: spin 1.2s linear infinite;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
.preview-headerlink, .preview-headerlink:visited {
color: inherit;
font-weight: bold;
}
/* Hack: get the speaker icon on Wikipedia articles without having to load Phonos. */
.ext-phonos .oo-ui-buttonElement-button:after {
content: "🔊";
}
.ext-phonos * {
display: inline !important;
padding: 0 !important;
margin: 0 !important;
}
`);
const definitionIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M15 2a7.65 7.65 0 00-5 2 7.65 7.65 0 00-5-2H1v15h4a7.65 7.65 0 015 2 7.65 7.65 0 015-2h4V2zm2.5 13.5H14a4.38 4.38 0 00-3 1V5s1-1.5 4-1.5h2.5z"></path></g></svg>`;
const glossaryIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M12.43 14.34A5 5 0 0110 15a5 5 0 113.95-2L17 16.09V3a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 001.45-.63z"></path><circle cx="10" cy="10" r="3"></circle></g></svg>`;
const articleIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M5 1a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 002-2V3a2 2 0 00-2-2zm0 3h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"></path></g></svg>`;
const bibliographyIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M3 2h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H3c0 0 .5-.5.5-1V3c0-.5-.5-1-.5-1zM4 6h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H4c0 0 .5-.5.5-1V7c0-.5-.5-1-.5-1zM3 10h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H3c0 0 .5-.5.5-1v-1c0-.5-.5-1-.5-1zM4 14h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H4c0 0 .5-.5.5-1v-1c0-.5-.5-1-.5-1z"/></g></svg>`;
const loader = document.createElement("div");
loader.className = "ring-loader";
const popupContainer = document.createElement("div");
const popup = document.createElement("div");
const popupContent = document.createElement("div");
popupContainer.style = `display: none; position: absolute; filter: drop-shadow(0px 30px 30px rgba(0, 0, 0, 0.15)) drop-shadow(0px 0px 0.75px var(--wikt-palette-dullblue)); z-index: 801`;
popupContainer.className = "wikt-page-preview";
popup.style = "box-sizing: border-box; height: 100%; background: var(--wikt-palette-white);color:inherit";
popupContent.style = "display: flex; flex-direction: column; border-radius: 2px; box-sizing: border-box; color: var(--wikt-palette-black); overflow: auto; height: 100%; overflow-wrap: break-word; scrollbar-width: thin";
document.body.append(popupContainer);
popupContainer.append(popup);
popup.append(popupContent);
let popupTimer;
let openLink;
let mouseX, mouseY;
let API_controller = new AbortController();
function closePopup() {
if (!openLink) return;
openLink = null;
API_controller.abort();
API_controller = new AbortController();
if (popupContainer.classList.contains("popup-fade-in-up")) {
popupContainer.classList.remove("popup-fade-in-up");
popupContainer.classList.add("popup-fade-out-down");
} else {
popupContainer.classList.remove("popup-fade-in-down");
popupContainer.classList.add("popup-fade-out-up");
}
// After the animation has completed, reset the popup to its initial state.
setTimeout(() => {
popupContainer.style.display = "none";
popupContainer.classList.remove("popup-fade-out-down", "popup-fade-out-up");
}, animationSpeed * 1000);
}
popup.addEventListener("pointerenter", () => {
clearTimeout(popupTimer);
});
popup.addEventListener("pointerleave", () => {
clearTimeout(popupTimer);
popupTimer = setTimeout(closePopup, 300);
});
function processLink(link) {
let linkTitle = decodeURIComponent(link.pathname.split("/wiki/")[1]);
let titlePrefix = linkTitle.includes(":") ? linkTitle.toLowerCase().split(":")[0] : "";
let resolvedTitle = linkTitle;
let API_domain = link.origin;
let linkAnchor = decodeURIComponent(link.hash.slice(1) || "");
let isWPlink = link.href.match(/^https:\/\/[^.]+.wikipedia.org\/wiki\//);
let isPreviewLink = Boolean(link.closest(".wikt-page-preview"));
let isGlossary = /^Appendix:.*[Gg]lossary$/.test(linkTitle);
// Start with various checks to determine whether a link should be processed.
if (link.matches(`nav a, .cancelLink a, .mw-widget-titleOptionWidget a, .new, .preview-headerlink, .external, [href$="#"]`)) {
return;
} else if (isGlossary) {
// Links to glossary *must* have an anchor.
if (!linkAnchor) return;
} else if (linkTitle.startsWith("Appendix:Bibliography/")) {
// Bibliography subpages must have an anchor starting with `bib-`.
if (!linkAnchor || !linkAnchor.startsWith("bib-")) return;
} else if (!isWPlink) {
// Other Wiktionary pages must not have a lowercase-starting anchor (filters out some unhelpful links).
if (/^[a-z]/.test(linkAnchor)) return;
}
if (link.href.startsWith("https://vi.wiktionary.org/wiki/")) {
// Filter out all interwiki prefixes.
if (INTERWIKI_PREFIXES.has(titlePrefix))
return;
let {namespace, title} = new mw.Title(linkTitle);
if (namespace === 0) { // Mainspace
if (title.endsWith("/translations"))
return;
} else if (namespace === 100) { // Appendix space
if (!appendixWithSlash.some(lang => title.startsWith(lang + "/")) && !appendixNoSlash.includes(title) && !isGlossary)
return;
} else if (namespace !== 118) { // Reconstruction space
return;
}
} else if (isWPlink) {
// Filter out invalid interwiki prefixes.
if (INTERWIKI_PREFIXES.get(titlePrefix) === 0)
return;
// Get the resolved title if it's a language interwiki.
if (INTERWIKI_PREFIXES.has(titlePrefix)) {
API_domain = `https://${INTERWIKI_PREFIXES.get(titlePrefix)}.wikipedia.org`;
resolvedTitle = linkTitle.substring(linkTitle.indexOf(":") + 1);
// If the resolved title contains another interwiki, return.
let resolvedTitlePrefix = resolvedTitle.includes(":") ? resolvedTitle.toLowerCase().split(":")[0] : ""; // same as titlePrefix
if (INTERWIKI_PREFIXES.has(resolvedTitlePrefix))
return;
}
} else {
return;
}
link.addEventListener("pointerover", event => {
[mouseX, mouseY] = [event.clientX, event.clientY];
clearTimeout(popupTimer);
// Ignore links which are already open.
if (link === openLink)
return;
if (!isPreviewLink)
closePopup();
// Fetch popup text immediately on hover to reduce delay.
let responsePromise = fetch(`${API_domain}/api/rest_v1/page/html/${encodeURIComponent(resolvedTitle)}`, {
headers: {"Api-User-Agent": "Gadget developed by User:Ioaxxere"},
signal: API_controller.signal
}).then(r => r.text()).catch(() => { /* fetch was aborted */ });
popupTimer = setTimeout(() => {
popupContainer.style.display = "";
popupContent.innerHTML = "";
popupContent.append(loader);
popupContent.style.padding = "14px 16px 8px";
// Disable link hovering until animation has completed.
popupContent.style.pointerEvents = "none";
setTimeout(() => popupContent.style.pointerEvents = "", animationSpeed * 1000);
// Adapt the popup for large, standard, and small size preference in Vector 2022.
let sizeSetting = 0;
if (document.documentElement.matches(".vector-feature-custom-font-size-clientpref-1"))
sizeSetting = 1;
else if (document.documentElement.matches(".vector-feature-custom-font-size-clientpref-2"))
sizeSetting = 2;
let width = [320, 340, 360][sizeSetting];
let height = [210, 225, 240][sizeSetting];
let triangleSize = [9, 10, 11][sizeSetting];
popupContainer.style.fontSize = ["14px", "15px", "17px"][sizeSetting];
popupContainer.style.lineHeight = ["21px", "22px", "24px"][sizeSetting];
popupContainer.style.width = width + "px";
popupContainer.style.height = height + "px";
if (isPreviewLink) {
// Trigger fade-in-down animation.
popupContainer.classList.remove("popup-fade-in-up", "popup-fade-in-down");
void popupContainer.offsetLeft; // force reflow
popupContainer.classList.add("popup-fade-in-down");
} else {
openLink = link;
// Get list of rects (lines) of the target element, then find the one whose midpoint is closest to mouseY.
// This ensures that the code can correctly handle multi-line links.
let linkBlock = [...event.target.getClientRects()].reduce((prev, next) => Math.abs((next.top + next.bottom) / 2 - mouseY) < Math.abs((prev.top + prev.bottom) / 2 - mouseY) ? next : prev);
// Horizontal position. Choose left or right depending on the side of the screen the mouse is in.
let leftPosition = mouseX - 30;
if (mouseX > document.documentElement.clientWidth / 2)
leftPosition = mouseX - width + 30;
// Ensure that the popup is at least 5px away from the side of the screen.
leftPosition = Math.max(5, Math.min(leftPosition, document.documentElement.clientWidth - width - 5));
popupContainer.style.left = leftPosition + document.documentElement.scrollLeft + "px";
// Vertical position. Prioritize fade-in-down unless there would be less than 10px of room above.
if (linkBlock.top > height + 10 || linkBlock.top > document.documentElement.clientHeight - linkBlock.bottom) {
popupContainer.style.top = linkBlock.top + document.documentElement.scrollTop - height + "px";
popupContainer.classList.add("popup-fade-in-down");
popup.style.padding = `0 0 ${triangleSize}px`;
// Create a triangle on the bottom.
popup.style.clipPath = `polygon(0 0, 100% 0, 100% calc(100% - ${triangleSize}px), ${mouseX - leftPosition + triangleSize}px calc(100% - ${triangleSize}px), ${mouseX - leftPosition}px 100%, ${mouseX - leftPosition - triangleSize}px calc(100% - ${triangleSize}px), 0 calc(100% - ${triangleSize}px))`;
} else {
popupContainer.style.top = linkBlock.bottom + document.documentElement.scrollTop + "px";
popupContainer.classList.add("popup-fade-in-up");
popup.style.padding = `${triangleSize}px 0 0`;
// Create a triangle on top.
popup.style.clipPath = `polygon(0 ${triangleSize}px, ${mouseX - leftPosition - triangleSize}px ${triangleSize}px, ${mouseX - leftPosition}px 0, ${mouseX - leftPosition + triangleSize}px ${triangleSize}px, 100% ${triangleSize}px, 100% 100%, 0 100%)`;
}
}
responsePromise.then(response => {
if (!response) return; // if the fetch was aborted
popupContent.innerHTML = "";
let responseDocument = new DOMParser().parseFromString(response, "text/html");
// Convert to absolute URLs.
responseDocument.querySelectorAll("a[href]").forEach(link => link.setAttribute("href", link.href));
let anchoredElement = responseDocument.getElementById(linkAnchor);
let popupHeader = document.createElement("div");
popupHeader.style = "font-size: 90%; color: var(--wikt-palette-deepblue)";
popupContent.append(popupHeader);
let iconContainer = document.createElement("span");
iconContainer.style = "float: right; margin-left: 10px; height: 20px; color: var(--wikt-palette-black)";
popupHeader.append(iconContainer);
let titleLink = document.createElement("a");
titleLink.href = link.href;
titleLink.title = link.title;
titleLink.className = "skin-invert-image preview-headerlink";
// Scrape entry content.
if (isWPlink) {
iconContainer.innerHTML = articleIcon;
titleLink.textContent = linkTitle.replaceAll("_", " ");
if (responseDocument.title)
titleLink.innerHTML = responseDocument.title; // sometimes gives HTML text
let WikipediaName = WP_LANGUAGES.get(API_domain.substr(8).split(".")[0]);
popupHeader.append(WikipediaName + " Wikipedia article for ", titleLink);
let articleContent = document.createElement("div");
articleContent.style.margin = "5px 0 0 10px";
let firstSection = responseDocument.querySelector("section");
if (firstSection && responseDocument.querySelector(`meta[property="mw:pageNamespace"][content="0"]`)) {
firstSection.querySelectorAll("b").forEach(boldElem => boldElem.outerHTML = boldElem.innerHTML);
firstSection.querySelectorAll(":scope > p, :scope > ul, :scope > ol").forEach(elem => articleContent.append(elem));
}
if (articleContent.childElementCount)
popupContent.append(articleContent);
} else if (isGlossary) {
iconContainer.innerHTML = glossaryIcon;
titleLink.textContent = linkAnchor.replaceAll("_", " ");
popupHeader.append("Glossary definition of ", titleLink);
if (anchoredElement && anchoredElement.matches(".template-anchor")) {
// Get succeeding `dd` elements. The HTML is <dt>...<span class="template-anchor"></span>...</dt><dd>...</dd><dd>...</dd>
for (let elem = anchoredElement.parentElement.nextElementSibling; elem && elem.matches("dd"); elem = elem.nextElementSibling) {
elem.style = "margin: 5px 0 0 15px";
popupContent.append(elem.cloneNode(true));
}
}
} else if (linkTitle.startsWith("Appendix:Bibliography/")) {
iconContainer.innerHTML = bibliographyIcon;
let language = linkTitle.slice(22).replaceAll("_", " "); // trim "Appendix:Bibliography/" prefix
popupHeader.append(`${language} bibliography`);
if (anchoredElement && anchoredElement.matches(".bibliography-id")) {
let bibliographyCitation = document.createElement("div");
bibliographyCitation.style = "margin: 5px 0 0 15px";
bibliographyCitation.innerHTML = anchoredElement.innerHTML;
popupContent.append(bibliographyCitation);
}
} else {
const hasDefinitions = elem => Boolean(elem.querySelector("ol:not(.references), .ja-see, .zh-see"));
iconContainer.innerHTML = definitionIcon;
// Try to resolve the anchor element to #Chinese.
if (!anchoredElement && ["Cantonese", "Gan", "Hakka", "Hokkien", "Literary_Chinese", "Mandarin", "Middle_Chinese", "Old_Chinese", "Wu", "Xiang"].includes(linkAnchor))
anchoredElement = responseDocument.querySelector("#Tiếng Trung Quốc");
// Try to guess the anchor target in the following order: English, Chinese, Translingual, [first h2 on page]
// Always prioritize an L2 section which contains definitions.
if (!linkAnchor) {
let pageH2s = [...responseDocument.querySelectorAll("h2")];
if (pageH2s.some(h2 => hasDefinitions(h2.parentElement)))
pageH2s = pageH2s.filter(h2 => hasDefinitions(h2.parentElement));
anchoredElement = pageH2s.find(h2 => h2.id === "Tiếng Việt");
if (!anchoredElement) anchoredElement = pageH2s.find(h2 => h2.id === "Chinese");
if (!anchoredElement) anchoredElement = pageH2s.find(h2 => h2.id === "Translingual");
if (!anchoredElement) anchoredElement = pageH2s[0];
}
let displayTitle = document.createElement("strong");
displayTitle.textContent = linkTitle.split("/").pop().replaceAll("_", " ");
if (linkTitle.startsWith("Reconstruction:"))
displayTitle.textContent = "*" + displayTitle.textContent;
// Find localest section containing an h2.
let languageSection = anchoredElement;
while (languageSection && !languageSection.querySelector(":scope > h2"))
languageSection = languageSection.parentElement.closest("section");
// Make sure that the entry is well-formed.
if (languageSection) {
let language = languageSection.querySelector(":scope > h2").textContent;
let scrapeSection = anchoredElement.closest("section");
// Find localest section which contains any definitions.
while (scrapeSection && !hasDefinitions(scrapeSection))
scrapeSection = scrapeSection.parentElement.closest("section");
if (scrapeSection) {
let headwords = [...scrapeSection.querySelectorAll(".headword-line > strong")];
if (new Set(headwords.map(h => h.textContent)).size === 1) {
// If there is a single unique headword, replace the display title with that.
displayTitle = headwords[0];
if (displayTitle.querySelector("a > img"))
displayTitle = displayTitle.querySelector("a > img").cloneNode();
} else if (new Set(headwords.map(h => h.cloneNode().outerHTML)).size === 1) {
// If there is a single unique set of element attributes, use that with the display title.
headwords[0].innerHTML = displayTitle.innerHTML;
displayTitle = headwords[0];
}
// Remove existing links in the headword.
displayTitle.querySelectorAll("a").forEach(elem => elem.replaceWith(elem.textContent));
let ols = scrapeSection.querySelectorAll(":scope > ol:not(.references), section > ol:not(.references)");
if (anchoredElement.matches(".senseid")) {
[...anchoredElement.parentElement.childNodes].forEach(child => {
if (child !== anchoredElement) child.remove();
});
ols = [anchoredElement.closest("ol")];
}
for (let ol of ols) {
let POS_container = document.createElement("div");
POS_container.style.margin = "8px 0 5px 0";
let POS = document.createElement("span");
POS.style = "font-size: 110%; font-weight: bold";
POS.textContent = ol.closest("section").firstChild.textContent;
POS_container.append(POS);
let tlb = ol.closest("section").querySelector(".headword-line ~ .usage-label-term");
if (tlb)
POS_container.append(document.createElement("br"), tlb);
popupContent.append(POS_container, ol);
}
// {{ja-see}} and {{zh-see}} don't follow the normal format, so just insert them verbatim.
for (let seeTemplate of scrapeSection.querySelectorAll(".ja-see, .zh-see"))
popupContent.append(seeTemplate);
}
titleLink.append(displayTitle);
popupHeader.append("Preview definitions of " + language + " ", titleLink);
} else {
titleLink.append(displayTitle);
popupHeader.append("Preview definitions of ", titleLink);
}
}
// Post-fetch error handling.
if (popupContent.childElementCount > 1) {
// Clean up HTML.
popupContent.querySelectorAll("link, .previewonly, .maintenance-line, .mw-empty-elt, .reference, .Inline-Template, .vsHide").forEach(elem => elem.remove());
if (!isWPlink)
popupContent.querySelectorAll("li > ul").forEach(elem => elem.remove()); // remove quotations
for (let elem of popupContent.querySelectorAll("*"))
elem.removeAttribute("id"); // avoid inadvertently repeating IDs within a page
} else if (isWPlink) {
// Display a message if the Wikipedia article was invalid or not in mainspace.
let noArticle = document.createElement("div");
noArticle.style = "margin: 5px 0 0 15px; font-size: 90%";
noArticle.textContent = "(article content could not be previewed)";
popupContent.append(noArticle);
} else if (linkAnchor && !anchoredElement) {
// Display a message if the anchor is invalid.
let noSectionFound = document.createElement("div");
noSectionFound.style = "margin: 10px 0 0 7.5px; font-size: 90%";
let strong = document.createElement("strong");
strong.textContent = linkAnchor.replaceAll("_", " ");
noSectionFound.append("The ", strong, " section was not found on this page.");
popupContent.append(noSectionFound);
} else {
// Display a message if no definitions were found in the section.
let noDefinitionsFound = document.createElement("div");
noDefinitionsFound.style = "margin: 5px 0 0 15px; font-size: 90%";
noDefinitionsFound.textContent = "(no definitions found)";
popupContent.append(noDefinitionsFound);
}
// Reduce the padding if a scrollbar is present. The intended padding is 16px on each side.
if (width - popupHeader.clientWidth > 32)
popupContent.style.paddingRight = Math.max(4, 48 + popupHeader.clientWidth - width) + "px";
});
// (Hack?) make sure that `link pointerleave` doesn't cause the popup to immediately close.
setTimeout(() => clearTimeout(popupTimer), 0);
}, isPreviewLink ? 1200 : 400);
});
link.addEventListener("pointerout", () => {
clearTimeout(popupTimer);
if (link === openLink) {
popupTimer = setTimeout(closePopup, 300);
} else {
API_controller.abort();
API_controller = new AbortController();
}
});
link.addEventListener("pointermove", event => [mouseX, mouseY] = [event.clientX, event.clientY]);
link.addEventListener("click", () => clearTimeout(popupTimer));
}
// Process all links.
document.querySelectorAll("a").forEach(processLink);
// Process links which are added to the DOM after the gadget has run.
(new MutationObserver(events => events.flatMap(event => [...event.addedNodes]).forEach(node => {
if (node instanceof HTMLAnchorElement)
processLink(node);
if (node instanceof HTMLElement)
node.querySelectorAll("a").forEach(processLink);
}))).observe(document.body, {childList: true, subtree: true});
// Dispatch hover events to support [[w:MediaWiki:Gadget-ReferenceTooltips.js]].
const linkEvent = ev => openLink && openLink.dispatchEvent(new Event(ev, {bubbles: true, cancelable: true}));
// Note: for some reason an event listener on `popup` doesn't catch everything...
popupContainer.addEventListener("pointerenter", () => setTimeout(() => linkEvent("mouseover")));
popupContainer.addEventListener("pointerleave", () => linkEvent("mouseout"));
// Custom events
popupContainer.addEventListener("pointerenter", () => linkEvent("linkPopupHover"));
popupContainer.addEventListener("pointerleave", () => linkEvent("linkPopupUnhover"));
// </nowiki>
76l9sfw1x7fj1r2x88wl3zrxrthw38e
ᠲᠠᠢᠱ᠋ᠠ᠋ᠠ᠌
0
412162
2514026
2026-08-14T12:01:39Z
WhoAlone
40420
Trang mới: “=={{langname|cmg}}== ==={{ĐM|etym}}=== Một trong những dạng viết của {{ncog|bua|тайшаа}}. ==={{ĐM|pron}}=== {{rfp|cmg}} ==={{ĐM|noun}}=== {{head|cmg|Danh từ}} # {{lb|cmg|historical}} [[taisha]] {{gloss|người đứng đầu được bầu chọn của một Duma thảo nguyên}}”
2514026
wikitext
text/x-wiki
=={{langname|cmg}}==
==={{ĐM|etym}}===
Một trong những dạng viết của {{ncog|bua|тайшаа}}.
==={{ĐM|pron}}===
{{rfp|cmg}}
==={{ĐM|noun}}===
{{head|cmg|Danh từ}}
# {{lb|cmg|historical}} [[taisha]] {{gloss|người đứng đầu được bầu chọn của một Duma thảo nguyên}}
bpamu4iq4it7mp4axkdrwfzy687guhc
ᠲᠠᠢᠵᠢ
0
412163
2514027
2026-08-14T12:05:29Z
WhoAlone
40420
Trang mới: “=={{langname|mn}}== {{mn-variant|ᠲᠠᠢᠵᠢ|тайж}} ==={{ĐM|etym}}=== {{inh+|mn|cmg|ᠲᠠᠢᠵᠢ}}, từ {{inh|mn|xng|}}, từ {{der|mn|cmn-ear|太子|tr=-|ts=*tʰäj.t͜sɿ|t=thái tử}} và {{mention|cmn-ear|皇太弟|太弟|tr=-|ts=*tʰäj.ti|thái đệ}}. ==={{ĐM|pron}}=== * {{IPA4|mn|/tʰæːt͡ʃ/}} ==={{ĐM|noun}}=== {{mn-noun}} # {{lb|mn|historical}} [[taiji]] {{gloss|tước hiệu quý tộc Mông Cổ}} ===={{ĐM|decl}}==== {{Mong-decl|ᠲ…”
2514027
wikitext
text/x-wiki
=={{langname|mn}}==
{{mn-variant|ᠲᠠᠢᠵᠢ|тайж}}
==={{ĐM|etym}}===
{{inh+|mn|cmg|ᠲᠠᠢᠵᠢ}}, từ {{inh|mn|xng|}}, từ {{der|mn|cmn-ear|太子|tr=-|ts=*tʰäj.t͜sɿ|t=thái tử}} và {{mention|cmn-ear|皇太弟|太弟|tr=-|ts=*tʰäj.ti|thái đệ}}.
==={{ĐM|pron}}===
* {{IPA4|mn|/tʰæːt͡ʃ/}}
==={{ĐM|noun}}===
{{mn-noun}}
# {{lb|mn|historical}} [[taiji]] {{gloss|tước hiệu quý tộc Mông Cổ}}
===={{ĐM|decl}}====
{{Mong-decl|ᠲᠠᠢᠵᠢ|a|v|pl=[[ᠲᠠᠢᠵᠢ]] [[ᠨᠠᠷ]]|r}}
===={{ĐM|related}}====
{{col|mn|ᠬᠤᠩ ᠲᠠᠢᠵᠢ}}
702h0gn2tuvch6r77qbqmpfyudhqn86
2514028
2514027
2026-08-14T12:07:18Z
WhoAlone
40420
2514028
wikitext
text/x-wiki
{{also|ᡨᠠᡳᠵᡳ}}
=={{langname|mn}}==
{{mn-variant|ᠲᠠᠢᠵᠢ|тайж}}
==={{ĐM|etym}}===
{{inh+|mn|cmg|ᠲᠠᠢᠵᠢ}}, từ {{inh|mn|xng|}}, từ {{der|mn|cmn-ear|太子|tr=-|ts=*tʰäj.t͜sɿ|t=thái tử}} và {{mention|cmn-ear|皇太弟|太弟|tr=-|ts=*tʰäj.ti|thái đệ}}.
==={{ĐM|pron}}===
* {{IPA4|mn|/tʰæːt͡ʃ/}}
==={{ĐM|noun}}===
{{mn-noun}}
# {{lb|mn|historical}} [[taiji]] {{gloss|tước hiệu quý tộc Mông Cổ}}
===={{ĐM|decl}}====
{{Mong-decl|ᠲᠠᠢᠵᠢ|a|v|pl=[[ᠲᠠᠢᠵᠢ]] [[ᠨᠠᠷ]]|r}}
===={{ĐM|related}}====
{{col|mn|ᠬᠤᠩ ᠲᠠᠢᠵᠢ}}
=={{langname|cmg}}==
==={{ĐM|etym}}===
{{inh+|cmg|xng|}}, từ {{der|cmg|cmn-ear|太子|tr=-|ts=*tʰäj.t͜sɿ|t=thái tử}} và {{mention|cmn-ear|皇太弟|太弟|tr=-|ts=*tʰäj.ti|thái đệ}}.
==={{ĐM|pron}}===
{{rfp|cmg}}
==={{ĐM|noun}}===
{{head|cmg|Danh từ}}
# {{lb|cmg|historical}} [[taiji]] {{gloss|tước hiệu quý tộc Mông Cổ}}
===={{ĐM|related}}====
{{col|cmg|ᠬᠤᠩ ᠲᠠᠢᠵᠢ}}
===={{ĐM|desc}}====
* {{desc|ykh|тайджи|tr=taiji}}
* {{desc|mn|ᠲᠠᠢᠵᠢ}}
*: {{desc|mn|тайж|sclang=1}}
* {{desc|bua|тайжа|bor=1}}
* {{desc|mnc|ᡨᠠᡳᠵᡳ|bor=1}}
** {{desc|cmn|台吉|bor=1}}
30vhbbznwhusj1g10n8z4czpxsxj3kl
2514029
2514028
2026-08-14T12:10:10Z
WhoAlone
40420
/* {{ĐM|desc}} */
2514029
wikitext
text/x-wiki
{{also|ᡨᠠᡳᠵᡳ}}
=={{langname|mn}}==
{{mn-variant|ᠲᠠᠢᠵᠢ|тайж}}
==={{ĐM|etym}}===
{{inh+|mn|cmg|ᠲᠠᠢᠵᠢ}}, từ {{inh|mn|xng|}}, từ {{der|mn|cmn-ear|太子|tr=-|ts=*tʰäj.t͜sɿ|t=thái tử}} và {{mention|cmn-ear|皇太弟|太弟|tr=-|ts=*tʰäj.ti|thái đệ}}.
==={{ĐM|pron}}===
* {{IPA4|mn|/tʰæːt͡ʃ/}}
==={{ĐM|noun}}===
{{mn-noun}}
# {{lb|mn|historical}} [[taiji]] {{gloss|tước hiệu quý tộc Mông Cổ}}
===={{ĐM|decl}}====
{{Mong-decl|ᠲᠠᠢᠵᠢ|a|v|pl=[[ᠲᠠᠢᠵᠢ]] [[ᠨᠠᠷ]]|r}}
===={{ĐM|related}}====
{{col|mn|ᠬᠤᠩ ᠲᠠᠢᠵᠢ}}
=={{langname|cmg}}==
==={{ĐM|etym}}===
{{inh+|cmg|xng|}}, từ {{der|cmg|cmn-ear|太子|tr=-|ts=*tʰäj.t͜sɿ|t=thái tử}} và {{mention|cmn-ear|皇太弟|太弟|tr=-|ts=*tʰäj.ti|thái đệ}}.
==={{ĐM|pron}}===
{{rfp|cmg}}
==={{ĐM|noun}}===
{{head|cmg|Danh từ}}
# {{lb|cmg|historical}} [[taiji]] {{gloss|tước hiệu quý tộc Mông Cổ}}
===={{ĐM|related}}====
{{col|cmg|ᠬᠤᠩ ᠲᠠᠢᠵᠢ}}
===={{ĐM|desc}}====
* {{desc|ykh|тайджи}}
* {{desc|mn|ᠲᠠᠢᠵᠢ}}
*: {{desc|mn|тайж|sclang=1}}
* {{desc|bua|тайжа|bor=1}}
* {{desc|mnc|ᡨᠠᡳᠵᡳ|bor=1}}
** {{desc|cmn|台吉|bor=1}}
5gvten9xy22bzarv54rczijta7u912m
ಕುದುರೆ
0
412164
2514030
2026-08-14T12:15:52Z
Kelly zhrm
58416
Trang mới: “{{also|ಕಂದರ}} =={{langname|kn}}== ==={{ĐM|etym}}=== {{inh+|kn|dra-pro|*kuti|*kut-ir-ay}}. So sánh với {{cog|ml|കുതിര}}, {{cog|ta|குதிரை}}, {{cog|te|గుర్రము}}. ==={{ĐM|pron}}=== {{kn-IPA}} ==={{ĐM|n}}=== {{kn-noun}} # [[ngựa|Ngựa]]. #: {{syn|kn|ಅಶ್ವ}} #: {{ux|kn|'''ಕುದುರೆ'''[[-ಯು|ಯು]] [[ತನ್ನ]] [[ಒಡೆ|ಒಡೆಯನನ್ನು]] [[ಇಪ್ಪತ್ತು]] ಏಡು|ಏ…”
2514030
wikitext
text/x-wiki
{{also|ಕಂದರ}}
=={{langname|kn}}==
==={{ĐM|etym}}===
{{inh+|kn|dra-pro|*kuti|*kut-ir-ay}}. So sánh với {{cog|ml|കുതിര}}, {{cog|ta|குதிரை}}, {{cog|te|గుర్రము}}.
==={{ĐM|pron}}===
{{kn-IPA}}
==={{ĐM|n}}===
{{kn-noun}}
# [[ngựa|Ngựa]].
#: {{syn|kn|ಅಶ್ವ}}
#: {{ux|kn|'''ಕುದುರೆ'''[[-ಯು|ಯು]] [[ತನ್ನ]] [[ಒಡೆ|ಒಡೆಯನನ್ನು]] [[ಇಪ್ಪತ್ತು]] [[ಏಡು|ಏಡುಗಳಿಗೆ]] [[ಓಲಗಿಸು|ಓಲಗಿಸಿದೆ]].|Con '''ngựa''' đã phục vụ chủ nhân của nó suốt hai mươi năm.}}
# {{lb|kn|chess}} [[mã|Mã]].
===={{ĐM|decl}}====
{{kn-decl-e-i-ai|ಕುದುರೆ}}
==={{ĐM|see}}===
{{bảng:quân cờ vua/kn}}
{{C|kn|Họ Ngựa}}
ocphy2tuzmjw27390dyl0hj1129yw7o
W̃
0
412165
2514032
2026-08-14T12:16:36Z
Lcsnes
40261
Trang mới: “{{-Latn-}} ==={{ĐM|desction}}=== {{mul-letter}} #[[chữ cái|Chữ cái]] '''W viết hoa''' với dấu ngã (◌̃). ==={{ĐM|see}}=== {{Latn-script}} =={{langname|bza}}== ==={{ĐM|letter}}=== {{letter|bza}} #Chữ '''{{l|bza|W}} viết hoa''' với dấu mũi hóa. #:{{quote|bza|Ngalángi Lókolo Mbá '''W̃'''ɔ́i, nde ná ni w̃a, ele lɔ í í lévengɔ?| Hỡi Đấng Christ, hãy nói tiên-tri đi; cho chúng ta biết ai đánh ngươi. (s:Ma-thi-ơ/26#26:…”
2514032
wikitext
text/x-wiki
{{-Latn-}}
==={{ĐM|desction}}===
{{mul-letter}}
#[[chữ cái|Chữ cái]] '''W viết hoa''' với dấu ngã (◌̃).
==={{ĐM|see}}===
{{Latn-script}}
=={{langname|bza}}==
==={{ĐM|letter}}===
{{letter|bza}}
#Chữ '''{{l|bza|W}} viết hoa''' với dấu mũi hóa.
#:{{quote|bza|Ngalángi Lókolo Mbá '''W̃'''ɔ́i, nde ná ni w̃a, ele lɔ í í lévengɔ?| Hỡi Đấng Christ, hãy nói tiên-tri đi; cho chúng ta biết ai đánh ngươi. ([[s:Ma-thi-ơ/26#26:68|Ma-thi-ơ 26:68]])}}
==={{ĐM|ref}}===
*{{Chú thích web|bza|author=Bible Society in Liberia|work=Kɛ́lɛ Niinaí|year=2000|entryurl=https://www.bible.com/bible/2827/MAT.26.KNNT|entry=MÁFIYU 26}}
=={{langname|bsc}}==
==={{ĐM|letter}}===
{{letter|bsc}}
#Chữ '''{{l|bsc|W}} viết hoa''' với dấu mũi hóa.
#:{{quote|bsc|Ata Yesu ƴe ko ƴaŋ në etënd. '''W̃'''ac këɓi ɓër ỹandi baŋo ɓën do ɓën yaka këno.|Kế đó, Đức Chúa Jêsus lên trên núi, đòi những người Ngài muốn, thì những người ấy đến kề Ngài. ([[s:Mác/3#3:13|Mác 3:13]])}}
==={{ĐM|see}}===
*{{letters|lang=bsc|sc=Latn|qual=Bảng chữ cái ở Senegal|Aa|Bb|Ɓɓ|Cc|Dd|Ɗɗ|Ee|Ëë|Ff|Gg|Hh|Ii|Jj|Kk|Ll|Mm|Nn|Ññ|Ŋŋ|Oo|Pp|Rr|Ss|Ŝŝ|Tt|Uu|Ww|Xx|Yy|Ƴƴ}}
*{{letters|lang=bsc|sc=Latn|qual=Bảng chữ cái ở Guinea|Aa|Bb|Ɓɓ|Cc|Dd|Ɗɗ|Ǝə|Ee|Ɛɛ|Ff|Gg|Gw/gw|Hh|Hw/hw|Ii|Jj|Ɉɉ|Kk|Kw/kw|Ll|Mm|Mb/mb|Nn|Nd/nd|Ng/ng|Ngw/ngw|Nj/nj|Ññ|Ŋŋ|Ŋw/ŋw|Oo|Ɔɔ|Pp|Rr|Ss|Ʃʃ|Tt|Uu|Ww|Yy|Ƴƴ}}
==={{ĐM|ref}}===
*{{Chú thích web|bsc|author=Wycliffe Bible Translators, Inc.|work=Akayëta and eter ekaŝax aŋ. Akayëta Añanar aŋ|year=2016|entry=Marëk 3|entryurl=https://www.bible.com/bible/1556/MRK.3.BSCDBL}}
=={{langname|tcd}}==
==={{ĐM|letter}}===
{{letter|tcd}}
#Chữ cái thứ 47 viết hoa trong bảng chữ cái Latinh tiếng Tafi.
==={{ĐM|see}}===
*{{letters|lang=tcd|sc=Latn|qual=Bảng chữ cái Latinh tiếng Tafi|Aa|Ãã|Bb|Bh/bh|Dd|Dz/dz|Dzy/dzy|Ɖɖ|Ee|Ɛɛ|Ɛ̃/ɛ̃|Ff|Fw/fw|Gg|Gb/gb|Hh|Hw/hw|Ii|Ĩĩ|Ɩɩ|Ɩ̃/ɩ̃|Kk|Kp/kp|Ll|Mm|Nn|Ny/ny|Ŋŋ|Ŋw/ŋw|Oo|Ɔɔ|Ɔ̃/ɔ̃|Pp|Rr|Ss|Sh/sh|Tt|Ts/ts|Tsy/tsy|Tsyw/tsyw|Uu|Ũũ|Ʊʊ|Ʊ̃/ʊ̃|Vv|Ww|W̃/w̃|Xx|Xw/xw|Yy|Zz|Zh/zh}}
==={{ĐM|ref}}===
*{{Chú thích web|tcd|work=ONUGBÙ NYƐNYÃ VUVƆ|author=Wycliffe Bible Translators, Inc.|year=2025|entry=Mateo 2|entryurl=https://www.bible.com/bible/3070/MAT.2.TCD}}
=={{langname|cou}}==
==={{ĐM|letter}}===
{{letter|cou}}
#Chữ cái thứ 43 viết hoa trong bảng chữ cái Latinh tiếng Wamey.
#:{{quote|cou|Ante pëgwëko '''W̃'''ën ntind viỹë ŋa, ambin ŋa g'inkal iŋa ntiko ten.|Ban đầu Đức Chúa Trời dựng nên trời đất. ([[s:Sáng thế Ký/1#1:1|Sáng thế Ký 1:1]])}}
==={{ĐM|see}}===
*{{letters|lang=cou|sc=Latn|qual=Bảng chữ cái Latinh tiếng Wamey|a|á|b|ɓ|c|d|ɗ|e|ë|f|g|gw|h|hn|hw|i|j|k|kw|l|m|mb|mp|n|nc|nd|nj|nk|nkw|nt|ñ|ŋ|ŋw|o|p|r|ry|s|t|u|v|w|w̃|y|ỹ|ƴ}}
==={{ĐM|ref}}===
*{{Chú thích web|cou|work=Wamey|author=Wycliffe Bible Translators, Inc.|year=2018|entry=Wapëgwala 1|entryurl=https://www.bible.com/bible/2254/GEN.1.COU}}
psu3cb0r3rmofayz7f807ikd1ati34e
2514070
2514032
2026-08-15T03:00:04Z
Hiyuune
50834
2514070
wikitext
text/x-wiki
=={{langname|mul}}==
==={{ĐM|desction}}===
{{mul-letter}}
#[[chữ cái|Chữ cái]] '''W viết hoa''' với dấu ngã (◌̃).
==={{ĐM|see}}===
{{Latn-script}}
=={{langname|bza}}==
==={{ĐM|letter}}===
{{letter|bza}}
#Chữ '''{{l|bza|W}} viết hoa''' với dấu mũi hóa.
#:{{quote|bza|Ngalángi Lókolo Mbá '''W̃'''ɔ́i, nde ná ni w̃a, ele lɔ í í lévengɔ?| Hỡi Đấng Christ, hãy nói tiên-tri đi; cho chúng ta biết ai đánh ngươi. ([[s:Ma-thi-ơ/26#26:68|Ma-thi-ơ 26:68]])}}
==={{ĐM|ref}}===
*{{Chú thích web|bza|author=Bible Society in Liberia|work=Kɛ́lɛ Niinaí|year=2000|entryurl=https://www.bible.com/bible/2827/MAT.26.KNNT|entry=MÁFIYU 26}}
=={{langname|bsc}}==
==={{ĐM|letter}}===
{{letter|bsc}}
#Chữ '''{{l|bsc|W}} viết hoa''' với dấu mũi hóa.
#:{{quote|bsc|Ata Yesu ƴe ko ƴaŋ në etënd. '''W̃'''ac këɓi ɓër ỹandi baŋo ɓën do ɓën yaka këno.|Kế đó, Đức Chúa Jêsus lên trên núi, đòi những người Ngài muốn, thì những người ấy đến kề Ngài. ([[s:Mác/3#3:13|Mác 3:13]])}}
==={{ĐM|see}}===
*{{letters|lang=bsc|sc=Latn|qual=Bảng chữ cái ở Senegal|Aa|Bb|Ɓɓ|Cc|Dd|Ɗɗ|Ee|Ëë|Ff|Gg|Hh|Ii|Jj|Kk|Ll|Mm|Nn|Ññ|Ŋŋ|Oo|Pp|Rr|Ss|Ŝŝ|Tt|Uu|Ww|Xx|Yy|Ƴƴ}}
*{{letters|lang=bsc|sc=Latn|qual=Bảng chữ cái ở Guinea|Aa|Bb|Ɓɓ|Cc|Dd|Ɗɗ|Ǝə|Ee|Ɛɛ|Ff|Gg|Gw/gw|Hh|Hw/hw|Ii|Jj|Ɉɉ|Kk|Kw/kw|Ll|Mm|Mb/mb|Nn|Nd/nd|Ng/ng|Ngw/ngw|Nj/nj|Ññ|Ŋŋ|Ŋw/ŋw|Oo|Ɔɔ|Pp|Rr|Ss|Ʃʃ|Tt|Uu|Ww|Yy|Ƴƴ}}
==={{ĐM|ref}}===
*{{Chú thích web|bsc|author=Wycliffe Bible Translators, Inc.|work=Akayëta and eter ekaŝax aŋ. Akayëta Añanar aŋ|year=2016|entry=Marëk 3|entryurl=https://www.bible.com/bible/1556/MRK.3.BSCDBL}}
=={{langname|tcd}}==
==={{ĐM|letter}}===
{{letter|tcd}}
#Chữ cái thứ 47 viết hoa trong bảng chữ cái Latinh tiếng Tafi.
==={{ĐM|see}}===
*{{letters|lang=tcd|sc=Latn|qual=Bảng chữ cái Latinh tiếng Tafi|Aa|Ãã|Bb|Bh/bh|Dd|Dz/dz|Dzy/dzy|Ɖɖ|Ee|Ɛɛ|Ɛ̃/ɛ̃|Ff|Fw/fw|Gg|Gb/gb|Hh|Hw/hw|Ii|Ĩĩ|Ɩɩ|Ɩ̃/ɩ̃|Kk|Kp/kp|Ll|Mm|Nn|Ny/ny|Ŋŋ|Ŋw/ŋw|Oo|Ɔɔ|Ɔ̃/ɔ̃|Pp|Rr|Ss|Sh/sh|Tt|Ts/ts|Tsy/tsy|Tsyw/tsyw|Uu|Ũũ|Ʊʊ|Ʊ̃/ʊ̃|Vv|Ww|W̃/w̃|Xx|Xw/xw|Yy|Zz|Zh/zh}}
==={{ĐM|ref}}===
*{{Chú thích web|tcd|work=ONUGBÙ NYƐNYÃ VUVƆ|author=Wycliffe Bible Translators, Inc.|year=2025|entry=Mateo 2|entryurl=https://www.bible.com/bible/3070/MAT.2.TCD}}
=={{langname|cou}}==
==={{ĐM|letter}}===
{{letter|cou}}
#Chữ cái thứ 43 viết hoa trong bảng chữ cái Latinh tiếng Wamey.
#:{{quote|cou|Ante pëgwëko '''W̃'''ën ntind viỹë ŋa, ambin ŋa g'inkal iŋa ntiko ten.|Ban đầu Đức Chúa Trời dựng nên trời đất. ([[s:Sáng thế Ký/1#1:1|Sáng thế Ký 1:1]])}}
==={{ĐM|see}}===
*{{letters|lang=cou|sc=Latn|qual=Bảng chữ cái Latinh tiếng Wamey|a|á|b|ɓ|c|d|ɗ|e|ë|f|g|gw|h|hn|hw|i|j|k|kw|l|m|mb|mp|n|nc|nd|nj|nk|nkw|nt|ñ|ŋ|ŋw|o|p|r|ry|s|t|u|v|w|w̃|y|ỹ|ƴ}}
==={{ĐM|ref}}===
*{{Chú thích web|cou|work=Wamey|author=Wycliffe Bible Translators, Inc.|year=2018|entry=Wapëgwala 1|entryurl=https://www.bible.com/bible/2254/GEN.1.COU}}
necweac0iexnymwt6py2dm6i1zaodzc
Bản mẫu:bảng:quân cờ vua/kn
10
412166
2514034
2026-08-14T12:27:06Z
Kelly zhrm
58416
Trang mới: “{{bảng:quân cờ vua|lang=kn |chess pieces = {{l-self|kn|[[ಚದುರಂಗ|ಚದುರಂಗದ]] [[ತುಂಡು|ತುಂಡುಗಳು]]}} |pawn = {{l-self|kn|ಪ್ಯಾದೆ}} |knight = {{l-self|kn|ಕುದುರೆ}} |bishop = {{l-self|kn|ಆನೆ}} |rook = {{l-self|kn|ರಥ}} |queen = {{l-self|kn|ಮಂತ್ರಿ}}, {{l|kn|ರಾಣಿ}} |king = {{l-self|kn|ರಾಜ}} }}<noinclude>{{table doc}}</noinclude>”
2514034
wikitext
text/x-wiki
{{bảng:quân cờ vua|lang=kn
|chess pieces = {{l-self|kn|[[ಚದುರಂಗ|ಚದುರಂಗದ]] [[ತುಂಡು|ತುಂಡುಗಳು]]}}
|pawn = {{l-self|kn|ಪ್ಯಾದೆ}}
|knight = {{l-self|kn|ಕುದುರೆ}}
|bishop = {{l-self|kn|ಆನೆ}}
|rook = {{l-self|kn|ರಥ}}
|queen = {{l-self|kn|ಮಂತ್ರಿ}}, {{l|kn|ರಾಣಿ}}
|king = {{l-self|kn|ರಾಜ}}
}}<noinclude>{{table doc}}</noinclude>
5g1l2h32zczja42hur3rbpfbewn4nlu
ആന
0
412167
2514035
2026-08-14T12:33:18Z
Kelly zhrm
58416
Trang mới: “{{also|ആനി}} =={{langname|ml}}== {{wp|ml:}} ==={{ĐM|etym}}=== {{inh+|ml|dra-pro|*yĀnay}}. Cùng gốc với {{cog|kn|ಆನೆ}}, {{cog|kfa|ಆನೆ}}, {{cog|ta|யானை}} and {{cog|te|ఏనుగు}}. ==={{ĐM|pron}}=== {{ml-IPA}} * {{audio|ml|LL-Q36236 (mal)-Vis M-ആന.wav}} * {{audio|ml|LL-Q36236 (mal)-Netha Hussain-ആന.wav}} * {{audio|ml|LL-Q36236 (mal)-BhagyaMohan-ആന.wav}} ==={{ĐM|n}}=== {{ml-noun}} File:African elephant (Loxodonta afri…”
2514035
wikitext
text/x-wiki
{{also|ആനി}}
=={{langname|ml}}==
{{wp|ml:}}
==={{ĐM|etym}}===
{{inh+|ml|dra-pro|*yĀnay}}. Cùng gốc với {{cog|kn|ಆನೆ}}, {{cog|kfa|ಆನೆ}}, {{cog|ta|யானை}} and {{cog|te|ఏనుగు}}.
==={{ĐM|pron}}===
{{ml-IPA}}
* {{audio|ml|LL-Q36236 (mal)-Vis M-ആന.wav}}
* {{audio|ml|LL-Q36236 (mal)-Netha Hussain-ആന.wav}}
* {{audio|ml|LL-Q36236 (mal)-BhagyaMohan-ആന.wav}}
==={{ĐM|n}}===
{{ml-noun}}
[[File:African elephant (Loxodonta africana) 3.jpg|thumb|Một con voi]]
# [[voi|Voi]].
#: {{syn|ml|Kho từ vựng:ആന}}
# {{lb|ml|chess}} [[tượng|Tượng]].
===={{ĐM|decl}}====
{{ml-decl-noun|ആന|ആനേ|ആനയെ|ആനയ്ക്ക്|ആനയുടെ|ആനയിൽ|ആനയോട്|ആനയാൽ|ആനകൾ|ആനകളേ|ആനകളെ|ആനകൾക്ക്|ആനകളുടെ|ആനകളിൽ|ആനകളോട്|ആനകളാൽ}}
===={{ĐM|drv}}====
{{col4|ml
|ആനപ്പാപ്പാൻ
|കൊമ്പനാന
|പിടിയാന
|നാട്ടാന
|കാട്ടാന
|ആനക്കൂട്ടം
|പോരാന
|ആനച്ചന്തം
|ആനവാതിൽ
|കടലാന
|}}
==={{ĐM|see}}===
{{bảng:quân cờ vua/ml}}
==={{ĐM|ref}}===
* {{R:ml:Gundert}}
* {{R:ml:Warrier}}
{{C|ml|Lớp Thú}}
8zeqqf0scrop8cu4n9dbe7dmcas7n0f
ၶမ်း
0
412168
2514039
2026-08-14T12:50:56Z
Kelly zhrm
58416
Trang mới: “=={{langname|shn}}== ==={{ĐM|etym}}=== {{inh+|shn|tai-swe-pro|*ɣamᴬ⁴||gold}}, từ {{der|shn|och|-}} {{och-l|金}}. Cùng gốc với {{cog|th|คำ}}, {{cog|lo|ຄຳ}}, {{cog|nod|ᨤᩴᩣ}}, {{cog|kkh|ᨤᩴᩣ}}, {{cog|khb|ᦆᧄ}}, {{cog|aho|𑜁𑜪}} hoặc {{m|aho|𑜁𑜞𑜪}}, {{cog|za|gim}}. ==={{ĐM|pron}}=== {{shn-pron|audio=shn-ၶမ်း.ogg}} ==={{ĐM|n}}=== {{shn-noun}} # [[vàng|Vàng]]. {{c|shn|Kim loại}}”
2514039
wikitext
text/x-wiki
=={{langname|shn}}==
==={{ĐM|etym}}===
{{inh+|shn|tai-swe-pro|*ɣamᴬ⁴||gold}}, từ {{der|shn|och|-}} {{och-l|金}}. Cùng gốc với {{cog|th|คำ}}, {{cog|lo|ຄຳ}}, {{cog|nod|ᨤᩴᩣ}}, {{cog|kkh|ᨤᩴᩣ}}, {{cog|khb|ᦆᧄ}}, {{cog|aho|𑜁𑜪}} hoặc {{m|aho|𑜁𑜞𑜪}}, {{cog|za|gim}}.
==={{ĐM|pron}}===
{{shn-pron|audio=shn-ၶမ်း.ogg}}
==={{ĐM|n}}===
{{shn-noun}}
# [[vàng|Vàng]].
{{c|shn|Kim loại}}
dxsxl416m1zc3bwhkxp31ec1lnbieed
2514041
2514039
2026-08-14T12:52:49Z
TheHighFighter2
42988
/* Từ nguyên */
2514041
wikitext
text/x-wiki
=={{langname|shn}}==
==={{ĐM|etym}}===
{{inh+|shn|tai-swe-pro|*ɣamᴬ⁴||vàng}}, từ {{der|shn|och|-}} {{och-l|金}}. Cùng gốc với {{cog|th|คำ}}, {{cog|lo|ຄຳ}}, {{cog|nod|ᨤᩴᩣ}}, {{cog|kkh|ᨤᩴᩣ}}, {{cog|khb|ᦆᧄ}}, {{cog|aho|𑜁𑜪}} hoặc {{m|aho|𑜁𑜞𑜪}}, {{cog|za|gim}}.
==={{ĐM|pron}}===
{{shn-pron|audio=shn-ၶမ်း.ogg}}
==={{ĐM|n}}===
{{shn-noun}}
# [[vàng|Vàng]].
{{c|shn|Kim loại}}
o8qbfqmn1ljjjsw7yq2kfu8u5gq59i7
Thể loại:Mục từ có liên kết âm thanh tiếng Shan
14
412169
2514040
2026-08-14T12:51:10Z
Kelly zhrm
58416
Trang mới: “{{auto cat}}”
2514040
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
sumbulere
0
412170
2514043
2026-08-14T12:59:15Z
TheHighFighter2
42988
Trang mới: “=={{langname|ny}}== [[File:ASC Leiden - W.E.A. van Beek Collection - Dogon markets 40 - Just back from a stint in Abidjan, Domo shows his wealth at the market. Clothing, hat, umbrella. Tireli, Mali 1980.jpg|thumb|upright|Người đàn ông cầm ô tại [[Tireli]], [[Mali]].]] ==={{ĐM|etym}}=== {{ety|ny|:bor|sw:shumburere|tree=}} Vay mượn từ {{bor|ny|sw|shumburere}}, từ {{der|ny|pt|sombreiro}}. ==={{ĐM|pron}}=== * {{ny-IPA|súmbúlere}} ==={{ĐM|noun}}=== {{…”
2514043
wikitext
text/x-wiki
=={{langname|ny}}==
[[File:ASC Leiden - W.E.A. van Beek Collection - Dogon markets 40 - Just back from a stint in Abidjan, Domo shows his wealth at the market. Clothing, hat, umbrella. Tireli, Mali 1980.jpg|thumb|upright|Người đàn ông cầm ô tại [[Tireli]], [[Mali]].]]
==={{ĐM|etym}}===
{{ety|ny|:bor|sw:shumburere|tree=}}
Vay mượn từ {{bor|ny|sw|shumburere}}, từ {{der|ny|pt|sombreiro}}.
==={{ĐM|pron}}===
* {{ny-IPA|súmbúlere}}
==={{ĐM|noun}}===
{{ny-noun|súmbúlere|9}} hoặc {{ny-noun|súmbúlere|9/6}}
# {{lb|ny|dated}} [[ô|Ô]], [[dù]].
===={{ĐM|syn}}====
* {{l|ny|ambulera}}
===References===
* {{R:ny:Paas:2016|page=503}}
11rs8bf4n9qtckkp1stqzhzmjhy3iab
ᦆᧄ
0
412171
2514052
2026-08-14T14:08:36Z
Hiyuune
50834
Trang mới: “=={{langname|khb}}== ==={{section|etym}}=== {{inh+|khb|tai-swe-pro|*ɣamᴬ⁴||vàng}}, từ {{der|khb|och|-}} {{och-l|金}}. Cùng gốc với {{cog|th|คำ}}, {{cog|lo|ຄຳ}}, {{cog|shn|ၶမ်း}}, {{cog|aho|𑜁𑜪}} hoặc {{m|aho|𑜁𑜞𑜪}}, {{cog|za|gim}}. ==={{section|pron}}=== {{khb-pron}} ==={{section|n}}=== {{khb-noun|l=ᨤᩣᩴ}} # [[vàng|Vàng]]. ===={{section|drv}}==== {{col4|khb |ᦀᦱᧇᦆᧄ |ᦀᦳᧄᧈᦆᧄ |ᦷᦀᧇᦆᧄ |ᦆ…”
2514052
wikitext
text/x-wiki
=={{langname|khb}}==
==={{section|etym}}===
{{inh+|khb|tai-swe-pro|*ɣamᴬ⁴||vàng}}, từ {{der|khb|och|-}} {{och-l|金}}. Cùng gốc với {{cog|th|คำ}}, {{cog|lo|ຄຳ}}, {{cog|shn|ၶမ်း}}, {{cog|aho|𑜁𑜪}} hoặc {{m|aho|𑜁𑜞𑜪}}, {{cog|za|gim}}.
==={{section|pron}}===
{{khb-pron}}
==={{section|n}}===
{{khb-noun|l=ᨤᩣᩴ}}
# [[vàng|Vàng]].
===={{section|drv}}====
{{col4|khb
|ᦀᦱᧇᦆᧄ
|ᦀᦳᧄᧈᦆᧄ
|ᦷᦀᧇᦆᧄ
|ᦆᧄᦃᦱᧁ
|ᦆᧄᦶᦡᧂ
|ᦇᦹᧃᦆᧄ
|ᦋᦱᧂᧈᦆᧄ
|ᦵᦋᧂᦆᧄ
|ᦷᦏᧈᦆᧄ
|ᦑᦱᧁᦆᧄ
|ᦶᦕᧃᧈᦆᧄ
|ᦡᦱᧁᦆᧄ}}
{{C|khb|Nguyên tố hóa học|Kim loại}}
a0tlxyfa5wf78v02gvvsa910eki4t4c
đoạn thẳng
0
412172
2514054
2026-08-14T14:11:04Z
Hiyuune
50834
Trang mới: “=={{langname|vi}}== ==={{section|pron}}=== {{vi-pron}} ==={{section|n}}=== {{vi-noun}} # Phần [[đường thẳng]] [[giới hạn]] bởi hai [[điểm]]. ==={{section|ref}}=== * {{R:Tratu}}”
2514054
wikitext
text/x-wiki
=={{langname|vi}}==
==={{section|pron}}===
{{vi-pron}}
==={{section|n}}===
{{vi-noun}}
# Phần [[đường thẳng]] [[giới hạn]] bởi hai [[điểm]].
==={{section|ref}}===
* {{R:Tratu}}
kih50p467hqunmwexe8n1xqgwd19c1p
2514055
2514054
2026-08-14T14:11:47Z
Hiyuune
50834
/* Tiếng Việt */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2514055
wikitext
text/x-wiki
=={{langname|vi}}==
==={{section|etym}}===
{{af|vi|đoạn|thẳng}}
==={{section|pron}}===
{{vi-pron}}
==={{section|n}}===
{{vi-noun}}
# {{lb|vi|geometry}} Phần [[đường thẳng]] [[giới hạn]] bởi hai [[điểm]].
==={{section|see}}===
* {{vi-l|đường thẳng}}
==={{section|ref}}===
* {{R:Tratu}}
52kf6ofucccwyxn2l0vh57tdlm6l9fv
2514056
2514055
2026-08-14T14:14:33Z
Hiyuune
50834
/* Danh từ */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2514056
wikitext
text/x-wiki
=={{langname|vi}}==
==={{section|etym}}===
{{af|vi|đoạn|thẳng}}
==={{section|pron}}===
{{vi-pron}}
==={{section|n}}===
{{vi-noun}}
# {{lb|vi|geometry}} Phần [[đường thẳng]] [[giới hạn]] bởi hai [[điểm]].
===={{section|trans}}====
{{trans-top|phần đường thẳng giới hạn bởi hai điểm}}
* {{langname|en}}: {{t+|en|line segment}}
* {{langname|hy}}: {{t+|hy|հատված}}
* {{langname|ca}}: {{t+|ca|segment|m}}
* {{langname|da}}: {{t|da|linjestykke|n}}
* {{langname|de}}: {{t+|de|Strecke|n}}
* {{langname|nl}}: {{t+|nl|lijnstuk|n}}
* {{langname|fi}}: {{t+|fi|jana}}
* {{langname|fr}}: {{t|fr|segment de droite|m}}
* {{langname|eo}}: {{t|eo|streko}}
* {{langname|cs}}: {{t+|cs|úsečka|f}}
* {{langname|zh}}:
*: {{langname|cmn}}: {{t+|cmn|綫段|tr=xiànduàn}}
{{trans-bottom}}
==={{section|see}}===
* {{vi-l|đường thẳng}}
==={{section|ref}}===
* {{R:Tratu}}
nh7umwwtpjisw693wiylkxkuh3tb015
2514057
2514056
2026-08-14T14:17:37Z
Hiyuune
50834
/* Dịch */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2514057
wikitext
text/x-wiki
=={{langname|vi}}==
==={{section|etym}}===
{{af|vi|đoạn|thẳng}}
==={{section|pron}}===
{{vi-pron}}
==={{section|n}}===
{{vi-noun}}
# {{lb|vi|geometry}} Phần [[đường thẳng]] [[giới hạn]] bởi hai [[điểm]].
===={{section|trans}}====
{{trans-top|phần đường thẳng giới hạn bởi hai điểm}}
* {{langname|en}}: {{t+|en|line segment}}
* {{langname|hy}}: {{t+|hy|հատված}}
* {{langname|pl}}: {{t+|pl|odcinek|m-in}}
* {{langname|pt}}: {{t+|pt|segmento|m}}
* {{langname|ca}}: {{t+|ca|segment|m}}
* {{langname|da}}: {{t|da|linjestykke|n}}
* {{langname|de}}: {{t+|de|Strecke|n}}
* {{langname|nl}}: {{t+|nl|lijnstuk|n}}
* {{langname|hu}}: {{t+|hu|szakasz}}
* {{langname|is}}: {{t|is|strik|n}}, {{t|is|línustrik|n}}
* {{langname|km}}: {{t+|km|អង្កត់}}
* {{langname|ru}}: {{t+|ru|отре́зок|m}}
* {{langname|ja}}: {{t+|ja|線分|tr=senbun}}
* {{langname|fi}}: {{t+|fi|jana}}
* {{langname|fr}}: {{t|fr|segment de droite|m}}
* {{langname|eo}}: {{t|eo|streko}}
* {{langname|ro}}: {{t+|ro|segment de dreaptă|n}}, {{t+|ro|segment|n}}
* {{langname|cs}}: {{t+|cs|úsečka|f}}
* {{langname|tl}}: {{t|tl|putol ng guhit}}
* {{langname|ta}}: {{t|ta|கோட்டுத்துண்டு}}
* {{langname|es}}: {{t+|es|segmento|m}}
* {{langname|th}}: {{t|th|ส่วนของเส้นตรง}}
* {{langname|sv}}: {{t+|sv|sträcka|c}}
* {{langname|zh}}:
*: {{langname|cmn}}: {{t+|cmn|綫段|tr=xiànduàn}}
* {{langname|it}}: {{t+|it|segmento|m}}
{{trans-bottom}}
==={{section|see}}===
* {{vi-l|đường thẳng}}
==={{section|ref}}===
* {{R:Tratu}}
ojcmy3g9etn96ltti23ef49mj8fso40
amajana
0
412173
2514058
2026-08-14T14:19:13Z
Hiyuune
50834
+ es
2514058
wikitext
text/x-wiki
{{also|amajaná}}
=={{langname|es}}==
==={{section|pron}}===
{{es-pr}}
==={{section|v}}===
{{head|es|Biến thể hình thái động từ}}
# {{es-verb form of|amajanar}}
cmfv9b96tf3djlhd4aixpulkhjhmkh5
ambulera
0
412174
2514061
2026-08-14T14:56:03Z
TheHighFighter2
42988
Trang mới: “=={{langname|ny}}== ==={{ĐM|etym}}=== Vay mượn từ {{bor|ny|en|umbrella}}. ==={{ĐM|pron}}=== * {{ny-IPA|ambúlera}} ==={{ĐM|n}}=== {{ny-noun|ambúlera|9}} # [[ô|Ô]], [[dù]]. ==={{ĐM|ref}}=== * {{R:ny:Paas:2016|page=13}}”
2514061
wikitext
text/x-wiki
=={{langname|ny}}==
==={{ĐM|etym}}===
Vay mượn từ {{bor|ny|en|umbrella}}.
==={{ĐM|pron}}===
* {{ny-IPA|ambúlera}}
==={{ĐM|n}}===
{{ny-noun|ambúlera|9}}
# [[ô|Ô]], [[dù]].
==={{ĐM|ref}}===
* {{R:ny:Paas:2016|page=13}}
alrwgv9jo4jqwuxi9fpehxo7oy5tbud
2514062
2514061
2026-08-14T14:57:27Z
TheHighFighter2
42988
/* Danh từ */
2514062
wikitext
text/x-wiki
=={{langname|ny}}==
==={{ĐM|etym}}===
Vay mượn từ {{bor|ny|en|umbrella}}.
==={{ĐM|pron}}===
* {{ny-IPA|ambúlera}}
==={{ĐM|n}}===
{{ny-noun|ambúlera|9}}
# [[ô|Ô]], [[dù]].
===={{ĐM|syn}}====
* {{l|ny|sumbulere}} {{q|lỗi thời}}
==={{ĐM|ref}}===
* {{R:ny:Paas:2016|page=13}}
ik0y2js2e9eu01icg7fiisnnr2mwcxp
𠱓
0
412175
2514066
2026-08-14T15:46:22Z
Hiyuune
50834
/* */
2514066
wikitext
text/x-wiki
{{character info}}
=={{langname|mul}}==
==={{section|han}}===
{{Han char|rn=30|rad=口|as=6|sn=9|four=|canj=RNMU|ids=⿰口危}}
===={{section|ref}}====
{{Han ref|kx=0187.030|hdz=10619.140|dkj=03548|uh=20C53}}
4wx91drvvak053sullendtwvdb6ve5e
モロサスムカ
0
412176
2514067
2026-08-14T15:58:31Z
Hiyuune
50834
/* */ + ain
2514067
wikitext
text/x-wiki
=={{langname|ain}}==
==={{section|n}}===
{{head|ain|Danh từ|tr=morosasmuka}}
# {{lb|ain|Kuril}} [[tháng Mười]].
==={{section|ref}}===
:* {{R:ain:Mizushina1893}}
{{c|ain|Tháng}}
raer7wmtjs18ee5l7ks147zgwfd1qy0
Thể loại:Tiếng Nhật Đài Loan
14
412177
2514068
2026-08-14T18:00:17Z
Hiyuune
50834
/* */
2514068
wikitext
text/x-wiki
{{auto cat|lang=ja|Đài Loan|lect=1}}
h4vwh7qsngwqcvoqjri8ig7ivsf2zd6
𠱔
0
412178
2514069
2026-08-15T00:28:28Z
Hiyuune
50834
/* */ + mul
2514069
wikitext
text/x-wiki
{{character info}}
=={{langname|mul}}==
==={{section|han}}===
{{Han char|rn=30|rad=口|as=6|sn=9|four=|canj=|ids=⿰口守}}
===={{section|ref}}====
* {{Han ref|kx=0187.040|dkj=|dj=|hdz=10623.010|uh=20C54}}
i41vzj8vecnym7drd3pm27rjtj3bvlt
医生
0
412179
2514077
2026-08-15T03:16:19Z
Hiyuune
50834
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|い|せい|yomi=o}} ==={{section|pron}}=== {{ja-pron|いせい}} ==={{section|n}}=== {{ja-noun|いせい}} # [[sinh viên|Sinh viên]] [[y khoa]]. # {{lb|ja|obsolete|Triều Tiên|Taiwan}} [[y học|Y học]] [[cổ truyền]]. ===={{section|syn}}==== * {{ja-r|医学生|いがくせい}}”
2514077
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|い|せい|yomi=o}}
==={{section|pron}}===
{{ja-pron|いせい}}
==={{section|n}}===
{{ja-noun|いせい}}
# [[sinh viên|Sinh viên]] [[y khoa]].
# {{lb|ja|obsolete|Triều Tiên|Taiwan}} [[y học|Y học]] [[cổ truyền]].
===={{section|syn}}====
* {{ja-r|医学生|いがくせい}}
k7x003eubfy9e1cvh4ohzcef3h69u5l
Thể loại:Tiếng Nhật Nhật Bản
14
412180
2514078
2026-08-15T03:19:12Z
Hiyuune
50834
Trang mới: “{{auto cat|lect=1|Nhật Bản|lang=ja}}”
2514078
wikitext
text/x-wiki
{{auto cat|lect=1|Nhật Bản|lang=ja}}
cbozrx8iddtb4sc1mjc2ztxff2ohxm3
Thể loại:Tiếng Nhật Ibaraki
14
412181
2514079
2026-08-15T03:20:12Z
Hiyuune
50834
Trang mới: “{{auto cat|lect=1|Ibaraki|lang=ja|cat=Tiếng Nhật Nhật Bản}}”
2514079
wikitext
text/x-wiki
{{auto cat|lect=1|Ibaraki|lang=ja|cat=Tiếng Nhật Nhật Bản}}
o0o3gdgowzfaakmjn0posxc9lrvy4wo
亜巳李
0
412182
2514080
2026-08-15T03:24:58Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514080
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
亜巳梨
0
412183
2514081
2026-08-15T03:25:00Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514081
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
亜巳理
0
412184
2514082
2026-08-15T03:25:02Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514082
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
亜巳里
0
412185
2514083
2026-08-15T03:25:05Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514083
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
亜巳莉
0
412186
2514084
2026-08-15T03:25:08Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514084
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿見李
0
412187
2514085
2026-08-15T03:25:10Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514085
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿見梨
0
412188
2514086
2026-08-15T03:25:13Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514086
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿見理
0
412189
2514087
2026-08-15T03:25:15Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514087
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿見里
0
412190
2514088
2026-08-15T03:25:18Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514088
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿見莉
0
412191
2514089
2026-08-15T03:25:20Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514089
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
亞巳李
0
412192
2514090
2026-08-15T03:25:37Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|亜巳李}}”
2514090
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|亜巳李}}
n72l6h6jisr0i0r7fgt1crawlay408a
亞巳梨
0
412193
2514091
2026-08-15T03:27:01Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|亜巳梨}}”
2514091
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|亜巳梨}}
t2esgs8zbzdf9c3w1n5glndlzr8ydrs
亞巳理
0
412194
2514092
2026-08-15T03:27:15Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|亜巳理}}”
2514092
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|亜巳理}}
ghp5znpfy2pi8mikq4znxvtl0m1avv0
亞巳里
0
412195
2514093
2026-08-15T03:27:31Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|亜巳里}}”
2514093
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|亜巳里}}
kbxts30656g5e50shuw76kpg9cc7u9g
亞巳莉
0
412196
2514094
2026-08-15T03:27:46Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|亜巳莉}}”
2514094
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|亜巳莉}}
o1vw66f6dlf3dqkpav2ktj73eb00u9v
Thể loại:lay:Nước
14
412197
2514096
2026-08-15T03:37:32Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514096
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Chất lỏng
14
412198
2514097
2026-08-15T03:37:43Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514097
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Danh sách chủ đề thuộc nhóm liên quan
14
412199
2514098
2026-08-15T03:37:44Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514098
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Vật chất
14
412200
2514099
2026-08-15T03:38:54Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514099
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Danh sách chủ đề thuộc nhóm tập hợp
14
412201
2514100
2026-08-15T03:38:56Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514100
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Tất cả chủ đề
14
412202
2514101
2026-08-15T03:39:02Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514101
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Tự nhiên
14
412203
2514102
2026-08-15T03:39:08Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514102
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Hóa học
14
412204
2514103
2026-08-15T03:39:10Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514103
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:lay:Khoa học
14
412205
2514104
2026-08-15T03:39:21Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514104
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Thiên thể
14
412206
2514109
2026-08-15T03:48:04Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514109
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Không gian
14
412207
2514110
2026-08-15T03:48:51Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514110
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Danh sách chủ đề thuộc nhóm tập hợp
14
412208
2514111
2026-08-15T03:48:52Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514111
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Tất cả chủ đề
14
412209
2514112
2026-08-15T03:49:13Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514112
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Tự nhiên
14
412210
2514113
2026-08-15T03:49:14Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514113
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Danh sách chủ đề thuộc nhóm liên quan
14
412211
2514114
2026-08-15T03:49:16Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514114
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
阿実李
0
412212
2514115
2026-08-15T03:50:12Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514115
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿実梨
0
412213
2514116
2026-08-15T03:50:14Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514116
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿実里
0
412214
2514117
2026-08-15T03:50:16Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514117
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿實李
0
412215
2514118
2026-08-15T03:51:29Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|阿実李}}”
2514118
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|阿実李}}
gxkecibcm9gu1uesn5ikbjs4igdvutd
阿實梨
0
412216
2514119
2026-08-15T03:51:40Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|阿実梨}}”
2514119
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|阿実梨}}
0cqrdhqs54vjdn2kbdopgfpthezatg5
阿實里
0
412217
2514120
2026-08-15T03:51:59Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|阿実里}}”
2514120
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|阿実里}}
06ayjmkpwkvr7whiy0gxrli7cft8f5s
阿実莉
0
412218
2514121
2026-08-15T03:52:25Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514121
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿美李
0
412219
2514122
2026-08-15T03:52:27Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514122
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿美利
0
412220
2514123
2026-08-15T03:52:28Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514123
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿美梨
0
412221
2514124
2026-08-15T03:52:30Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514124
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿美理
0
412222
2514125
2026-08-15T03:52:31Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514125
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿美里
0
412223
2514126
2026-08-15T03:52:34Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514126
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿美麗
0
412224
2514127
2026-08-15T03:52:36Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あ|み|り}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|あみり}} # {{given name|ja|nữ|sort=あみり}}”
2514127
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-kanjitab|あ|み|り}}
==={{ĐM|pr-noun}}===
{{ja-pos|proper|あみり}}
# {{given name|ja|nữ|sort=あみり}}
s8uorizb207aw0r4p9a9uh0qd9s6kfj
阿實莉
0
412225
2514131
2026-08-15T03:58:35Z
WhoAlone
40420
Trang mới: “=={{langname|ja}}== {{ja-see|阿実莉}}”
2514131
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|阿実莉}}
9r2xgqrgtur90kq2wfvqeexnrerle3d
Thể loại:mmd:Nước
14
412226
2514136
2026-08-15T03:59:47Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514136
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Chất lỏng
14
412227
2514137
2026-08-15T04:00:23Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514137
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Vật chất
14
412228
2514139
2026-08-15T04:01:32Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514139
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Hóa học
14
412229
2514141
2026-08-15T04:02:33Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514141
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:mmd:Khoa học
14
412230
2514144
2026-08-15T04:03:30Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514144
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Rau
14
412231
2514148
2026-08-15T05:13:06Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514148
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Thực phẩm
14
412232
2514149
2026-08-15T05:13:28Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514149
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Danh sách chủ đề thuộc nhóm tập hợp
14
412233
2514150
2026-08-15T05:13:31Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514150
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Thực vật
14
412234
2514151
2026-08-15T05:13:34Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514151
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Sinh vật
14
412235
2514152
2026-08-15T05:13:46Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514152
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Danh sách chủ đề thuộc nhóm loại hình
14
412236
2514153
2026-08-15T05:13:48Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514153
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Ăn uống
14
412237
2514154
2026-08-15T05:13:51Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514154
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Ăn
14
412238
2514155
2026-08-15T05:13:53Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514155
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Tất cả chủ đề
14
412239
2514156
2026-08-15T05:14:01Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514156
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Hành vi con người
14
412240
2514157
2026-08-15T05:14:40Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514157
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Danh sách chủ đề thuộc nhóm liên quan
14
412241
2514158
2026-08-15T05:14:41Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514158
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Sự sống
14
412242
2514159
2026-08-15T05:14:56Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514159
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Con người
14
412243
2514160
2026-08-15T05:15:03Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514160
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:cmg:Tự nhiên
14
412244
2514161
2026-08-15T05:15:35Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514161
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Ngôn ngữ Chữ Soyombo
14
412245
2514162
2026-08-15T05:16:41Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514162
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Chữ Soyombo
14
412246
2514163
2026-08-15T05:17:16Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2514163
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Tiếng Nhật Hokuriku
14
412247
2514164
2026-08-15T05:33:22Z
Hiyuune
50834
/* */
2514164
wikitext
text/x-wiki
{{auto cat|lect=1|lang=ja|Hokuriku|cat=Tiếng Nhật Nhật Bản}}
c8ml94wuc55qnksl86etcerche7f3r4
agnostisizm
0
412248
2514167
2026-08-15T07:15:32Z
Hiyuune
50834
/* */
2514167
wikitext
text/x-wiki
=={{langname|tr}}==
==={{section|etym}}===
Vay mượn từ {{bor|tr|fr|agnosticisme}}.
==={{section|pron}}===
* {{IPA|tr|/ɑɡ.nos.ti.siz(ɯ)m/}}
==={{section|n}}===
{{tr-noun|i|ler}}
# [[thuyết bất khả tri]].
===={{section|decl}}====
{{tr-infl-noun-c|i}}
===={{section|syn}}====
* {{l|tr|bilinemezcilik}}
===={{section|rel}}====
* {{l|tr|agnostik}}
==={{section|ref}}===
* {{R:tr:TDK}}
{{C|tr|Tôn giáo}}
gkefwu8r1l5rg8m8arinx1hbl6wwkza
Thể loại:Tiếng Nhật Kyūshū
14
412249
2514168
2026-08-15T09:02:51Z
Hiyuune
50834
Trang mới: “{{auto cat|lang=ja|lect=1|Kyūshū|cat=Tiếng Nhật Nhật Bản}}”
2514168
wikitext
text/x-wiki
{{auto cat|lang=ja|lect=1|Kyūshū|cat=Tiếng Nhật Nhật Bản}}
r4l7acer0stjwogr39ipatm1tywl37g
Thể loại:Tiếng Nhật Yamagata
14
412250
2514173
2026-08-15T09:07:59Z
Hiyuune
50834
Trang mới: “{{auto cat|lang=ja|lect=1|Yamagata|cat=Tiếng Nhật Nhật Bản}}”
2514173
wikitext
text/x-wiki
{{auto cat|lang=ja|lect=1|Yamagata|cat=Tiếng Nhật Nhật Bản}}
ozidwssmhq52sm4256mfaj9u3nk01m3
Thể loại:Tiếng Ả Rập Al-Andalus
14
412251
2514174
2026-08-15T09:12:15Z
Hiyuune
50834
Trang mới: “{{auto cat|lect=1|lang=ar|Al-Andalus}}”
2514174
wikitext
text/x-wiki
{{auto cat|lect=1|lang=ar|Al-Andalus}}
940rfkby2sj0e2v3x88t2v3lm6mfiis
แรด
0
412252
2514181
2026-08-15T09:48:57Z
Kelly zhrm
58416
Trang mới: “=={{langname|th}}== {{wp|th:}} ==={{ĐM|etym}}=== Cùng gốc với {{cog|lo|ແຮດ}}, {{cog|shn|ႁႅတ်ႈ}}. ==={{ĐM|pron}}=== {{th-pron|แรด|แร็่ด}} ==={{ĐM|n}}=== {{th-noun|ตัว}} # [[tê giác|Tê giác]]. # {{lang|th|([[ปลา]]~)}} [[cá tai tượng|Cá tai tượng]] ({{taxlink|Osphronemus goramy|loài}}). {{C|th|Họ Tê giác}}”
2514181
wikitext
text/x-wiki
=={{langname|th}}==
{{wp|th:}}
==={{ĐM|etym}}===
Cùng gốc với {{cog|lo|ແຮດ}}, {{cog|shn|ႁႅတ်ႈ}}.
==={{ĐM|pron}}===
{{th-pron|แรด|แร็่ด}}
==={{ĐM|n}}===
{{th-noun|ตัว}}
# [[tê giác|Tê giác]].
# {{lang|th|([[ปลา]]~)}} [[cá tai tượng|Cá tai tượng]] ({{taxlink|Osphronemus goramy|loài}}).
{{C|th|Họ Tê giác}}
mdguq657svhn621nwwwsokmr31zs9t4
anno luce
0
412253
2514185
2026-08-15T11:01:40Z
Kelly zhrm
58416
Trang mới: “=={{langname|it}}== {{wp|it:}} ==={{ĐM|pron}}=== {{it-pr}} ==={{ĐM|n}}=== {{it-noun|m|+first}} # {{lb|it|astronomy}} [[năm ánh sáng|Năm ánh sáng]].”
2514185
wikitext
text/x-wiki
=={{langname|it}}==
{{wp|it:}}
==={{ĐM|pron}}===
{{it-pr}}
==={{ĐM|n}}===
{{it-noun|m|+first}}
# {{lb|it|astronomy}} [[năm ánh sáng|Năm ánh sáng]].
488uzkoda35mywo1q83t5fobbjd10zk
anni luce
0
412254
2514186
2026-08-15T11:02:49Z
Kelly zhrm
58416
Trang mới: “=={{langname|it}}== ==={{ĐM|n}}=== {{head|it|Biến thể hình thái danh từ|g=m}} # {{plural of|it|anno luce}} ==={{ĐM|ana}}=== * {{anagrams|it|a=aceilnnu|calunnie|nucleina}}”
2514186
wikitext
text/x-wiki
=={{langname|it}}==
==={{ĐM|n}}===
{{head|it|Biến thể hình thái danh từ|g=m}}
# {{plural of|it|anno luce}}
==={{ĐM|ana}}===
* {{anagrams|it|a=aceilnnu|calunnie|nucleina}}
393bvag4jpligb6m9qdx1fh20j6ie5p
ފިރިހެން ހަށި
0
412255
2514188
2026-08-15T11:12:38Z
TheHighFighter2
42988
Trang mới: “=={{langname|dv}}== {{wp|dv:}} ==={{ĐM|pron}}=== {{dv-IPA}} ==={{ĐM|noun}}=== {{head|dv|noun|head=[[ފިރިހެން]] [[ހަށ]]}} # {{topics|dv|Cơ quan}} [[dương vật|Dương vật]]. ==={{ĐM|see}}=== * {{l|dv|އޮމާމަސް|t=quy đầu}}”
2514188
wikitext
text/x-wiki
=={{langname|dv}}==
{{wp|dv:}}
==={{ĐM|pron}}===
{{dv-IPA}}
==={{ĐM|noun}}===
{{head|dv|noun|head=[[ފިރިހެން]] [[ހަށ]]}}
# {{topics|dv|Cơ quan}} [[dương vật|Dương vật]].
==={{ĐM|see}}===
* {{l|dv|އޮމާމަސް|t=quy đầu}}
dvphutuyecjvvwsqlxplg3l3a2m16fd
instrument de musique
0
412256
2514191
2026-08-15T11:24:12Z
Kelly zhrm
58416
Trang mới: “=={{langname|fr}}== {{wp|fr:}} ==={{ĐM|pron}}=== * {{fr-IPA}} * {{audio|fr|LL-Guilhelma-fr-instrument de musique.wav}} * {{audio|fr|LL-Q150 (fra)-Lyokoï-instrument de musique.wav|a=Lyon}} ==={{ĐM|n}}=== {{fr-noun|m}} # [[nhạc cụ|Nhạc cụ]].”
2514191
wikitext
text/x-wiki
=={{langname|fr}}==
{{wp|fr:}}
==={{ĐM|pron}}===
* {{fr-IPA}}
* {{audio|fr|LL-Guilhelma-fr-instrument de musique.wav}}
* {{audio|fr|LL-Q150 (fra)-Lyokoï-instrument de musique.wav|a=Lyon}}
==={{ĐM|n}}===
{{fr-noun|m}}
# [[nhạc cụ|Nhạc cụ]].
31kkjyimb34v0hpuktax1qic485ql6u